From 45beee3b32a47d6c25e81f8416cad548b1a35217 Mon Sep 17 00:00:00 2001 From: b84330808 Date: Mon, 26 Oct 2026 11:26:31 +0900 Subject: [PATCH] Read alias_map_file as UTF-8 instead of the locale encoding load_alias_map_file() opened the JSON file in text mode with the locale encoding. On Windows that is a legacy code page such as cp932 or cp1252, so a UTF-8 alias map with non-ASCII table names either raised UnicodeDecodeError (not caught, so pgcli failed to start) or was decoded into mojibake that never matched the table name. A BOM written by some Windows editors was also rejected as invalid JSON on every platform. Open the file in binary mode and let json detect the encoding, which handles UTF-8 with or without a BOM regardless of the locale. Co-Authored-By: Claude Opus 5.5 --- AUTHORS | 1 + changelog.rst | 2 ++ pgcli/pgcompleter.py | 4 +++- tests/test_pgcompleter.py | 9 +++++++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 45019555e..2c9b97b18 100644 --- a/AUTHORS +++ b/AUTHORS @@ -157,6 +157,7 @@ Contributors: * Chris (ChrisJr404) * Pieter Ouwerkerk (pouwerkerk) * VXNCXNX + * Wei-Lun Li (b84330808) * jackwalkerlabs (Codex-assisted) diff --git a/changelog.rst b/changelog.rst index 5a9bc17f1..b76b3c25d 100644 --- a/changelog.rst +++ b/changelog.rst @@ -12,6 +12,8 @@ Bug fixes: ---------- * Fix the development setup instructions to activate the ``.venv`` directory created by ``uv venv``. +* Read ``alias_map_file`` as UTF-8 (with or without a BOM) instead of the + locale encoding, which made non-ASCII aliases fail on Windows. 4.7.1 (2026-09-20) ================== diff --git a/pgcli/pgcompleter.py b/pgcli/pgcompleter.py index 07d68bf1d..d0fb92e9b 100644 --- a/pgcli/pgcompleter.py +++ b/pgcli/pgcompleter.py @@ -84,7 +84,9 @@ class InvalidMapFile(ValueError): def load_alias_map_file(path): try: - with open(path) as fo: + # Read bytes so that json detects the encoding (UTF-8, with or without + # a BOM) instead of using the locale encoding (e.g. cp932 on Windows). + with open(path, "rb") as fo: alias_map = json.load(fo) except FileNotFoundError as err: raise InvalidMapFile(f"Cannot read alias_map_file - {err.filename} does not exist") diff --git a/tests/test_pgcompleter.py b/tests/test_pgcompleter.py index bf38db236..ae75d9d12 100644 --- a/tests/test_pgcompleter.py +++ b/tests/test_pgcompleter.py @@ -25,6 +25,15 @@ def test_load_alias_map_file_invalid_json(tmp_path): pgcompleter.load_alias_map_file(str(fpath)) +@pytest.mark.parametrize("encoding", ["utf-8", "utf-8-sig"]) +def test_load_alias_map_file_reads_utf8(tmp_path, encoding): + # JSON files are UTF-8, whatever the locale encoding is (e.g. cp932 or + # cp1252 on Windows). Editors such as Notepad may also add a BOM. + fpath = tmp_path / "aliases.json" + fpath.write_text('{"注文明細": "om", "café": "c"}', encoding=encoding) + assert pgcompleter.load_alias_map_file(str(fpath)) == {"注文明細": "om", "café": "c"} + + def test_path_completion_filters_files_for_cd(tmp_path, monkeypatch): (tmp_path / "folder").mkdir() (tmp_path / "file.sql").touch()