Skip to content

TYP: enable mypy check_untyped_defs for shap/maskers/_image - #4761

Open
SarthakB11 wants to merge 1 commit into
shap:mainfrom
SarthakB11:typ/3730-image-masker-type-hints
Open

SarthakB11 wants to merge 1 commit into
shap:mainfrom
SarthakB11:typ/3730-image-masker-type-hints

Conversation

@SarthakB11

Copy link
Copy Markdown
Contributor

Summary

  • Adds type annotations to all functions and classes in shap/maskers/_image.py
  • Removes shap.maskers._image from the check_untyped_defs = false override in pyproject.toml
  • mypy shap/maskers/_image.py passes with zero new errors (only the pre-existing numba.njit attr-defined error shared with _clustering.py and _masked_model.py, which disappears in CI where numba is not installed)

Changes

shap/maskers/_image.py

  • from __future__ import annotations + numpy.typing as npt added
  • Class-level variable declarations added so _blur_value_cache is typed as npt.NDArray[Any] | None rather than inferred as None
  • __init__ annotated; int(np.prod(...)) wrap added (returns np.intp, base class expects int); targeted # type: ignore for issubclass-based guard (mypy cannot narrow on issubclass, changing to isinstance would be a behavior change) and for tuple(map(int, ...)) returning variable-length tuple
  • assert self._blur_value_cache is not None added before index access — logically safe (the if self.last_xid != id(x) block above always assigns it), narrows the type for mypy
  • __call__ annotated with x: Any (accepts torch.Tensor + ndarray), mask: npt.NDArray[Any] | bool | None, # type: ignore[override] since base class does not allow None mask
  • inpaint, build_partition_tree, save, load annotated
  • _jit_build_partition_tree annotated with # type: ignore[misc] on @njit (project convention, same as _clustering.py)

pyproject.toml

  • "shap.maskers._image" commented out following the existing # NOW TYPE CHECKED convention

Test

.venv/bin/mypy shap/maskers/_image.py --no-error-summary 2>&1 | grep "_image.py"
# shap/maskers/_image.py:10: error: Module "numba" has no attribute "njit"  [attr-defined]
# (pre-existing, shared with _clustering.py and _masked_model.py, gone in CI)

AI Disclosure

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

Part of #3730.

Add type annotations to all functions and classes in shap/maskers/_image.py
and remove the module from the mypy check_untyped_defs exclusion list.

- Add from __future__ import annotations and numpy.typing (npt) import
- Add class-level variable declarations so _blur_value_cache is known
  as npt.NDArray[Any] | None (not inferred as None from __init__ alone)
- Annotate __init__, __call__, inpaint, build_partition_tree, save, load
- Add assert self._blur_value_cache is not None before the index access
  to narrow the type after the lazy-init guard (logically safe: the
  if-block above always assigns it before this line)
- Add # type: ignore[union-attr] for issubclass(type(mask_value), ndarray)
  guard (mypy cannot narrow on issubclass; isinstance would work but
  changing the guard is a behavior change)
- Add # type: ignore[misc] on @njit decorator (project-wide convention;
  same suppression used in shap/utils/_clustering.py)
- Annotate _jit_build_partition_tree with precise int / npt.NDArray types
- Comment out shap.maskers._image from pyproject.toml override

Only remaining mypy output is the pre-existing numba njit attr-defined
error (present in _clustering.py and _masked_model.py, both already
type-checked; disappears in CI where numba is not installed).

Closes part of shap#3730
@SarthakB11

Copy link
Copy Markdown
Contributor Author

@CloseChoice bumping this too, same #3730 series as #4445/#4760/#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