[MAINTENANCE] Type-check great_expectations/render/renderer/
Part of #12188.
What to do
Bring the six excluded modules under great_expectations/render/renderer/ into the
type-check: remove their six exclude patterns from pyproject.toml, fix the errors mypy
then reports, regenerate the relaxation inventory in the same change, and prove that no
rendered byte changed.
These modules build every Data Docs page and Slack payload a user sees, and their test coverage is thin precisely because they were never checked. So the bar is higher than "mypy is green": fix each error at its cause, widen a declaration rather than narrow it, and if the only fix you can see changes what a renderer emits, comment here before writing it.
One error is dead code rather than a typing gap: _build_run_time_block in
slack_renderer.py guards if run_id is not None, then reads formatted_run_time outside
the guard. The None case cannot arrive — CheckpointResult.run_id is a required
RunIdentifier, and Checkpoint.run mints one when the caller passes none. Remove the guard
so the name is bound on the one real path; do not widen the type to admit a value that never
comes. Say that reasoning in the commit.
Where
render/renderer/content_block/content_block.py12,site_builder.py11,page_renderer.py8,content_block/exception_list_content_block.py6,slack_renderer.py3,profiling_results_overview_section_renderer.py2 — 42 errors after #12189 merges (51 before it). By kind: 15union-attr, 5misc, 4override, 4attr-defined, and a tail.pyproject.toml— remove the sixexcludeentries underrender/renderer/.scripts/mypy_relaxation_inventory.json— regenerate with the guard's emit mode, never by hand.
How to verify
Files named on mypy's command line are checked even while an exclude pattern covers them,
so this is red today and green only when both the errors and the patterns are gone
(--cache-dir=/dev/null keeps the count independent of earlier runs):
mypy --cache-dir=/dev/null --warn-unused-ignores --disallow-untyped-decorators great_expectations/render/renderer/*.py great_expectations/render/renderer/content_block/*.py && ! grep -q "'render/renderer/" pyproject.tomlThen python scripts/mypy_config_guard.py --emit-inventory > scripts/mypy_relaxation_inventory.json,
invoke type-check --ci, and pytest tests/render tests/actions tests/checkpoint.
Then the rendered-output check: build Data Docs twice from the same fixed input — an
ephemeral context, one small pandas DataFrame, a suite that exercises the expectations whose
renderers these modules drive, one checkpoint run, context.build_data_docs() — once at your
merge-base and once on your branch, and diff the two site directories after stripping run ids
and timestamps. Before trusting a clean diff, prove it can fail: change one rendered string
locally, see the diff flag it, revert. Put the procedure and the result in the PR.
Before: 42 errors in six files with #12189 merged, 51 without it (at 3798c021b).
invoke type-check --ci checks 939 files with #12190 merged.
After: the fence exits 0; invoke type-check --ci reports zero errors over 945 files; the
three test directories pass as they do today; an empty normalized Data Docs diff.
Requirements
- When the type-check runs on the merged change, it reports zero errors and no
excludepattern naming a path underrender/renderer/remains. pytest tests/render tests/actions tests/checkpointmust pass with the same outcomes as before, with no expected value, assertion, skip, or xfail changed or added.- Data Docs built from identical input before and after the change must be byte-identical apart from run ids and timestamps, and the PR must say how that was checked.
- The
slack_renderer.pypossibly-undefinederror is resolved by removing the dead guard, with its output on every supported path unchanged. If your own call-path analysis finds a path whererun_idisNone, comment here and do not remove the guard. - No public signature narrows, renames, or changes a default; a new
# type: ignore[code]is acceptable only where every code-level fix would change output or break a public surface, and each one is single-line, commented, and listed in the PR. - The inventory must be regenerated by
python scripts/mypy_config_guard.py --emit-inventoryin the same change, and the guard must pass.
Out of scope: the follow_imports = 'silent' block (#12192); great_expectations/render/ components.py's constructor contracts and the renderer configuration/result nullability
convention, settled in #12116 — comment here if an error traces to them; anything under
tests/ (#12128).
Order
- Blocked by #12190 — the two lifts edit the same lines of
pyproject.tomland the inventory, and this issue's error count is only meaningful against the merged state of that one. - Blocks #12192 — the silent-imports block must outlive every library exclusion.
Notes
page_renderer.py's_parse_run_valuescarried a second guard of the same shape until #12098 found a realNonereaching it. That is why the Slack site gets its own call-path check before anything is deleted.- If a genuine runtime bug surfaces while you type a module, open a separate issue for it.
Source: fivetran/great_expectations