Skip to content

[TIDY-FIRST] Type the runners - Part 2#12810

Merged
QMalcolm merged 5 commits intomainfrom
qmalcolm--tidy-first-type-the-runners-part-2
Apr 10, 2026
Merged

[TIDY-FIRST] Type the runners - Part 2#12810
QMalcolm merged 5 commits intomainfrom
qmalcolm--tidy-first-type-the-runners-part-2

Conversation

@QMalcolm
Copy link
Copy Markdown
Contributor

@QMalcolm QMalcolm commented Apr 9, 2026

Summary

Continues the runner typing work from part 1 by introducing a NodeT TypeVar on BaseRunner, then specializing each runner subclass to its concrete node type. This eliminates the remaining union-attr and override ignores on self.node attribute accesses across the runner hierarchy.

Commits, in order:

  • Add NodeT TypeVar to BaseRunnerBaseRunner is now Generic[NodeT, RunnerResultT]; self.node is typed as NodeT; execute() takes compiled_node: NodeT
  • Specialize CompileRunner hierarchyCompileRunner[CompilableNodeT], ModelRunner[ModelNode], FunctionRunner[FunctionNode], ShowRunner[ManifestSQLNode]; removes all 8 union-attr ignores in run.py and the override ignore on MicrobatchModelRunner.execute
  • Specialize FreshnessRunner[SourceDefinition] and improve TestRunner — removes union-attr on self.node.source_name; corrects UnitTestDefinition vs UnitTestNode type usage in TestRunner
  • Specialize CloneRunner and NoOpRunner as BaseRunner[ResultNode, RunResult]
  • Fix remaining local-var ignores in freshness.py — retype _metadata_freshness_cache to Dict[BaseRelation, FreshnessResponse]; use a separate variable for adapter_response_dict to avoid reassignment ignore

Test plan

  • hatch run default:mypy core/dbt/ passes (or ignore count decreases)
  • hatch run default:pytest tests/unit/ passes
  • Runner-related functional tests pass

🤖 Generated with Claude Code

@QMalcolm QMalcolm requested a review from a team as a code owner April 9, 2026 19:32
@cla-bot cla-bot bot added the cla:yes label Apr 9, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

Thank you for your pull request! We could not find a changelog entry for this change. For details on how to document a change, see the contributing guide.

@QMalcolm QMalcolm changed the title [TIDY-FIRST] Type the runners, part 2: NodeT TypeVar on BaseRunner [TIDY-FIRST] Type the runners - Part 2 Apr 9, 2026
@QMalcolm QMalcolm added the Skip Changelog Skips GHA to check for changelog file label Apr 9, 2026
@QMalcolm
Copy link
Copy Markdown
Contributor Author

QMalcolm commented Apr 9, 2026

@QMalcolm QMalcolm force-pushed the qmalcolm--tidy-first-type-the-runners branch from ce3f829 to 43f38ea Compare April 9, 2026 20:06
@QMalcolm QMalcolm force-pushed the qmalcolm--tidy-first-type-the-runners-part-2 branch from 122b135 to 6c831bb Compare April 9, 2026 20:07
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 9, 2026

Codecov Report

❌ Patch coverage is 95.45455% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.37%. Comparing base (26c9c8c) to head (96eb75e).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #12810   +/-   ##
=======================================
  Coverage   91.36%   91.37%           
=======================================
  Files         203      203           
  Lines       25884    25881    -3     
