Repository navigation
Refuse a lean_lib that is not an array of named tables, and tidy lean_probe - #505
Conversation
lean_libraries read `lean_lib` with `config.get("lean_lib", []) or []`
and skipped every entry that was not a table with a string name. So
`lean_lib = true` crashed with a TypeError, while `lean_lib = "Solo"`,
`lean_lib = false`, `lean_lib = [1]`, a nameless `[[lean_lib]]` and
`[lean_lib]` written for `[[lean_lib]]` all fell back to the package
library without a word; the single-bracket case dropped its configured
roots. Lake's TOML loader refuses every one of these shapes ("expected
array", "expected table", "missing required key: name"), so
`lake build` never built anything for them. lean_libraries now raises
a SkeletonError naming the problem. An empty array keeps the package
fallback. Only a hand-written lakefile.toml reaches the check: for a
lakefile.lean project, Lake's own translate-config output always writes
`[[lean_lib]]`.
The rest is tidying with no change in behavior:
- merge the two `if not libraries:` blocks in lean_libraries;
- drop `_check_build_freshness`'s `timeout` argument, which its one
caller never passed;
- type run_module_probes with a TypeVar, so a probe's result type
reaches the caller and skeleton.py's `type: ignore[arg-type]` on
`records.update(result)` goes away;
- inline `_snapshot_regular_file` into project_control_snapshot, its
one caller.
The bounded-command interruption test now returns the real clock on
every call but the second, so a later read of time.monotonic during
cleanup cannot raise a second KeyboardInterrupt. A new test covers the
six refused lean_lib shapes, and the package-fallback test now also runs
with `lean_lib = []`.
|
Review at af9826f: merge. Nothing blocks merge. This covers #505's own commits (eaa0cca, af9826f) on top of #504. Notes
ChecksEvery lean_lib shape in the body, plus mixed arrays and non-string names, was run on #504's head and on this head, and compared with Lake's loader source. Of 23 mutants, 14 were killed; the survivors are the untested cases in notes 1 and 2, plus two gaps that already existed on main. Merged with current main, the probe, skeleton, impact, library, review, doc-budget, release and skill-example suites gave 970 passed, 77 skipped (real Lean) and 1 failed. The failure is a Python 3.14 quirk that also fails on plain main. The 8 new collected IDs are the six refusal cases and the now-parametrized fallback test. CI passed 9 of 9. Posted by Claude Code (session jackmccarthy-63). |
Lake replaces a lean_lib's default of one glob per root with the globs array as written, so `globs = []` builds no module. lean_libraries stored it as () like a missing key, and builds, project_modules and library generate then fell back to the roots. LeanLibrary.globs is now None for a missing key and () for an empty array. When the impact probe loads a module whose source is captured but that no library builds, the refusal names that source instead of saying there is none. Review notes on facebookresearch#500: pin the strict module map for a nested library, the import-closure listing of a name declared in a file no library builds, the glob refusals under strict ownership, and builds against Lake's isBuildableModule rule. Review notes on facebookresearch#505: refuse-test a number, a mixed array, a nameless target after a named one and a non-string name; say "has no string name"; pin the ", written [[lean_lib]]" advice; and correct the CHANGELOG, since main skipped the bad entries of a mixed array.
A follow-up to #482:
lean_librariesrefuses alean_libthat is not an array of named tables, as Lake refuses it, andlean_probegets four small tidies that change no behavior.Change
A
lean_libLake refuses is refused here too.lean_librariesreadconfig.get("lean_lib", []) or []and skipped any entry that was not a table with a stringname. Withname = "Solo"inlakefile.toml:lean_lib = true(or any nonzero number) crashed with aTypeError;lean_lib = "Solo",lean_lib = false(or0),lean_lib = [1], a[[lean_lib]]with noname, and[lean_lib]written for[[lean_lib]]all fell back to the package library without a word. The single-bracket case also lost its configuredroots.Lake's TOML loader refuses every one of these shapes ("expected array", "expected table", "missing required key: name"), so
lake buildnever built anything for them. They now raise aSkeletonError: "cannot read the lean_lib targets of ...: Lake expects an array of tables, written [[lean_lib]]", or "...: a [[lean_lib]] target has no name". This reachesskeleton,review prepare,work import-impactandlibrary index.What still works. An empty
lean_lib = [], or nolean_libat all, keeps the package fallback. Only a hand-writtenlakefile.tomlcan reach the new refusals: for alakefile.leanproject,lean_librariesreads Lake's owntranslate-configoutput, which always writes[[lean_lib]].Tidies, same behavior:
if not libraries:blocks at the end oflean_librariesare one block;_check_build_freshnessdrops itstimeoutargument, which its one caller,default_runner, never passed;run_module_probesis typed with a TypeVar,dict[str, _T | SkeletonError], soskeleton.pyno longer needs# type: ignore[arg-type]onrecords.update(result). The union stays because a module'sSkeletonErroris stored as its result;_snapshot_regular_fileis inlined intoproject_control_snapshot, its one caller.Tests.
test_a_lean_lib_that_is_not_an_array_is_refused_as_lake_refuses_itintests/test_lean_probe.py, after the TOML 1.1 test:true,false, a string, single brackets and[1]match "array of tables", and the nameless table matches "has no name".test_a_package_without_library_targets_is_its_own_librarynow also runs withlean_lib = [], which pins the package fallback for an empty array.test_bounded_command_interruption_kills_the_processreturns the real clock on everytime.monotoniccall but the second (calls != 2, wascalls == 1). The interrupt fires at the same point, and a later read during cleanup can no longer raise a secondKeyboardInterrupt.CHANGELOG. One
Fixedentry, "Lake configuration".Net: +64/−28 across
autoform_cli/lean_probe.py,autoform_cli/skeleton.py,tests/test_lean_probe.pyandCHANGELOG.md.Verification
lean_librariescalled directly onlakefile.toml-only projects (no process starts), withname = "Solo"plus each shape:trueand3raiseTypeError;"Solo",[lean_lib],false,[1]and the nameless table return the package librarySolo;SkeletonErrorwith the messages above, andlean_lib = []still returnsSolo.TypeError, five "DID NOT RAISE") and pass here, and both fallback cases pass on both;tests/test_lean_probe.pycover the new test, the interruption test, and the project-layout, TOML, snapshot and probe-pool tests: 26 pass and 2 skip because they need real Lake. The last,test_lake_configuration_snapshot_rejects_content_changed_between_reads, misses under the direct runner on the base branch too, because that runner's temporary directory on macOS is not resolved and pytest's is; called with a resolved directory, it passes;tests/test_skeleton.pythat patch_check_build_freshnessor run extraction throughrun_module_probespass, includingtest_cli_sets_the_probe_timeout.checkpasses on the three Python files, and they compile.ruff format --checkflagslean_probe.py,skeleton.pyandtests/test_lean_probe.pyas it flags them on the base branch; the changed lines add no formatter hunks, and CI does not run the formatter.test(Python 3.10 and 3.13) runsruff check autoform_cli servers testsandpytest -q, which collects the new test and the interruption test.real-lean-skeletonrunstests/test_skeleton.pyandtests/test_lean_probe.pyon real Lake, including the twotranslate-configlayout tests that read alakefile.leanthroughlean_libraries.real-lean's impact and library index steps runtests/test_impact.pyandtests/test_library_generate.pyon real Lean;work import-impactandlibrary indexcalllean_libraries.windows-hardeningruns only the node IDs it lists.test_bounded_command_interruption_kills_the_processis one of them; the newlean_libtest is not.Overlap
cleanup/lean-probe-tests), which moves the runner tests intotests/test_lean_probe.py; the two tests here land in that file. Merge Move the lean_probe runner tests into tests/test_lean_probe.py #504 first.autoform_cli/lean_probe.py, and Give the managed-output helpers their own module #501 also changesautoform_cli/skeleton.py. Read a link definition as Python-Markdown does when rewriting links #484, Report every code fence autoform reads as left open, not only one at the margin #487, Bump opentelemetry-api, and document stop's timeout and #481's nesting #489, Fix the book's copy: whole landing leads, Lean-specific Next up, one-line progress, no failure text in search #494, Read the book in one order: outline, numbers, Next up, Previous/Next and the nav follow the containment tree #495 and Claim a source file in import-impact only for a module Lake can build #500 also changeCHANGELOG.md. Each merges with this branch without conflict.