diff --git a/tests/architecture/test_contributor_task_board.py b/tests/architecture/test_contributor_task_board.py index 45d2dcf078..487d4d703e 100644 --- a/tests/architecture/test_contributor_task_board.py +++ b/tests/architecture/test_contributor_task_board.py @@ -131,10 +131,10 @@ def test_inactive_or_unmerged_design_cannot_be_available( ) -> None: run, board, root = check_board path = root / "docs/architecture/rfcs/goal-direction-baseline-v0.md" - text = path.read_text() + text = path.read_text(encoding="utf-8") changed = re.sub(r"(?<=RFC status:\*\* )[^\n]+", state, text, count=1) assert changed != text - path.write_text(changed) + path.write_text(changed, encoding="utf-8") with pytest.raises(AssertionError, match="not an Accepted claimable design"): run(board) diff --git a/tests/architecture/test_rfc_status_index.py b/tests/architecture/test_rfc_status_index.py index 2da36bfab9..24b2f36987 100644 --- a/tests/architecture/test_rfc_status_index.py +++ b/tests/architecture/test_rfc_status_index.py @@ -45,7 +45,9 @@ def document( .replace("Supersedes / closes:", "替代 / 关闭:") .replace("Superseded by:", "被替代为:") ) - (rfcs / f"{name}{'.zh-CN' if zh else ''}.md").write_text(header + "\n" + body) + (rfcs / f"{name}{'.zh-CN' if zh else ''}.md").write_text( + header + "\n" + body, encoding="utf-8" + ) def run(repo: Path, mode: str) -> subprocess.CompletedProcess[str]: diff --git a/tests/architecture/test_semantic_inventory.py b/tests/architecture/test_semantic_inventory.py index 3f5a8f3ab6..c9c69beb2f 100644 --- a/tests/architecture/test_semantic_inventory.py +++ b/tests/architecture/test_semantic_inventory.py @@ -372,7 +372,10 @@ def test_untracked_sources_do_not_change_inventory(repo: Path) -> None: def test_tracked_symlink_cannot_read_untracked_source(repo: Path) -> None: _write(repo, "private.py", 'PRIVATE_CONTEXT = ("synthetic", "local")\n') - (repo / "loopx/link.py").symlink_to(repo / "private.py") + try: + (repo / "loopx/link.py").symlink_to(repo / "private.py") + except OSError as exc: + pytest.skip(f"file symlinks unavailable: {exc}") subprocess.run(["git", "-C", str(repo), "add", "loopx/link.py"], check=True) with pytest.raises(ValueError, match="symlink"): load_sources(repo) diff --git a/tests/architecture/test_semantic_production.py b/tests/architecture/test_semantic_production.py index 004d35e88c..6b0718058a 100644 --- a/tests/architecture/test_semantic_production.py +++ b/tests/architecture/test_semantic_production.py @@ -116,7 +116,7 @@ def test_declared_return_is_scanned_in_real_python_syntax(): def test_real_return_producer_rejects_an_unregistered_result(vocabulary_name, module, original): import json from loopx.semantics.inventory import load_sources - v = json.loads((ROOT / 'loopx/semantics/vocabulary_v0.json').read_text())['vocabularies'][vocabulary_name] + v = json.loads((ROOT / 'loopx/semantics/vocabulary_v0.json').read_text(encoding='utf-8'))['vocabularies'][vocabulary_name] sources = load_sources(ROOT) replacement = 'return "unknown_action"' found = False @@ -205,7 +205,7 @@ def test_real_effect_adapters_are_observed_as_unresolved_passthrough(): import json from loopx.semantics.inventory import load_sources - v = json.loads((ROOT / 'loopx/semantics/vocabulary_v0.json').read_text())['vocabularies']['effective_action'] + v = json.loads((ROOT / 'loopx/semantics/vocabulary_v0.json').read_text(encoding='utf-8'))['vocabularies']['effective_action'] paths = {'loopx/control_plane/effect_program.py', 'loopx/control_plane/effect_program.ts'} owner = v['owners']['python'].split('::')[0] sources = [source for source in load_sources(ROOT) if source.path in paths | {owner}] @@ -249,7 +249,7 @@ def test_real_reexported_turn_owner_is_attributed_through_one_hop(): from loopx.semantics.inventory import load_sources # loop_controller imports LoopXTurnRoute from driver, which re-exports the # generated owner; the registered return producer must still resolve. - v = json.loads((ROOT / 'loopx/semantics/vocabulary_v0.json').read_text())['vocabularies']['turn_route'] + v = json.loads((ROOT / 'loopx/semantics/vocabulary_v0.json').read_text(encoding='utf-8'))['vocabularies']['turn_route'] rows = collect_production(ROOT, v, load_sources(ROOT)) site = 'loopx/control_plane/turn_driver/loop_controller.py::_envelope_route' resolved = {value for r in rows if r.site == site and not r.unresolved for value in r.values}