From 4bfb53aae349f0129a11e00415c77b7036b1b88c Mon Sep 17 00:00:00 2001 From: Charlie Tonneslan Date: Mon, 18 May 2026 11:08:36 -0400 Subject: [PATCH] cli: output JSON without escaping non-ASCII characters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #625. json.dumps defaults to ensure_ascii=True, so output_rows emitted '\u65e5\u672c\u8a9e' instead of '日本語' for Japanese. The CSV path already shows the characters verbatim - the JSON path should too. Pass ensure_ascii=False so the bytes match what the CSV output (and the database itself) holds. Signed-off-by: Charlie Tonneslan --- sqlite_utils/cli.py | 2 +- tests/test_cli.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/sqlite_utils/cli.py b/sqlite_utils/cli.py index 5844dfc0..988f4b99 100644 --- a/sqlite_utils/cli.py +++ b/sqlite_utils/cli.py @@ -3317,7 +3317,7 @@ def output_rows(iterator, headers, nl, arrays, json_cols): data = dict(zip(headers, data)) line = "{firstchar}{serialized}{maybecomma}{lastchar}".format( firstchar=("[" if first else " ") if not nl else "", - serialized=json.dumps(data, default=json_binary), + serialized=json.dumps(data, default=json_binary, ensure_ascii=False), maybecomma="," if (not nl and not is_last) else "", lastchar="]" if (is_last and not nl) else "", ) diff --git a/tests/test_cli.py b/tests/test_cli.py index 40b36854..a2ac75eb 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -738,6 +738,17 @@ def test_query_json(db_path, sql, args, expected): assert expected == result.output.strip() +def test_query_json_unicode(db_path): + # Regression for #625: JSON output should keep non-ASCII characters + # as themselves, not as \u-escapes. + db = Database(db_path) + with db.conn: + db["t"].insert({"id": 1, "text": "Japanese 日本語"}) + result = CliRunner().invoke(cli.cli, [db_path, "select id, text from t"]) + assert "日本語" in result.output + assert "\\u65e5" not in result.output + + def test_query_json_empty(db_path): result = CliRunner().invoke( cli.cli,