Skip to content

TYP: enable mypy check_untyped_defs for shap/plots/_force - #4760

Open
SarthakB11 wants to merge 3 commits into
shap:mainfrom
SarthakB11:typ/3730-force-plot-type-hints
Open

SarthakB11 wants to merge 3 commits into
shap:mainfrom
SarthakB11:typ/3730-force-plot-type-hints

Conversation

@SarthakB11

Copy link
Copy Markdown
Contributor

Summary

  • Adds type annotations to all functions and classes in shap/plots/_force.py
  • Removes shap.plots._force from the check_untyped_defs = false override in pyproject.toml
  • mypy shap/plots/_force.py now passes with zero errors

Changes

shap/plots/_force.py

  • from __future__ import annotations added to resolve the matplotlib: bool parameter / matplotlib.figure.Figure return-type name conflict
  • Figure imported only under TYPE_CHECKING (no runtime cost)
  • All module-level functions annotated: force, visualize, save_html, getjs, initjs, id_generator, ensure_not_numpy, verify_valid_cmap
  • Explanation.__init__ and AdditiveExplanation.__init__ annotated with precise legacy types (DenseData, Link, Model, Instance)
  • All Visualizer classes annotated: SimpleListVisualizer, AdditiveForceVisualizer, AdditiveForceArrayVisualizer (all __init__, html, _repr_html_, matplotlib methods)
  • BaseVisualizer.html() stub added so save_html() type-checks correctly
  • filter(lambda ...) patterns converted to generator expressions for mypy compatibility

pyproject.toml

  • "shap.plots._force" commented out following the existing # NOW TYPE CHECKED convention

Test

mypy shap/plots/_force.py --no-error-summary 2>&1 | grep "_force.py"
# (no output — zero errors)

AI Disclosure

Type annotations were drafted with AI assistance (Claude) and verified manually against the source code, runtime behaviour, and mypy output.

Part of #3730.

SarthakB11 and others added 3 commits April 22, 2026 21:59
Add type annotations to all functions and classes in shap/plots/_force.py
and remove the module from the mypy check_untyped_defs exclusion list.

- Add from __future__ import annotations to resolve the matplotlib
  parameter/module name conflict in force() and visualize()
- Annotate force(), visualize(), save_html(), getjs(), initjs(),
  id_generator(), ensure_not_numpy(), verify_valid_cmap()
- Annotate all Visualizer __init__, html(), _repr_html_(), matplotlib()
  methods across SimpleListVisualizer, AdditiveForceVisualizer,
  AdditiveForceArrayVisualizer
- Annotate AdditiveExplanation.__init__ with precise legacy types
- Add html() stub to BaseVisualizer so save_html() type-checks
- Convert filter(lambda...) to generator expressions for mypy compatibility
- Use TYPE_CHECKING guard for matplotlib.figure.Figure import (no runtime cost)
- Comment out shap.plots._force from pyproject.toml override

Closes part of shap#3730
SimpleListVisualizer: annotation was AdditiveExplanation (contradicting
the isinstance(e, Explanation) runtime guard and the call site in
visualize()). Fix: annotate e as Explanation to match the guard, then
cast to AdditiveExplanation internally for attribute access. Remove the
now-unnecessary type: ignore on the SimpleListVisualizer(e) call in
visualize().

ordering_keys: was silently changed from hasattr(ordering_keys, '__iter__')
to 'is not None', which is a behavioral difference for untyped callers
passing non-iterable non-None values. Restore the original guard and scope
the type: ignore to the list() call only.
@SarthakB11

Copy link
Copy Markdown
Contributor Author

@CloseChoice bumping this, part of the #3730 type-annotation migration series alongside #4445/#4761/#4772. CI green, no review yet.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant