[TIDY-FIRST] Add typing to BaseRunner and subclasses (Part 1)#12803
Merged
[TIDY-FIRST] Add typing to BaseRunner and subclasses (Part 1)#12803
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #12803 +/- ##
==========================================
- Coverage 91.41% 91.36% -0.05%
==========================================
Files 203 203
Lines 25879 25884 +5
==========================================
- Hits 23657 23649 -8
- Misses 2222 2235 +13
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
16805ec to
02a4a97
Compare
122b135 to
ce3f829
Compare
This was referenced Apr 9, 2026
Contributor
Author
|
This is a stacked PR |
Types node in ExecutionContext, and all parameters and instance variables in BaseRunner.__init__, using ResultNode and BaseAdapter. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
These methods raised NotImplementedError at runtime but were not decorated with @AbstractMethod, giving no static guarantee that subclasses implement them. Converting them to proper abstract methods catches missing implementations at class-definition time rather than at runtime. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces RunnerResultT = TypeVar("RunnerResultT", bound=NodeResult) and
makes BaseRunner generic over it. All result-producing methods (safe_run,
run_with_hooks, error_result, ephemeral_result, from_run_result,
compile_and_execute, execute, run, on_skip, _build_run_result) now declare
their return types in terms of RunnerResultT.
The base _build_run_result and on_skip implementations construct RunResult
directly (valid for all RunResult-returning subclasses); subclasses with
different result types (FreshnessRunner, GenericSqlRunner) override these
methods entirely. Targeted type: ignore comments are placed only at those
two concrete construction points.
Also moves the skip_cause None guard before its first use in on_skip,
fixing a latent runtime error if the guard condition were ever triggered
in a different order.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Declares CompileRunner(BaseRunner[RunResult]) so that all inherited result-producing methods are statically known to return RunResult. Adds return type annotations to before_execute, after_execute, and execute. The compile() method's type: ignore[arg-type] documents a pre-existing semantic constraint: CompileRunner is only used with compileable node types, but the ResultNode union includes SeedNode and SourceDefinition which compile_node does not accept. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…markers GenericSqlRunner uses SQLResult (bound to RemoteCompileResultMixin) which belongs to a completely separate type hierarchy from NodeResult/RunResult. It cannot be a valid BaseRunner[RunnerResultT] and its execute/from_run_result overrides intentionally return a different type than CompileRunner declares. Mark each override point with # type: ignore[override] and add a class-level comment explaining the violation, making the boundary visible rather than silently wrong. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds return type annotations to ModelRunner.after_execute, ModelRunner.execute, MicrobatchBatchRunner.on_skip, and MicrobatchBatchRunner.error_result. MicrobatchModelRunner.execute(model: ModelNode) already had a narrowed type annotation; marks it # type: ignore[override] to document that it intentionally accepts a more specific argument type than the base class requires. The remaining type: ignore[union-attr/arg-type] markers document pre-existing issues surfaced by typing self.node as ResultNode: MicrobatchBatchRunner and MicrobatchModelRunner access ModelNode-specific attributes (batch, has_this, previous_batch_results, config.batch_size, config.concurrent_batches) that are not present on the full ResultNode union. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
TestRunner.execute accepts Union[TestNode, UnitTestNode] which narrows the first parameter relative to BaseRunner; marks it # type: ignore[override]. TestRunner uses TestStatus internally but still returns RunResult, so the return type is compatible. Adds # type: ignore[attr-defined] on describe_node_name for the UnitTestNode branch, where model/versioned_name attributes exist on UnitTestDefinition but not on all ResultNode union members. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
FreshnessRunner is the only runner that returns a completely different result type from the standard RunResult hierarchy. By declaring it as BaseRunner[FreshnessNodeResult], the return types of execute, error_result, _build_run_result, from_run_result, and on_skip are all statically known to return FreshnessNodeResult. _build_run_result carries # type: ignore[override] because FreshnessRunner's signature omits the agate_table/adapter_response/failures/batch_results parameters that the base declares; this is intentional — freshness results do not need those fields. Pre-existing type issues surfaced by self.node: ResultNode (source_name only on SourceDefinition, FreshnessResponse typing in execute) are documented with targeted type: ignore markers. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Declares CloneRunner(BaseRunner[RunResult]) and NoOpRunner(BaseRunner[RunResult]). Adds return type annotations to execute and after_execute on each. Adds return type to ShowRunner.execute. SeedRunner and SnapshotRunner inherit from the already-typed ModelRunner and do not override the result-returning methods, so no changes needed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- call_runner() -> NodeResult (was RunResult): runner.run_with_hooks() can return FreshnessNodeResult for FreshnessRunner, so RunResult was too narrow - _handle_result(result: NodeResult): only accesses .node, .status, and .to_msg_dict() which are all available on NodeResult - _mark_dependent_errors now takes NodeResult / Optional[NodeResult] for result and cause parameters - _skipped_children dict broadened to Dict[str, Optional[NodeResult]] - Add # type: ignore[arg-type] on run_with_hooks(self.manifest) since self.manifest is Optional[Manifest] but guaranteed non-None at runtime Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- build.py: call_model_and_unit_tests_runner() -> NodeResult (was RunResult), since it returns call_runner() which now returns NodeResult; drop unused RunResult import, add NodeResult import - function.py: add # type: ignore[override] on FunctionRunner.execute() which narrows compiled_node to FunctionNode (an LSP violation like other runners that operate on specific node subtypes) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After making before_execute, after_execute, and execute abstract in BaseRunner, MockRunner in the test file needs stub implementations to be instantiable. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
call_runner() now returns NodeResult, but MicrobatchModelRunner.execute() always returns RunResult. Use cast() to satisfy the List[RunResult] type at the batch_results.append call site. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ce3f829 to
43f38ea
Compare
MichelleArk
approved these changes
Apr 10, 2026
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.
Summary
BaseRunnergeneric over its result type viaBaseRunner[RunnerResultT]whereRunnerResultT = TypeVar("RunnerResultT", bound=NodeResult)before_execute,after_execute, andexecutefromraise NotImplementedErrorto true@abstractmethodsRunResult,FreshnessNodeResult, etc.)call_runnerand_handle_resultinrunnable.pytoNodeResultto correctly handleFreshnessRunner's result typeCommits
Each commit is independently reviewable:
a3b564a— Add type annotations toExecutionContextandBaseRunner.__init__284e1e5— Makebefore_execute,after_execute,executeabstract inBaseRunnere6df3e0— AddRunnerResultTgeneric TypeVar toBaseRunner5e8f601— TypeCompileRunnerasBaseRunner[RunResult]52fe025— DocumentGenericSqlRunner's LSP violation with explicittype: ignoremarkers2ed5917— TypeModelRunner,MicrobatchBatchRunner,MicrobatchModelRunner1853ac0— TypeTestRunner.executeandafter_executefa59711— TypeFreshnessRunnerasBaseRunner[FreshnessNodeResult]4ba5156— Type remaining runners:CloneRunner,NoOpRunner,ShowRunner85502ca— Typerunnable.py: broadencall_runnerand_handle_resulttoNodeResultNotable design decisions
GenericSqlRunner: UsesRemoteCompileResultMixinas its result type, which is not aNodeResultsubtype, so it cannot satisfy theRunnerResultTbound. It is kept in theCompileRunnerMRO and its overriding methods are annotated with# type: ignore[override]with an explanatory comment block.FreshnessRunner: Typed asBaseRunner[FreshnessNodeResult]whereFreshnessNodeResult = Union[PartialSourceFreshnessResult, SourceFreshnessResult]— both areNodeResultsubtypes.MicrobatchModelRunnerandTestRunneraccess subtype-specific attributes (ModelNode,TestNode) onself.node: ResultNode; these are suppressed with targeted# type: ignore[union-attr/attr-defined].Test plan
🤖 Generated with Claude Code