ci(python): add advisory ty type checking with SARIF reporting - #3752
ci(python): add advisory ty type checking with SARIF reporting#3752mcosgriff wants to merge 2 commits into
Conversation
- Add python_type_check.yml alongside python_lint, running ty with
--exit-zero so it annotates but never fails the build yet
- Add tools/ty_report.py to convert ty's GitLab JSON into SARIF for
code scanning, since ty cannot emit SARIF and its paths need
rewriting to be repo-root relative
- Add tools/generate_singleton_stubs.py and the five .pyi it emits, so
metaclass-forwarded calls like Logger.info("msg") check correctly;
drops diagnostics from 816 to 675
- Pass --no-build and --no-install-project to every uv step, so no
build backend executes in CI
- Add ty dev dependency plus just stubs and typecheck recipes
Co-Authored-By: Claude noreply@anthropic.com
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3752 +/- ##
==========================================
+ Coverage 80.01% 80.04% +0.03%
==========================================
Files 885 885
Lines 65382 65382
Branches 2543 2543
==========================================
+ Hits 52313 52336 +23
+ Misses 12407 12387 -20
+ Partials 662 659 -3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
- Lock the PEP 723 dependencies of both tools scripts and pass --locked everywhere, so a new mypy or ruff release cannot silently change what runs or make stubs-check report spurious drift - Validate --input, --sarif and --markdown in ty_report.py before touching the file system, confining them to the repo, cwd, temp dir and the paths the runner declares via GITHUB_STEP_SUMMARY and friends - Reject traversing arguments, symlinks, directories and missing parents with a clear message and exit 1 instead of writing Co-Authored-By: Claude noreply@anthropic.com
|


Why
The Python library has no static type checking today — only ruff, which catches style and a narrow band of correctness issues. Real type errors reach runtime, and in a command-and-control system that means they surface during an operation rather than in CI.
The obvious approach — turn ty on and gate PRs on it — doesn't work here. A bare ty check reports 816 diagnostics on the current tree, so a blocking check would fail every PR on day one and get disabled within a week. This PR is the groundwork that makes ty usable at all:
Summary
Deliberately out of scope: fixing the remaining 675. Roughly half trace to two declaration patterns rather than 675 distinct problems — singleton class attributes declared instance = None and never reset (91 in running_script.py alone, all downstream of one untyped declaration), and instance attributes assigned None then immediately reassigned. Those are source changes with real review cost and belong in follow-ups; this PR establishes the check and the reporting so those follow-ups have a baseline to measure against.
Worth noting the check already found at least one genuine bug it wasn't looking for: running_script.py:1136 guards on not RunningScript.instance, which is always false since instance is set in init and never reset — so that output-thread cleanup never runs.
Test plan
Note: upload-sarif needs a write token, so the code-scanning upload is expected to fail on fork PRs. It's marked continue-on-error: true; the job summary and SARIF artifact still work there.