Skip to content

Python extractor: overlay support - #20206

Closed
d10c wants to merge 14 commits into
github:mainfrom
d10c:d10c/python-overlay
Closed

Python extractor: overlay support#20206
d10c wants to merge 14 commits into
github:mainfrom
d10c:d10c/python-overlay

Conversation

@d10c

@d10cd10c commented Aug 11, 2025

Copy link
Copy Markdown
Contributor

This PR adds overlay support to the Python extractor, but no overlay compilation (to be merged separately since it needs further testing, see this PR).

This PR also includes an initial pass at the discard predicates (see Overlay.qll), though these are ignored in full (non-overlay) evaluation; they probably still need to be tweaked, so I'm happy to move this commit to another PR and let this one be only about the extractor.

Roadmap:

  • Update the dbscheme
  • Implement path transformer support
  • Read the overlay-changes JSON file
  • Read/write base metadata (CODEQL_EXTRACTOR_<LANG>_OVERLAY_BASE_METADATA_{IN,OUT})

@d10c
d10cforce-pushed the d10c/python-overlay branch 2 times, most recently from b18b9ce to 3015c12CompareAugust 12, 2025 10:48
Comment threadpython/ql/lib/semmle/python/Overlay.qll Fixed
Comment threadpython/ql/lib/semmle/python/Overlay.qll Fixed
@d10c
d10cforce-pushed the d10c/python-overlay branch from b0c7a52 to b5c8338CompareAugust 19, 2025 18:20
Comment threadpython/ql/lib/semmle/python/Overlay.qll Fixed
@d10c
d10cforce-pushed the d10c/python-overlay branch from f75a392 to 63106c0CompareAugust 20, 2025 14:32
@d10cd10c mentioned this pull request Aug 27, 2025
@d10c
d10cforce-pushed the d10c/python-overlay branch from 63106c0 to b3a1ba5CompareAugust 27, 2025 08:42
@d10c
d10cforce-pushed the d10c/python-overlay branch from b3a1ba5 to fb23977CompareAugust 27, 2025 08:59
@d10c

d10c commented Aug 28, 2025

Copy link
Copy Markdown
ContributorAuthor

@tausbn I'm thinking this might be a good time to checkpoint this work and get it reviewed. In the last DCA run for full analysis on this PR (see above), overall analysis time is unaffected, though there are a few outstanding stage timing results that are probably noise.

@d10c
d10c marked this pull request as ready for review August 28, 2025 10:33
@d10c
d10c requested a review from a team as a code ownerAugust 28, 2025 10:33
@d10c
d10c requested review from Copilot and tausbnAugust 28, 2025 10:33

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds overlay support to the Python extractor by implementing infrastructure for incremental analysis through database overlays, without including overlay compilation functionality.

Key changes implemented:

  • Database schema updates to support overlay metadata and change tracking
  • Extractor modifications to handle overlay-specific file traversal and metadata management
  • Path transformer support using updated environment variables

Reviewed Changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.

Show a summary per file
FileDescription
python/ql/lib/semmlecode.python.dbschemeAdds databaseMetadata and overlayChangedFiles relations for overlay support
python/ql/lib/semmle/python/Overlay.qllImplements discard predicates to filter out obsolete entities during overlay analysis
python/extractor/semmle/traverser.pyModifies file traversal to only process changed files during overlay extraction
python/extractor/semmle/worker.pyAdds support for writing base metadata output required for overlay operations
python/extractor/semmle/path_rename.pyUpdates path transformer to support new CODEQL_PATH_TRANSFORMER environment variable

Comment threadpython/extractor/semmle/traverser.py Outdated
with open(os.environ['CODEQL_EXTRACTOR_PYTHON_OVERLAY_CHANGES'], 'r', encoding='utf-8') as f:
data = json.load(f)
changed_paths = data.get('changes', [])
self.overlay_changes = { os.path.abspath(p) for p in changed_paths }

CopilotAIAug 28, 2025

Copy link

Choose a reason for hiding this comment

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

The variable name self.overlay_changes is inconsistent with the other instance variables which use snake_case (self.exclude_paths, self.recurse_files, etc.). Consider renaming to self.overlay_changed_paths for consistency.

Copilot generated this review using guidance from repository custom instructions.

@tausbntausbn left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Overall I think this looks good. 👍

