⚡ Sangsakala Proxy 🏠 Home
Skip to content

Python: reintroduce instance-attribute type-tracking without the classInstanceTracker blow-up (try 2) - #22965

Open
owen-mc wants to merge 6 commits into
github:mainfrom
owen-mc:copilot/reintroduce-functionality
Open

owen-mc wants to merge 6 commits into
github:mainfrom
owen-mc:copilot/reintroduce-functionality

Conversation

@owen-mc

@owen-mc owen-mc commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

Note: this is a copy of #22097, which was accidentally merged into an old release branch instead of main.

#22092 disabled the instanceFieldStep disjunct of TypeTrackingInput::levelStepCall because it identified instances via classInstanceTracker — a full type-tracker run — from inside levelStepCall, creating a mutual recursion that caused catastrophic slowdowns on OOP-heavy code bases (e.g. mypy, dask). This reintroduces the same flow (a value stored on self.attr in a method, read later as instance.attr) via a cheaper instance-identification strategy.

Change

  • instanceAttrRead now identifies the instance using local flow (getALocalSource(), purely simpleLocalFlowStep-based) from a constructor call resolved by resolveClassCall/classTracker, instead of classInstanceTracker. This drops the recursive dependency to the same call-graph machinery already used by the un-disabled inheritedFieldStep.
  • instanceFieldStep is otherwise unchanged (same levelStepCall shape, same getADirectSuperclass* relation).
  • Updated QLDoc + change note.
private predicate instanceAttrRead(Class cls, string attr, DataFlowPublic::AttrRead read) {
  exists(DataFlowPublic::CallCfgNode construction |
    DataFlowDispatch::resolveClassCall(construction.asCfgNode(), cls) and
    read.getObject().getALocalSource() = construction
  ) and
  read.mayHaveAttributeName(attr)
}

Trade-off

Precision drops for instances that flow across a call/return before being read — these are no longer covered, since the instance is now tracked only by local flow rather than a dedicated instance type-tracker.

Notes for reviewers

  • The 4 external-instance-read results previously produced by instanceFieldStep are reproduced; typetracking, dataflow, callgraph, ApiGraphs, and taint library tests pass.
  • The performance improvement is argued from the dependency structure (classTracker + local flow vs. classInstanceTracker); it was not measured against mypy/dask in this environment, so confirming the blow-up is resolved on those code bases is worth doing before merge.

@owen-mc
owen-mc marked this pull request as ready for review November 3, 2026 14:03
Copilot AI auto review requested due to automatic review settings November 3, 2026 14:03
@owen-mc
owen-mc requested a review from a team as a code owner November 3, 2026 14:03
@owen-mc
owen-mc requested a review from yoff November 3, 2026 14:04
@owen-mc

owen-mc commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

@yoff Please can you review? This is identical to #22097, which you approved, just targeted at main this time.

Copilot AI 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.

🟡 Changes recommended

The documentation needs to acknowledge the remaining indirect instance-tracker recursion and clarify that restored tracking requires local flow from a resolved constructor call.

2 open issues
What changed in this PR

Restores Python instance-attribute type tracking disabled by the earlier performance hotfix, using a narrower instance-identification strategy.

Changes:

  • Re-enables instance-field flow using local flow from resolved constructor calls.
  • Updates tests for restored external attribute reads and SQL injection detection, and adds a call/return limitation case.
  • Updates QLDoc and adds a change note describing the coverage trade-off.
File Description
python/​ql/​test/​query-tests/​Security/​CWE-089-SqlInjection/​SqlInjection.expected Records the restored SQL injection result and flow path.
python/​ql/​test/​query-tests/​Security/​CWE-089-SqlInjection/​app.py Updates inline source and alert expectations for /unsafe3/.
python/​ql/​test/​library-tests/​dataflow/​typetracking/​attribute_tests.py Updates external-read expectations and adds a function-return limitation case.
python/​ql/​lib/​semmle/​python/​dataflow/​new/​internal/​TypeTrackingImpl.qll Re-enables instance-field tracking with local constructor sources and updates QLDoc.
python/​ql/​lib/​change-notes/​2026-06-30-instance-attribute-typetracking-performance.md Documents restored tracking and its coverage limits.

Review effort: Max (auto)

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants