Repository navigation
test: decode repository files as utf-8 in tests that read them as text - #23775
Conversation
Twenty-four tests read a UTF-8 file from the repository (a source module, a CloudFormation template, a JSON fixture, a shell script) with a bare read_text() or open(), which decodes with the host's code page. On a cp950 Windows host each one fails at the first non-ASCII character with UnicodeDecodeError, so the suite cannot run green there; on a cp1252 host the same bytes are silently mis-decoded. Name the codec at each read, and record the rule beside the zone rule in testing-conventions.md D5. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
First Principles Review (Opus 5.5, fork) — ⏭️ skippedRevision |
UX Review (Opus 5.5, fork) — ⏭️ skippedRevision |
Design Review (Opus 5.5, fork) — ✅ PASSDesign-level review of Design-Verdict: PASS Nothing to check. The change only touches tests, it was verified on the failing host, and it is easy to revert. [DESIGN-REVIEWED] 832bc73 Description read[DESCRIPTION-READ] f2437466c2a7d0d8a743c79546647b74d2e147b68939b13aa81cf6c1f06d7305 That sha256 names everything this verdict read: the PR description, plus the 1 evidence file(s) the workflow collected from it and handed this review. It covers that evidence because the media strip replaces every attachment URL with the same placeholder, so an edit swapping one attachment for another would leave the description's captured text identical while what this review judged changed. Recompute it with |
Opus 5.5 Review (fork) — ✅ no blocking findingsReviewed |
GPT 6.1 Review (fork) — ✅ no blocking findingsReviewed Review detailsNo findings. |
iamwhatever
left a comment
There was a problem hiding this comment.
Approve at 832bc73.
Each change names encoding="utf-8" on a test's read of a repository file and changes nothing else, so on a UTF-8 host every read returns the same text and on a cp950 host it stops failing before the assertion. The one-sentence D5 addition states the rule (testing-conventions.md#L83-L87). AI lanes pass and every check is green. I read CI results and did not run tests.
— crew-pr-reviewer (r124)
Problem / Motivation
Goal: the backend tests that read a repository file as text decode it as UTF-8 on every host, so they pass or fail on what the file says rather than on the host's code page.
On a Windows host whose ANSI code page is cp950 (zh-TW), 24 tests fail before they assert anything:
Each one reads a UTF-8 file from the repository (a source module, a CloudFormation template, a JSON fixture, a shell script,
pyproject.toml) with a bareread_text()oropen(), which decodes with the host's code page. The first—,→or…in the file is not valid cp950. On a cp1252 host, the code page GitHub's Windows runners use, the same bytes decode without an error into other characters, so CI stays green while the test reads something other than the file.Why it matters
A contributor on a CJK-locale Windows machine cannot get a green local run of these tests, and
scripts/local-gate.pyreports them red on diffs that never touched them. D5 of the determinism contract already rules out depending on the host's locale; these reads do.Not a goal
src/file; locale decoding there ischeck_subprocess_encoding.py's territory and the reads it covers.read_text()calls intest/(about 1,500 on main). Almost all of them read ASCII files and decode the same on every host. Only the reads measured to fail are changed.read_text()in tests.What changed (motivation → approach → change)
UnicodeDecodeError: 'cp950'on a cp950 host.read_text()/ text-modeopen()in a test module that names a repository file holding non-ASCII bytes gave 97 candidate files. All 97 were run on a cp950 host, and these are the ones that failed with the decode error.encoding="utf-8", at 24 sites in 21 test files. The fouropen()sites intest_deploy_round29_fixes.pyandtest_deploy_web_iam.pyhand the stream toyaml_helpers.load_with, which is where the traceback lands.docs/system-specs/common/testing-conventions.mdD5 gets one sentence: a test that reads a repository file as text names the codec, and why.Backwards compatibility
Compatible: test-only, plus one documentation sentence. The files are UTF-8, so on a UTF-8 host every read returns the same text it did before.
Removes nothing: no assertion, test or file is removed or narrowed.
Tests
WinError 1314,test_agent_panel_store's symlinked-directory tests), and two intest_pod_provisionlook foruvon the 3.13 interpreter only.test/test_flake_pattern_ratchet.py: 60 passed. black (the 13 non-baselined files), isort, flake8,check_comment_history,check_brand_name,check_file_line_capandscripts/docs_lint.pypass.Proof: not provable -- test-only change
Manual verification
N/A — test-only change; the before/after run on the cp950 host above is the check.
Related Issues
Fixes #23774
Checklist
feat|fix|docs|style|refactor|perf|test|chore|ci|build|revert: ...)Contribution License Agreement
🤖 Generated with Claude Code