From f200fa35ab7d7c8578a720a30b39dcfbf51ef178 Mon Sep 17 00:00:00 2001 From: jawwad-ali Date: Wed, 22 Jul 2026 21:47:45 +0500 Subject: [PATCH] fix(bundler): dump_yaml writes literal UTF-8 (allow_unicode=True) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dump_yaml called yaml.safe_dump without allow_unicode=True, so non-ASCII content was written as \xNN / \uXXXX escapes instead of literal UTF-8 — a round-trip readability loss for bundle config. The centralized helper _utils.dump_frontmatter and the extensions/presets config writers all pass allow_unicode=True; align dump_yaml with them. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.8 (1M context) --- src/specify_cli/bundler/lib/yamlio.py | 8 +++++++- tests/unit/test_bundler_yamlio.py | 26 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 tests/unit/test_bundler_yamlio.py diff --git a/src/specify_cli/bundler/lib/yamlio.py b/src/specify_cli/bundler/lib/yamlio.py index fc90580275..b5fb0e5691 100644 --- a/src/specify_cli/bundler/lib/yamlio.py +++ b/src/specify_cli/bundler/lib/yamlio.py @@ -60,7 +60,13 @@ def dump_yaml(path: Path, data: Any, *, within: Path | None = None) -> Path: try: path.parent.mkdir(parents=True, exist_ok=True) with path.open("w", encoding="utf-8") as handle: - yaml.safe_dump(data, handle, sort_keys=False, default_flow_style=False) + yaml.safe_dump( + data, + handle, + sort_keys=False, + default_flow_style=False, + allow_unicode=True, + ) except OSError as exc: raise BundlerError(f"Could not write {path}: {exc}") from exc return path diff --git a/tests/unit/test_bundler_yamlio.py b/tests/unit/test_bundler_yamlio.py new file mode 100644 index 0000000000..e9c60d762e --- /dev/null +++ b/tests/unit/test_bundler_yamlio.py @@ -0,0 +1,26 @@ +"""Unit tests for the bundler YAML I/O helpers.""" +from __future__ import annotations + +from pathlib import Path + +from specify_cli.bundler.lib.yamlio import dump_yaml, load_yaml + + +def test_dump_yaml_preserves_unicode(tmp_path: Path): + # dump_yaml must write literal UTF-8, not \xNN / \uXXXX escapes, so bundle + # config stays human-readable — matching _utils.dump_frontmatter and the + # extensions/presets config writers (all allow_unicode=True). + path = tmp_path / "f.yml" + data = {"note": "café-münchen", "url": "https://例え.example"} + dump_yaml(path, data) + raw = path.read_text(encoding="utf-8") + assert "café-münchen" in raw + assert "例え" in raw + assert "\\x" not in raw and "\\u" not in raw + + +def test_dump_yaml_round_trips_unicode(tmp_path: Path): + path = tmp_path / "f.yml" + data = {"note": "café", "city": "münchen"} + dump_yaml(path, data) + assert load_yaml(path) == data