Repository navigation
update-shape.py: the printed git show <target>:<source> lines are not shell-quoted, and the kept-copy check (#536, #604) reads if TYPE_CHECKING:, if False: and a raising try unlike Python, and asks only if an importer is a validator #675
Description
Goal: the lines update-shape.py prints about a kept copy paste as printed, and its check of a kept copy's imports (#536, #604) answers as Python does where it claims to answer.
Filed by lane openRepoShape-5 on Brett Heap's word of 2026-10-16T12:17:02Z ("#458's update-shape/bump-leg (~22)"), from lines on #458: 6200820629 (R604's three lines on #616) and 6192496098 (its second line, second item: the untested try/else/finally import). Lane 4 judged the first three OPEN on main 95780dd (#473 comment 6215386495); lane 5 re-measured all four on main 879d804.
Lands after: nothing. update-shape.py is not a pinned copy, so no project re-pins. No open PR touches it.
Every line here is latent or exotic, and each says so itself: no shipped copy's path holds a blank or a quote, the validators import only repo_shape, and repo_shape.py imports no sibling copy. The issue is one small pull request if it is taken into v1.1.0 at all; leaving the four as known limits on #458 is a fair answer too.
Lines (path:line at main 879d804)
- The printed
git show <target>:<source>commands are not shell-quoted.merge_by_hand(update-shape.py:3495-3525) buildsf"git show {row.target}:{row.source}"(:3512) forupdate-conflict's remedy, and_missing_name_remediation(:3871-3912) builds`git show {target}:{kept[path].source}`(:3882) forupdate-accept-local-missing-name. A source path holding a blank makes git exit 128, and one holding a'makesshfailUnterminated quoted string. Latent: the source path is the standard's own (templates/assembly-root/...), and update-shape.pyapply --accept-local: a kept.pycopy that imports a name the run's newrepo_shape.pydropped passes, andmake bootstrapthen dies on an ImportError #604 widened the second from module names to any kept.pypath. The other printed paths are quoted by bump-leg.py and update-shape.py quote the paste lines that named a root or a path bare, the doctor'squote_argquotes a leading=for zsh, and README says the printed commands are for a POSIX shell (#532) #588 (Printed commands are POSIX-only: quote the bare paste lines in bump-leg.py and update-shape.py, and say in the docs that pasted commands are for a POSIX shell #532). (Tracking: update-shape.py and bump-leg.py, keeping a project's shape copies and leg pins current #458's 6200820629, first line; read, not run.) - The missing-name refusal's validators clause asks only whether an importer IS a validator.
_missing_name_refusal(:3837-3856) setsvalidated = any(pair.importer in kind.validators for pair in pairs)(:3845) and says "the validators, which never import it, pass" otherwise. It does not ask whether a validator imports the importer, or the module. Shipped files cannot reach this today. (Tracking: update-shape.py and bump-leg.py, keeping a project's shape copies and leg pins current #458's 6200820629, second line; read.) - The readers give two wrong answers in update-shape.py
apply --accept-local: a kept.pycopy that imports a name the run's newrepo_shape.pydropped passes, andmake bootstrapthen dies on an ImportError #604's reverse direction. Measured with the module's own_names_defined_inand_names_importedon four sources:- A WRITTEN module whose only binding of
NEWis underif TYPE_CHECKING:, in atrybody that raises first (raise RuntimeErrorthenNEW = 1), or underif False:readsNEWas defined (_bound_at, :4098-4123, enters everyifandtrybody through_same_scope, :4126-4136), so theImportErrorthe refusal exists to stop gets through. - A KEPT copy with
from repo_shape import NEWunderif False:is refused, though Python starts it:_blocks_inside(:4009-4021) leaves out anif TYPE_CHECKING:body (_is_type_checking, :4050-4054) and no other constant-false test.
(Tracking: update-shape.py and bump-leg.py, keeping a project's shape copies and leg pins current #458's 6200820629, third line.)
- A WRITTEN module whose only binding of
- No test holds an import in a
try'selseorfinally. Measured: the code is right,_blocks_insidegives those clauses the outer answer and not the handler's, sotry: pass / except ImportError: NEW = None / else: from repo_shape import NEWis read as takingNEW, and the same withfinally:.tests/test_update_shape_kept_helper.py, the only file naming the refusal, haselse:andfinally:only as module-scope bindings (:596-625); mutant N5, reported by R560v, survives (not re-run). (Tracking: update-shape.py and bump-leg.py, keeping a project's shape copies and leg pins current #458's 6192496098, second line, second item; the first item,os.path.lexists, is in the issue forapply.)
Direction
- Quote:
shlex.join(["git", "show", f"{target}:{source}"])in both places. A plain path prints exactly as before, so the tests that hold today's text stay green, and a test with a blank and a quote in a source path (a fork's, built for the test) holds the new one. - Clause: say it only where no importer is a validator AND no validator imports an importer or the module, with the same ast reading the check already has (
_names_importedof each validator inkind.validators). - Readers: do not enter an
if TYPE_CHECKING:body or anif False:/if 0:body in_same_scope(a binding there is not a binding), and do not enter anif False:body in_blocks_inside; leave a statement after an unconditionalraisein atrybody out of_bound_atwhere that is a few lines, and say in the docstring that the rest stays "what this cannot tell, it does not refuse" (the module's own rule). Each reading gets its test. - Test gap: add the
elseandfinallysources above to the table of "what the check is answered by".
Overlaps: none with open PRs. The issue for apply also edits update-shape.py, at Rollback._restore (:2806), _land (:4372), push_branch (:4607), _is_block_header (:1378) and current_branch (:2223), regions apart from these.
Mark each line → this issue on #458, and tick it there when this closes.
🤖 Generated with Claude Code
Activity
brettheap commentedon Oct 17, 2026
CLAIMED — lane openRepoShape-3, session b30e8b49-f249-4668-adb1-1dbfa93c09e1@Eagle, 2026-10-17T10:25:51Z, for #675
Logged in
lanes/log/openRepoShape-3.mdat97c8061a2eb13c23bd3430ac166c9e53dcdfc17e.The three reads (lane-collision-protocol Rule 1):
update-shape.py: the `update-add-would-overwrite` remedy names the ru…
docs/release-notes/v1.1.1.md: the v1.1.1 notes take RV883's NIT list …
docs/release-notes/v1.1.1.md: the v1.1.1 notes take RV883's round 3 a…
docs/release-notes/v1.1.1.md: the v1.1.1 notes run to main a249910, w…
docs/release-notes/v1.1.1.md: the v1.1.1 notes run to main 0d5d2b1, w…