Repository navigation
tests/test_adopt_plan_paths_spelled.py: seven mutants of the plan written to and cloning ... into lines that no row killed now fail one, so a printable non-ASCII path prints as typed, ESC, CR and a non-UTF-8 --work-dir are spelled, a relative --out is not made absolute, an --out that ends in a space or is wrapped in backticks is spelled, and execute spells the clone line as plan does (#1167) - #1185
brettheap wants to merge 2 commits into
Conversation
…itten to` and `cloning ... into` lines that no row killed now fail one, so a printable non-ASCII path prints as typed, ESC, CR and a non-UTF-8 `--work-dir` are spelled, a relative `--out` is not made absolute, an `--out` that ends in a space or is wrapped in backticks is spelled, and `execute` spells the clone line as `plan` does (#1167) Follows #1154 (for #1115), from RV1115's review of it (#1154 issuecomment-6344547992): its mutants R1, R2, R3, R4, R6, R7 and R12 left the 18 rows of the file green, and the code of #1154 is right on each case. No change to adopt-project.py. 13 rows are added, and the first 18 are unchanged: - ESC and CR join `CHARACTERS`, which feeds the `--out` rows and the `--work-dir` rows alike (R6, R7; 4 rows); - a `--work-dir` that is not UTF-8, under a `surrogateescape` stdout, is spelled `\udcff` between backticks and no raw byte is written (R7; 1 row); - a printable non-ASCII `--out` and `--work-dir` (U+00E9) print as typed, with no backticks (R2, R3; 2 rows); - a relative `--out`, `plan.yaml` and `./plan.yaml`, prints as `plan.yaml` (R4; 2 rows); - an `--out` that ends in a space, and a relative one that begins and ends with a backtick, are printable and still spelled, as `_shown` has it since #900 (R1; 2 rows); - `check` and `execute` over a plan from a local source, handed `--source testorg/Thing` and a `--work-dir` holding U+202E, refuse as `source-unclonable` after the spelled `cloning` line (R12; 2 rows). Only the `execute` row kills R12: `plan` and `check` hand `Source.clone` a list of the clones they made, `execute` none. Each new row passes on 8a782733 and fails on its mutant, and each mutant leaves the first 18 rows green. Lane: openreposhape-4 (openRepoShape-4) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Reviewer's GuideThis test-only PR adds 13 targeted rows and supporting helpers to kill seven previously surviving mutants in path-output spelling, covering terminal-control characters, printable and non-ASCII names, relative and ambiguous paths, non-UTF-8 bytes, and consistency across plan, check, and execute. File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
RV1185: independent review of #1185 at Independent adversarial review for lane 4. No MUST. One SHOULD: SonarCloud's one new issue on the PR, python:S9073, a composite assert at :320. Two NITs for follow-ups. Apart from S1 the PR does what #1167 asks. Every row #1167 asks for is there and asserts the line #1167 gives. Each of RV1115's seven mutants, which I rebuilt myself, fails at least one new row. #1154's 18 rows stay green under every one of them. What I measured against
1. The rows against #1167Each row asserts what #1167 gives, backticks and escapes included.
I checked the R12 reasoning in the source. 2. MutantsI wrote my own mutants from #1167's and RV1115's text, not from W1167's Each mutant was run against three things at once:
After each run I restored the file with
For R1 to R12, every count matches the PR body's table. The body's R6 is my R6a. 3. The helper that reads the child's bytes
4. GateEach run was on the scratch merge
5. Merge-trees
Findings
Notes, not findings
Lane: openreposhape-4 (openRepoShape-4) |
…issing traceback are two asserts, so a failure names the one that broke (#1167) The 0xff `--work-dir` row asserted `code == 2 and b"Traceback" not in stderr` as one composite assert, which SonarCloud flags as python:S9073 on #1185 (RV1185's S1). It is now `assert code == 2` and `assert b"Traceback" not in stderr`, each with the same message, the child's stdout and stderr. The row asserts what it asserted before. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
W1167b: fix round 1 at
Before: assert code == 2 and b"Traceback" not in stderr, stdout + stderrAfter: assert code == 2, stdout + stderr
assert b"Traceback" not in stderr, stdout + stderrNo other Tests on
A test-only change, so no doctor shards and no mutants. The merge-tree is clean (exit 0) against N1 and N2 are NITs; they go to a follow-up issue the lane files, and this round changes nothing for them. Lane: openreposhape-4 (openRepoShape-4) |
|
|
RV1185r2: independent re-check of #1185 at Independent re-check for lane 4 of W1167b's fix round. No MUST, no SHOULD. S1 is resolved. One thing is still open when I post: the 1. Scope
2. Tests (the landing gate's environment)Stub
The hygiene counts differ by one (101 on the merge, 100 on the head), as RV1185 (101) and W1167b (100) each reported. Both worktrees were clean after the runs. 3. CI on
|
| Mutant | Result |
|---|---|
| M0, none | 1 passed |
M1: the cloning path printed raw, {path} for {_shown(str(path))} |
fails at :324, the line assert |
M2: the path run through UTF-8 replace before _shown, so U+FFFD for the surrogate |
fails at :324 |
| M3: the exit code asserted as 3 | fails at :320, the first split assert, assert 2 == 3 |
M4: Traceback demanded in stderr |
fails at :321, the second split assert, with the child's output in the message |
So each half of the old composite fires alone, and a failure names the one that broke.
5. Merge-trees
- Against
origin/main(961640c68, unchanged on the remote when I started):git merge-tree --write-treeexits 0, tree173a373ab. That tree differs from main in four files only, all adopt-project.py:plan written toandcloning <repository> (read only) intoname the caller's--outand--work-dirwith_shown, as the other lines of the report name a path, so a bidi control, a line feed or a tab in either no longer reaches the terminal as it was typed (#1115) #1154's:adopt-project.py,tests/test_adopt_plan_paths_spelled.py,tests/test_non_utf8_name_callers.py,tests/test_stdout_encoding.py. It matches the tree W1167b named. - Against adopt-project.py:
plan written toandcloning <repository> (read only) intoname the caller's--outand--work-dirwith_shown, as the other lines of the report name a path, so a bidi control, a line feed or a tab in either no longer reaches the terminal as it was typed (#1115) #1154's head (origin/fix/1115-plan-paths-spelled,8a7828332): exit 0, tree4532a4bb8, the head's own tree.
Findings
No new finding.
- S1 (SHOULD): resolved, as above.
- N1 (NIT) and N2 (NIT) from RV1185 stand and are not for this PR. They go to the lane's follow-up issue: N1, the new rows fail under a one-byte (Latin-1) locale, where
skip_where_a_name_cannot_be_not_utf_8could also skip whereos.fsdecode(b"\xff") != NOT_UTF_8_PROBE; N2,plan_of_a_repository_on_github_as_bytesbuilds its environment withoutblank_unnamed_pin_sourcesand the git identity defaults thatrun_scriptandtest_stdout_encoding.py'srun_tool_bytesuse.
Notes, not findings
- The PR stays a draft. I changed nothing on it. The closing keyword in the body is not live while the base is adopt-project.py:
plan written toandcloning <repository> (read only) intoname the caller's--outand--work-dirwith_shown, as the other lines of the report name a path, so a bidi control, a line feed or a tab in either no longer reaches the terminal as it was typed (#1115) #1154's branch, as RV1185 noted. - I did not rerun RV1185's full mutant table: the change is a split of one assert, the source and every other row are byte for byte what RV1185 measured, and the four mutants above cover the split row.
Lane: openreposhape-4 (openRepoShape-4)



Closes #1167
Stacked on #1154 (for #1115): the base is
fix/1115-plan-paths-spelled, becausetests/test_adopt_plan_paths_spelled.pyis new in that PR. This lands after #1154 and after the v1.2.0 tag. No change toadopt-project.py.RV1115's review of #1154 (#1154 issuecomment-6344547992) found seven mutants of the two spelled lines,
plan written to {out}andcloning {repository} (read only) into {path}, that none of the file's 18 rows failed. #1154's code is right on each case; the rows were missing. 13 rows are added, and the first 18 are unchanged.Rows
CHARACTERS(4 rows:--outand--work-dir, each)<D>/pl\x1ban.yamland\rspelled between backticks on both lines--work-dirwith the byte 0xff, stdoututf-8:surrogateescape(1 row)`<realpath D>/wd\udcffk/source-readonly/Thing`and no raw 0xff on stdout--out, and--work-dir(U+00E9) (2 rows)--out,plan.yamland./plan.yaml, run intmp_path(2 rows)plan written to plan.yaml--out 'plan.yaml 'and--out '`plan.yaml`'(2 rows)`plan.yaml `and`\x60plan.yaml\x60`(#900's rule)checkandexecutewith--source testorg/Thing --work-dir <D>/wd<U+202E>k(2 rows)REFUSED source-unclonable, and the spelledcloninglineOn R12, only the
executerow kills the mutant.mainsetsargs.clones = []for every command, soplanandcheckhandSource.cloneamadelist and onlyexecutehands it none; thecheckrow is forcheck's own line.plan_of_a_local_sourcetakes an optionalcwd(the relative-path rows run there). One helper is new for the 0xff row, which reads the child's bytes, becauserun_scriptdecodes them in the parent's locale and the raw byte of a mutant would fail that decode and not the assertion.Mutants
Each mutant is RV1115's, applied to
adopt-project.pyon #1154's head8a7828332(sha256efe97bf7...b3d2); the old file (those 18 rows) and the new one were run together, and the file was restored withgit checkoutwith its sha256 checked after each.--outbyisprintable()alone (no trailing-space or backtick rule)test_a_printable_out_path_that_reads_as_another_is_spelled(trailing-space, begins-and-ends-with-a-backtick)--outspells every non-ASCII pathtest_a_printable_non_ascii_out_path_is_named_as_it_was_typed--work-dirspells every non-ASCII pathtest_a_printable_non_ascii_work_dir_is_named_as_it_was_typed--outprinted as_shown(os.path.abspath(out))test_a_relative_out_path_is_named_as_it_was_typed(both) and the two rows of R1--outspells only Cf, line feed and tabtest_plan_written_to_spells_an_out_path_a_terminal_would_not_show(escape, carriage-return) and the two rows of R1--work-dirspells only Cf, line feed and tabtest_cloning_spells_a_work_dir_a_terminal_would_not_show(escape, carriage-return) andtest_a_work_dir_that_is_not_utf8_is_spelled_and_no_raw_byte_is_writtencloningspelled only wheremade is not Nonetest_check_and_execute_spell_the_work_dir_as_plan_does[execute]As a check on the other side, main's own
adopt-project.py(both lines raw): the old file 15 failed and 3 passed, the new file 24 failed and 7 passed; the 7 are the 3 control rows, the two printable non-ASCII rows and the two relative-path rows, which main prints right as well.Gate
On a scratch merge commit of
origin/main961640c68and this head5dc90602f(merge20401c180, treeb6998640), the landing gate's environment: a stubghfirst on PATH,GH_TOKEN=bogus, an emptyGH_CONFIG_DIR, an empty global git config,GIT_CONFIG_NOSYSTEM=1,EMAILset.tests/test_adopt_plan_paths_spelled.pytests/test_stdout_encoding.pytests/test_non_utf8_name_callers.pytests/test_adopt_plan_escapes.pytests/test_path_guard_hygiene.pytests/test_repo_hygiene.pyA test-only change, so the doctor shards were not run.
git merge-tree --write-treeof this head againstorigin/mainand against #1154's head: exit 0 each. No other open PR touches the test file.Source ASCII (every non-ASCII character is an escape), POSIX only, and a
ghstand-in that refuses for--work-dir, as the file's rules say.🤖 Generated with Claude Code
Lane: openreposhape-4 (openRepoShape-4)
Summary by Sourcery
Strengthen path-display regression tests to cover safe and consistent spelling across adopt-project commands.
Enhancements:
Tests: