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()