=======================================
- Hits        23649    23648    -1     
+ Misses       2235     2233    -2     
Flag Coverage Δ
integration 88.16% <88.63%> (+<0.01%) ⬆️
unit 65.54% <59.09%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
Unit Tests 65.54% <59.09%> (+0.01%) ⬆️
Integration Tests 88.16% <88.63%> (+<0.01%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

MichelleArk
MichelleArk previously approved these changes Apr 10, 2026
Base automatically changed from qmalcolm--tidy-first-type-the-runners to main April 10, 2026 15:34
@QMalcolm QMalcolm dismissed MichelleArk’s stale review April 10, 2026 15:34

The base branch was changed.

QMalcolm and others added 5 commits April 10, 2026 10:40
…tion

BaseRunner is now Generic[NodeT, RunnerResultT] where:
- RunnerResultT (existing) = the result type (RunResult, FreshnessNodeResult, etc.)
- NodeT (new) = the node type the runner operates on (ModelNode, SourceDefinition, etc.)

self.node is now typed as NodeT instead of ResultNode, which will allow
subclasses to declare their concrete node type and eliminate all
[union-attr] ignores on self.node attribute accesses.

The abstract execute() now takes compiled_node: NodeT so subclass overrides
with narrower types (ModelNode, FunctionNode, etc.) no longer violate LSP.
A single type: ignore[arg-type] in run() bridges the ResultNode from
ExecutionContext to the NodeT that execute() expects.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…erride ignores

- CompileRunner(BaseRunner[CompilableNodeT, RunResult]): CompilableNodeT is a
  new TypeVar bound to ManifestSQLNode, allowing compile_node(self.node, ...)
  to be called without type: ignore[arg-type]
- ModelRunner(CompileRunner[ModelNode]): self.node is now ModelNode, removing
  all 8 union-attr ignores on ModelNode-specific attributes in run.py
  (language, config.batch_size, config.concurrent_batches, has_this, batch,
  previous_batch_results) and the override ignore on MicrobatchModelRunner.execute
- FunctionRunner(CompileRunner[FunctionNode]): removes the __init__ workaround
  (assert isinstance + self.node reassignment) and the override ignore on execute
- ShowRunner(CompileRunner[ManifestSQLNode]): ShowRunner processes any
  compileable node type

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… typing

FreshnessRunner:
- Now BaseRunner[SourceDefinition, FreshnessNodeResult]: removes union-attr on
  self.node.source_name (before_execute)
- after_execute simplified: use self.node.source_name/name directly instead of
  hasattr(result, "node") branch (which was always true since both
  PartialSourceFreshnessResult and SourceFreshnessResult inherit node from
  NodeResult); removes 3 union-attr ignores

TestRunner:
- UnitTestDefinition is not in ManifestSQLNode/ResultNode so TestRunner cannot
  be fully specialized without a node-type hierarchy change; use
  CompileRunner (type: ignore[type-arg]) to keep existing behavior
- describe_node_name: replace resource_type == NodeType.Unit check with proper
  isinstance(self.node, UnitTestDefinition) — removes attr-defined ignore
- execute: corrects type from Union[TestNode, UnitTestNode] to
  Union[TestNode, UnitTestDefinition] (model/versioned_name are on
  UnitTestDefinition, not UnitTestNode)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…sult]

These runners operate on any refable/generic node type, so ResultNode is the
correct NodeT — no node-specific attribute accesses to narrow further.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
freshness.py:
- _metadata_freshness_cache: retype from Dict[BaseRelation, FreshnessResult]
  to Dict[BaseRelation, FreshnessResponse] (FreshnessResponse is the TypedDict
  with age/max_loaded_at/snapshotted_at that the code actually stores); removes
  assignment and index ignores on freshness cache lookup and freshness["age"]
- adapter_response: use separate adapter_response_dict variable instead of
  reassigning adapter_response from AdapterResponse to Dict; removes assignment
  and arg-type ignores

build.py:
- RUNNER_MAP.get() returns ABCMeta | None which doesn't match
  Optional[Type[BaseRunner[Any, Any]]] after BaseRunner became generic;
  suppress with type: ignore[return-value]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@QMalcolm QMalcolm force-pushed the qmalcolm--tidy-first-type-the-runners-part-2 branch from 6c831bb to 96eb75e Compare April 10, 2026 15:43
@QMalcolm
Copy link
Copy Markdown
Contributor Author

Rebased off of main after the squash merge of #12803

@QMalcolm QMalcolm merged commit 43defc9 into main Apr 10, 2026
122 checks passed
@QMalcolm QMalcolm deleted the qmalcolm--tidy-first-type-the-runners-part-2 branch April 10, 2026 17:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla:yes Skip Changelog Skips GHA to check for changelog file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants