Repository navigation
Conversation
anth-volk
added this pull request to stack #755
October 13, 2026 11:40
2 tasks done
anth-volk
force-pushed
the
ruff-typing-imports
branch
from
October 13, 2026 16:56
18fae4c to
f651387
Compare
anth-volk
force-pushed
the
ruff-typing-imports
branch
4 times, most recently
from
October 14, 2026 17:29
6c25653 to
da295a5
Compare
anth-volk
force-pushed
the
ruff-typing-imports
branch
from
October 14, 2026 17:56
da295a5 to
ed7598a
Compare
anth-volk
force-pushed
the
ruff-typing-imports
branch
3 times, most recently
from
October 14, 2026 21:06
ccd5b09 to
fcc9970
Compare
anth-volk
force-pushed
the
ruff-typing-imports
branch
2 times, most recently
from
October 14, 2026 21:52
0169985 to
e9b8225
Compare
anth-volk
force-pushed
the
ruff-typing-imports
branch
from
October 15, 2026 14:06
e9b8225 to
123745c
Compare
anth-volk
force-pushed
the
ruff-typing-imports
branch
from
October 15, 2026 15:09
123745c to
1b6b51a
Compare
Select TC and move imports used only in annotations under TYPE_CHECKING. Pydantic evaluates model annotations and FastAPI evaluates endpoint annotations at runtime, so ruff.toml lists the runtime-evaluated model base classes (every project base, since ruff only checks direct bases) and the FastAPI/APIRouter route decorators. scripts/rules matches policyengine-api. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#789 landed on main after this stack branched. TC, which this PR enables, flags the annotation-only imports in its new database-retry and failure-recording modules; they now load only under TYPE_CHECKING. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#791 landed on main after this stack branched. TC, which this PR enables, flags the imports its new Stage 12 failure-cause module uses only in annotations (Iterator, Mapping, ObservabilityRuntime, Stage and StagePlan); they move under TYPE_CHECKING. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ruff treats a class as runtime-evaluated when a base, read through the import statements of the class's own module, is listed in runtime-evaluated-base-classes, or is a class in that same module that is. It never follows a re-export, and only follows inheritance within a module. Four models had bases ruff reads at unlisted paths, so ruff would have moved imports their annotations need under TYPE_CHECKING if they gained any: - ArtifactBaselineSimulation and PrecomputedSimulation subclass policyengine.py's policyengine.core.Simulation; - AppSettings subclasses pydantic_settings.BaseSettings; - EconomyComparison subclassed SingleYearMacroOutput through the executor's simulation_macro_output re-export. The first two paths are listed as their subclasses import them. For EconomyComparison, compat_models now imports SingleYearMacroOutput from policyengine_simulation_contract.macro_output, the module that defines it, and that path is listed: every project entry then names its defining module, and the entry also covers subclasses elsewhere that import the class from the contract. The ruff.toml comment now describes how ruff resolves bases instead of "direct bases only". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The executor's test imports every module of the executor package and of the project libraries installed with it; the entrypoint's imports every module of its package. For every Pydantic model a module-level class statement defines, they check that: - ruff treats it as runtime-evaluated, resolving each base the way ruff does: through the model module's import statements as they stand at the class statement, reading Base[Item] as Base, following bases defined in the same module, and never following a re-export or an assignment. A failure names the model and the base path to list; - its annotations resolve, with model_rebuild(raise_errors=True). Unit tests pin the resolution: a listed base, a subscripted one, a relative import, a same-module chain through Generic, an unlisted re-export, an unlisted third-party base, an assigned alias, and a base in a package's __init__.py, which ruff names with __init__ in its path. The proof fixtures are compat_models.py before and after the previous commit. The executor's src/modal Modal entry files are not imported: they are not part of the installed package, and importing them builds Modal images and functions, which their tests do only with a fake Modal SDK and a patched environment. A static test checks that every class there derives only from builtins and the standard library, so none can be a model. The gateway defines no Pydantic models. The entrypoint shares no package with the executor that could hold test helpers, so it keeps a copy of the resolution helpers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ports sim.quality.runtime-evaluated-models-resolve is enforced by the two new test files, which run in the executor and entrypoint jobs of the PR test matrix. Its nodes span both projects, so they are listed from the repository root without a project. The test files join the guard-test discovery globs, so any test added to them must be registered. docs/engineering/skills/typing-only-imports.md explains when ruff moves an import, how it decides a model is runtime-evaluated, and how to list model bases; AGENTS.md and the skills README point to it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#781 landed on main after this stack branched. TC, which this PR enables, flags the imports its contract job_progress module uses only in annotations (Mapping and datetime), which move under TYPE_CHECKING, and the cast in its new integration poll test, whose Client type is quoted. The module's Pydantic models annotate their timestamps with AwareDatetime, which stays a runtime import. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#781 landed on main after this stack branched. It added StageReportingSimulation, a policyengine.core.Simulation subclass, and made ArtifactBaselineSimulation subclass it from another module. Ruff reads that base through baseline_artifacts' import, which is not listed, so it would no longer treat ArtifactBaselineSimulation as runtime-evaluated. The sim.quality.runtime-evaluated-models-resolve guard names the path to list; it is added beside the other project bases. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
anth-volk
force-pushed
the
ruff-typing-imports
branch
from
October 15, 2026 21:56
80a1eec to
8c3125d
Compare
This branch has not been deployed
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.
Fixes #772
Same-Repository Draft PR Check
PolicyEngine/policyengine-sim-api, not a personal fork.Summary
Phase 1 step 1.8, group 2: typing-only imports. Stacked on #765.
ruff.tomlgainsTC, and 146 fixes move annotation-only imports underTYPE_CHECKING.[lint.flake8-type-checking]lists:pydantic.BaseModel,pydantic.RootModel, and every project model base class that other models inherit from: 10 across the contract,policyengine-fastapiand executor packages.FastAPI/APIRouterroute decorators. Pydantic and FastAPI evaluate these annotations at runtime.scripts/rulesis byte-identical with policyengine-api.Testing
All seven projects' test suites pass:
ruff check .passes with 0.15.22 and 0.16.8, andsrcformatting is unchanged.🤖 Generated with Claude Code