Do we have any tests for this? I feel like we might want to have a few CLI Integration tests to check that the overlay JSON files are being applied correctly. (The integration tests live here: https://github.com/github/codeql/tree/main/python/extractor/cli-integration-test)

Also, don't forget to update the extractor version here: https://github.com/github/codeql/blob/main/python/extractor/semmle/util.py#L13
(In this case, I think bumping it to 7.1.4 would be fine. We don't really have fixed rules for how to increase the version. The most important thing is that it changes so that we can tell from the log output what version of the extractor we're running.)

Comment threadpython/extractor/semmle/traverser.py Outdated
Comment on lines +36 to +38
if 'CODEQL_EXTRACTOR_PYTHON_OVERLAY_CHANGES' in os.environ:
with open(os.environ['CODEQL_EXTRACTOR_PYTHON_OVERLAY_CHANGES'], 'r', encoding='utf-8') as f:
data = json.load(f)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm debating whether we should have some exception handling here (substituting the empty list of changed files in case something goes wrong). Currently, if something ends up being messed up in the JSON, then I believe the whole extraction will just fail.

I don't have strong feelings about it, though.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Thanks for the review! I also don't have strong opinions about whether file reading should fail loudly or warn and continue with a default (None, i.e. full extraction). I guess I'll go for the latter. And also insert a logger statement with the value of the environment variable, as is the convention elsewhere in the extractor.

@d10c

d10c commented Sep 5, 2025

Copy link
Copy Markdown
ContributorAuthor

Do we have any tests for this? I feel like we might want to have a few CLI Integration tests to check that the overlay JSON files are being applied correctly. (The integration tests live here: https://github.com/github/codeql/tree/main/python/extractor/cli-integration-test)

There are basic integration tests here but they depend on overlay compilation (not part of this commit), and also I'm still running into some issues on Windows (it appears that the path transformer is not working correctly there—currently debugging that). So maybe merging this should wait until I have that sorted.

Otherwise, do you have an idea for an integration test for this functionality that doesn't also exercise complete overlay evaluation?

@d10c
d10cforce-pushed the d10c/python-overlay branch from fb23977 to f309dc6CompareSeptember 10, 2025 18:42
@d10c

d10c commented Sep 10, 2025

Copy link
Copy Markdown
ContributorAuthor

I think I've figured out why path transformers weren't working on Windows and why built-in modules were being extracted (see latest commits). Now the integration test on the other PR passes.

The only remaining thing now is solving some tuple count regressions uncovered through DCA, but that can be done independently of this PR.

Comment threadpython/extractor/semmle/extractors/builtin_extractor.py Outdated

@jbjjbj left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I've written a few comments after reading the discard predicates. I haven't reviewed the rest of this PR.

Comment threadpython/ql/lib/semmle/python/Overlay.qll Outdated
Comment threadpython/ql/lib/semmle/python/Overlay.qll Outdated
Comment on lines +179 to +180
overlay[discard_entity]
private predicate discardLocation(@location loc) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
overlay[discard_entity]
privatepredicatediscardLocation(@location loc){
/**
*Locationsin Python TRAPfiles use named ids, so the overlay database will
*reuselocationentitiesfrom the base. Therefore we should only discard a
*locationifit'snotinusebythe overlay.
*
*Ifthe same element (with a named TRAPid)couldhaveadifferent location
*inbaseandoverlay,thisdiscardingstrategywouldnotpreventthat element
*from appearing to have two locations. However, the Python extractor does not
*usenamedidsforentitiesthatcanchange location.
*/
overlay[discard_entity]
privatepredicatediscardLocation(@location loc){

This is not an obvious predicate. I've suggested a comment here, but I don't even know if it's correct: is it impossible for the same @py_Module entity to have a different location in the base and the overlay?

Also, maybe there should be a comment to say that if we don't discard locations, probably nothing bad will happen. There will just be some unattached locations.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Python locations use *-ids. Which I guess means that the same @py_Module extracted in the overlay would have a different location than in the base extraction. So the base location should be discarded.

with direct or indirect location links in dbscheme.
And don't add slash to start of path patterns on Windows.
…t-in files
On Windows, we're getting e.g. the following mismatches, which could be due to case differences:
"Skipped built-in file C:\hostedtoolcache\windows\Python\3.13.7\x64\Lib\multiprocessing\forkserver.py"
vs "Extracted file C:\hostedtoolcache\windows\Python\3.13.7\x64\lib\asyncio\streams.py"
This way, we filter both root modules and (transitive) imports against the overlay-changes json.
@d10c
d10cforce-pushed the d10c/python-overlay branch from f309dc6 to c2f026dCompareSeptember 12, 2025 21:14
@d10c

d10c commented Oct 2, 2025

Copy link
Copy Markdown
ContributorAuthor

Superceded by PR #20337

@d10cd10c closed this Oct 2, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@d10c@jbj@tausbn@github-advanced-security