Skip to content

Drop duplicate code from project inspection and the Lake metadata reader - #174

Open
Deicyde wants to merge 5 commits into
mainfrom
golf/project-inspect-duplicates
Open

Deicyde wants to merge 5 commits into
mainfrom
golf/project-inspect-duplicates

Conversation

@Deicyde

@Deicyde Deicyde commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Cleanup of the project inspection code from #14 and #79. No behaviour change: 2 files, +26/-44, one commit per item.

No other open PR edits these two files, and none uses _MANIFEST_VERSION, _LAKE_VERSION, _ELAN_WHITESPACE, _split_lean_name or _inspect_snapshot, the names this PR removes or whose type or signature it changes.

Validation at exact head fc97d1cf: ruff check autoform_cli servers tests is clean. tests/test_project_inspect.py (272) and tests/test_servers.py (19) pass. In tests/test_plugin_runtime.py, 3 pass; the fourth, test_wheel_contains_only_the_minimal_runtime, fails the same way on main in this checkout, because uv build reads a parent directory's pyproject.toml. CI runs it.

At b00a60c9, which only restores the two helpers: both parse to the same AST as on main. _trim_elan_whitespace now tests membership in _ELAN_WHITESPACE as a string rather than main's frozenset, and it returns the same as main's on 3,490,329 strings, including every code point alone and inside whitespace. ruff check autoform_cli servers tests is clean, and tests/test_project_inspect.py passes (272) with the checkout importable by child processes.

With #204 at 270ed1f7: merging this head and #204 onto main 8575a15c gives no conflict and the same tree in either order. There python -m autoform_cli --help exits 0; with fc97d1cf in place of this head it failed with ImportError: cannot import name '_json_optional'. In that tree, #204's five tests/test_library_*.py files pass (118) and tests/test_project_inspect.py passes (272).

_locked_mathlib had two try blocks with identical handlers around the
layout check and the package decoding. The legacy-layout branch between
them builds its diagnostic from constant strings and cannot raise, so
it moves inside one try.
_trim_elan_whitespace looped over a frozenset of elan's whitespace.
str.strip with the same characters as a string trims the same set.
- _MANIFEST_VERSION was _LAKE_VERSION with capture groups. The other
  use of _LAKE_VERSION only tests for a full match, so one pattern with
  the groups serves both.
- _json_optional was _json_default with a None default.
- _canonical_manifest_name and _canonical_toml_name both normalized the
  numeric parts _split_lean_name returned. _split_lean_name now does it.
Its only caller passed a fresh list and never read it again.
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Oct 7, 2026
@Deicyde

Deicyde commented Oct 11, 2026

Copy link
Copy Markdown
Contributor Author

Review at fc97d1c

Verdict: merge-ready. The no-behaviour-change claim holds, but #204 breaks the CLI if both land unchanged. #204 is an open draft that imports two of the helpers this PR deletes. git merge-tree reports the pair as clean, yet in the merged tree every autoform command dies with ImportError at startup. Whichever of #174 and #204 lands second needs a two-line change (see Landing). Nothing else turned up. CI is green at this head.

How the claim was checked:

  • Differential run, main 89dff279 against this head.
    • _canonical_manifest_name and _canonical_toml_name on 20,018 names: random strings built from «, », digits, dots, spaces and Unicode letters, plus the edge spellings.
    • _manifest_layout and _LAKE_VERSION.fullmatch on 20,012 version strings and 6 JSON integers.
    • The toolchain trim on 50,000 strings built from elan's whitespace set, U+001C..U+001F, U+200B, U+FEFF and printable characters.
    • The full inspect_project JSON report on 144 projects: manifest or package-overrides file, times 12 versions (including the legacy 0.5.0, 0.6.0, 5 and 6), times 6 packages shapes. These hit invalid-lake-manifest 72 times and unsupported-lake-manifest 48 times.
    • Every output was identical.
  • _locked_mathlib (autoform_cli/project/inspect.py:451-460). The legacy branch now sits inside the try. It only compares strings, formats f-strings over a str, builds a plain ProjectDiagnostic (a slots dataclass with no __post_init__) and appends it. None of that can raise AttributeError, RecursionError or ValueError, so the widened handler never fires for it.
  • _LAKE_VERSION (_lake_metadata.py:18). It is used only for a fullmatch truth test (:103) and for match.groups() (:335). The added groups are exactly the three the old _MANIFEST_VERSION had.
  • _split_lean_name normalization (:452). The only callers were the two canonical-name functions, and both normalized numeric parts afterwards. Both still return tuples.
  • Callers outside the PR. No test, server or other module calls or monkeypatches a removed or changed name. The one exception is Search a locked Lean library from autoform search, and generate its index (#203, reader and generator) #204, below.
  • Existing test. test_python_only_c0_whitespace_is_not_trimmed_like_elan (tests/test_project_inspect.py:906) still pins the reason _ELAN_WHITESPACE is not plain str.strip().

Landing

Posted by PR swarm: Review #173 #174 #180

@Deicyde
Deicyde marked this pull request as ready for review October 11, 2026 02:50
#204 adds autoform_cli/library/locate.py, which imports _json_optional
from _lake_metadata and _trim_elan_whitespace from inspect, and
__main__ imports that module at startup. With both deleted, main plus
this branch plus #204 merges cleanly, yet every autoform command then
fails with ImportError.

Restore main's two definitions unchanged, each with a comment naming
the importer. This module's own callers stay on _json_default and
str.strip. _ELAN_WHITESPACE is now a string rather than main's
frozenset, but the loop only tests single characters, for which the
two agree, so the restored trim returns what main's does for every
string.

@Franky100-pig Franky100-pig left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the unusually clear PR description — it made verification straightforward. I read the diff against each claimed change and grepped the tree for dangling references to the removed/renamed symbols.

Verified (behaviour-preserving):

  • _MANIFEST_VERSION and _json_optional are gone; grep finds no remaining references. The still-present names (_LAKE_VERSION, _json_default, _canonical_manifest_name, _canonical_toml_name) are all still defined and called.
  • _LAKE_VERSION now carries the capture groups and serves both call sites: _manifest_layout uses match.groups(), and the other fullmatch call is unaffected. Same matches.
  • _json_optional(..., str) → _json_default(..., None, str) is equivalent for the three call sites (absent / explicit-null / wrong-type all behave identically).
  • _split_lean_name now normalizes numeric parts and returns a tuple; the two _canonical_* wrappers delegate correctly, so their outputs are unchanged.
  • _locked_mathlib: the legacy-layout branch now sits inside the single try, and _validate_manifest_root is still inside it, so its ValueError is still caught by the one except (AttributeError, RecursionError, ValueError).

One thing worth a second look (turns out fine):

  • _ELAN_WHITESPACE changed from frozenset(...) to (...). At a glance that looks like it became a tuple, which would make str.strip(_ELAN_WHITESPACE) raise TypeError. But the three string literals are adjacent with no commas, so they concatenate into a single str — .strip() is valid and trims the same set (I confirmed locally: type is str, len 25, and " \u3000hi\u00a0 ".strip(...) → "hi"). A plain = "..." without the wrapping parentheses would remove the tuple-footgun for the next reader; non-blocking.

Minor / non-blocking:

  • With _json_optional removed, the None default is now hard-coded at each call site. Fine here, just slightly less self-documenting than the old name implied.

The "no behaviour change" claim holds up. Nice cleanup. (I reviewed by reading + grepping; I didn't run uv/the suite locally, so I'm trusting your validation note on test_project_inspect.py / test_servers.py.)

@Deicyde

Deicyde commented Oct 11, 2026

Copy link
Copy Markdown
Contributor Author

Kept the two helpers #204 imports, in b00a60c9. #204's library locator imports _json_optional from _lake_metadata and _trim_elan_whitespace from inspect, and __main__ imports the locator at startup, so with both deleted, main, this PR and #204 merged without a conflict and every autoform command then failed with ImportError. Both are back with main's definitions unchanged, each under a comment naming #204 as the importer; the rest of the PR is as before.
Merging this head and #204 (270ed1f7) onto main 8575a15c gives no conflict and the same tree in either order, and python -m autoform_cli --help exits 0 there; with fc97d1cf instead it fails with ImportError: cannot import name '_json_optional'. Either PR can now land first without a change to the other.
Both helpers parse to the same AST as main's. _trim_elan_whitespace now tests membership in _ELAN_WHITESPACE as a string instead of main's frozenset; it returned the same as main's on 3,490,329 strings, including every code point alone and inside whitespace.
With the checkout importable by child processes, tests/test_project_inspect.py passes 272 of 272 on this head and in the merged tree, and #204's five tests/test_library_*.py files pass 118 of 118 there. ruff check autoform_cli servers tests is clean, and the PR body now lists the two helpers as kept.
Exact-head CI at b00a60c9: all 9 checks pass (real Lean, Python 3.10 and 3.13, Windows).
Posted by PR swarm: Swarm Manager

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants