Open
Conversation
As defined in PEP-810. We implement this in much the same way as how we handle `async` annotations currently. The relevant nodes get an `is_lazy` field that defaults to being false.
Otherwise these will disappear every time we regenerate the AST.
Adds a new `isLazy` predicate to the relevant classes, and adds the relevant dbscheme (and up/downgrade) changes. On upgrades we do nothing, and on downgrades we remove the `is_lazy` bits.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds Python extractor + QL support for PEP 810 “lazy imports” by threading a new is_lazy boolean through the parser/DB scheme and exposing it as isLazy() on relevant import AST nodes.
Changes:
- Extend the tree-sitter grammar and TSG mapping to recognize
lazy import .../lazy from ... import ...and setis_lazy. - Add
is_lazyto the Python DB scheme forImportandImportStar, including upgrade/downgrade plumbing. - Expose
isLazy()in the generated QL AST classes and add extractor/parser tests and a change note.
Show a summary per file
| File | Description |
|---|---|
| python/ql/test/3/extractor-tests/lazy-imports/test.ql | New extractor test query validating Import.isLazy() output. |
| python/ql/test/3/extractor-tests/lazy-imports/test.py | New Python source for lazy vs non-lazy import extraction tests. |
| python/ql/test/3/extractor-tests/lazy-imports/test.expected | Expected results for the new extractor test. |
| python/ql/lib/upgrades/279cbb08d387ecd57ac177e87c94cfd5ca62f792/upgrade.properties | DB upgrade metadata for adding is_lazy. |
| python/ql/lib/upgrades/279cbb08d387ecd57ac177e87c94cfd5ca62f792/semmlecode.python.dbscheme | Upgrade dbscheme snapshot reflecting the new fields. |
| python/ql/lib/upgrades/279cbb08d387ecd57ac177e87c94cfd5ca62f792/old.dbscheme | Prior dbscheme snapshot for the upgrade. |
| python/ql/lib/semmlecode.python.dbscheme | Adds Import.is_lazy / ImportStar.is_lazy fields and updates @py_bool_parent. |
| python/ql/lib/semmle/python/AstGenerated.qll | Adds isLazy() predicates for Import and ImportStar AST nodes. |
| python/ql/lib/change-notes/2026-04-10-support-lazy-keyword.md | Change note documenting the new syntax support. |
| python/extractor/tsg-python/tsp/src/tree_sitter/array.h | Refactors array delete/swap helpers used by the embedded tree-sitter runtime. |
| python/extractor/tsg-python/tsp/src/node-types.json | Updates node types to include the is_lazy field and lazy token. |
| python/extractor/tsg-python/tsp/src/grammar.json | Generated grammar updates to parse optional lazy on import statements. |
| python/extractor/tsg-python/tsp/grammar.js | Grammar source changes adding optional lazy to import statements and soft-keyword handling. |
| python/extractor/tsg-python/python.tsg | Sets is_lazy attribute on import parse nodes when lazy is present. |
| python/extractor/tests/parser/lazy_imports_new.py | New parser test corpus for lazy imports + soft-keyword behavior. |
| python/extractor/tests/parser/lazy_imports_new.expected | Expected AST dump for the new parser test. |
| python/extractor/semmle/query_gen.py | Ensures generated QL libraries include overlay[local] module; header. |
| python/extractor/semmle/python/parser/tsg_parser.py | Updates placeholder node creation to treat is_lazy like other default-false fields. |
| python/extractor/semmle/python/parser/dump_ast.py | Avoids printing default-false is_lazy in AST dumps. |
| python/extractor/semmle/python/master.py | Adds is_lazy fields to Import and ImportFrom (ImportStar) schema definitions. |
| python/extractor/semmle/python/ast.py | Adds is_lazy slots/constructor params to Import and ImportFrom. |
| python/downgrades/eb5fc917c79bb23ce2de4a022f3e566d57a91be9/upgrade.properties | Downgrade metadata to remove is_lazy, including a py_bools rewrite step. |
| python/downgrades/eb5fc917c79bb23ce2de4a022f3e566d57a91be9/semmlecode.python.dbscheme | Downgrade dbscheme snapshot. |
| python/downgrades/eb5fc917c79bb23ce2de4a022f3e566d57a91be9/py_bools.ql | Downgrade query to drop py_bools rows for Import/ImportStar parents. |
| python/downgrades/eb5fc917c79bb23ce2de4a022f3e566d57a91be9/old.dbscheme | Prior dbscheme snapshot for the downgrade. |
Copilot's findings
- Files reviewed: 25/26 changed files
- Comments generated: 2
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Said PEP adds support for annotating imports (
import ...andfrom ... import ...) with alazykeyword, the semantics of which are not relevant to this PR.We handle this in the parser in much the same way we do
asynccurrently -- import nodes get a newis_lazyfield that gets populated when thelazykeyword is present. On the QL side, this determines whether the newisLazypredicate method holds on the relevant nodes.Should be reviewed commit-by-commit.