fix(roles): recognize pyproject.toml console-script entrypoints - #2535
Merged
Conversation
A Python project whose only entrypoint is a packaging-declared console script ([project.scripts], [project.gui-scripts], or [tool.poetry.scripts]) had no guard call and no __main__.py, so #2392's role classification still reported zero entry symbols for it. pyproject.toml is re-parsed fresh on every build rather than cached as per-file evidence like a guard call, since it's a single cheap-to-reread file — attribution runs unconditionally each build and self-corrects when the declared scripts change. Attribution is scoped to entrypoint_source_file = 'pyproject.toml' so it takes precedence over, but never clobbers, a guard-attributed target. docs check acknowledged Impact: 12 functions changed, 15 affected
Contributor
Greptile SummaryThe PR adds console-script entrypoint recognition from
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains; the previously reported deletion-path stale-root issue is addressed by clearing both TypeScript and native Python resolution caches before fresh attribution, with old and new target files included in role reclassification. Important Files Changed
Sequence DiagramsequenceDiagram
participant Build as Build/Watch Rebuild
participant Cache as Python Root Caches
participant Manifest as pyproject.toml
participant Resolver as Python Resolver
participant DB as Graph Database
participant Roles as Role Classifier
Build->>Cache: Clear configured and package roots
Build->>Manifest: Parse script declarations
Manifest->>Resolver: module:attribute targets
Resolver->>DB: Locate matching function or method nodes
DB->>DB: Clear stale and mark current attribution
DB->>Roles: Reclassify touched target files
Reviews (3): Last reviewed commit: "fix(roles): clear Python import-root cac..." | Re-trigger Greptile |
Contributor
Codegraph Impact Analysis8 functions changed → 15 callers affected across 8 files
|
…wn_files fixtures Three new #2408 unit tests built known_files entries with a hardcoded "/" join against a real std::env::temp_dir() root, which is backslash-separated on Windows. file_exists() normalizes the candidate path it checks but not the known_files set itself, so the mismatched separators made every lookup miss on windows-2022 CI (0 resolved instead of the expected count). Fixed by running the constructed entries through normalize_known_files(), matching how real callers already avoid this per its own doc comment. docs check acknowledged
…exit Greptile review: rebuildFile's two early-return branches (file deleted, no file-node-row) called refreshEntrypointAttribution before the common path's clearPythonImportRootsCache() call further down, so a long-lived watch session whose pyproject.toml root config changed would resolve script declarations against stale cached roots on those paths — wrongly clearing (or failing to mark) a still-valid target. Clearing first on every exit path, not just the common one, closes the gap; added a regression test isolating the configured-roots cache specifically (two pre-parsed files under different roots, switching which one pythonpath names). Mirrored the identical gap in the native full-build pipeline: it calls resolve_imports_batch directly, bypassing the NAPI resolve_imports wrapper's own cache-clearing (same reasoning as the pre-existing Cargo/exports-cache clears there for #2060/#2217), so a repeated native full build in the same process had the same exposure. docs check acknowledged Impact: 1 functions changed, 4 affected
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #2408
A Python project whose only program entrypoint is a packaging-declared console script (
[project.scripts],[project.gui-scripts], or[tool.poetry.scripts]inpyproject.toml) had neither anif __name__ == "__main__":guard nor a__main__.py, so #2392's role classification still reported zeroentrysymbols for it — exactly the "where does this start?" question a new agent asks first.pyproject.tomlis re-parsed fresh on every build (no per-file evidence table needed, unlike guard-call attribution) — it's a single, cheap-to-reread file, so attribution runs unconditionally each build and self-corrects when the declared scripts change.entrypoint_source_file = 'pyproject.toml', so it takes precedence over — but never clobbers — a target already attributed by guard-call evidence.resolvePythonImportPath/resolve_python_import_pathmachinery via a synthetic<rootDir>/pyproject.tomlanchor, sosrc/layouts, flat layouts, andpyproject.toml-configured import roots all resolve correctly with no new resolution logic.resolve.ts,builder/entrypoints.ts,builder/stages/build-edges.ts,builder/incremental.ts) and Rust (resolve.rs,builder/entrypoints.rs,builder/pipeline.rs).root_dircache (_pyprojectScriptsCache/pyproject_scripts_cache) that had no repeat-call benefit (this resolver runs at most once per build) but did introduce real staleness across repeatedbuildGraph/native-pipeline calls in the same process — removed rather than patched, since the function is already cheap enough to just re-read every call.resolve.ts, which was silently making everygrep/ugrepsearch against that file return nothing (file treated as binary).Test plan
resolve_pyproject_script_entrypoints(6 tests: src-layout resolution, gui/poetry tables, table-shaped-entry skip, dedup, missing/no-scripts, unresolvable module) andapply_pyproject_script_attribution(6 tests: marks, clears stale, no-clobber, precedence, empty case)tests/unit/resolve.test.tswasm/native) integration testtests/integration/issue-2408-pyproject-script-entrypoints.test.ts: classification for all three script tables, non-clobbering, precedence, and incremental-rebuild staleness clearingentrypoint=1,role='entry',entrypoint_source_file='pyproject.toml'on both engines)cargo test(1056 passed),cargo clippy -- -D warnings,cargo fmt --check,npm test(5351 passed),npm run lint,codegraph diff-impact --staged -T