Skip to content

TYP: add type hints for explainers.tf_utils - #4445

Open
SarthakB11 wants to merge 2 commits into
shap:mainfrom
SarthakB11:typ/3730-tf-utils-type-hints
Open

SarthakB11 wants to merge 2 commits into
shap:mainfrom
SarthakB11:typ/3730-tf-utils-type-hints

Conversation

@SarthakB11

Copy link
Copy Markdown
Contributor

Part of #3730

What: Add type annotations to shap/explainers/tf_utils.py and enable
check_untyped_defs for this module.

Changes:

  • Add return and parameter type hints to _import_tf, _get_session,
    _get_graph, _get_model_inputs, _get_model_output
  • Type the module-level lazy tf global as ModuleType | None
  • Add type: ignore[union-attr] comments where the optional tf module
    is accessed after the _import_tf() guard (mypy can't infer the narrowing
    across the global assignment)
  • Remove shap.explainers.tf_utils from the mypy exclusion list in
    pyproject.toml

Verification: mypy --check-untyped-defs passes with zero errors on this
module. ruff check passes. Runtime imports verified. No TF-specific tests
affected (TF is an optional dependency).

AI Disclosure

AI tools (Claude) were used for initial investigation and annotation scaffolding.
All code was reviewed and verified manually.

…tils

Add type annotations to all functions in tf_utils.py. Use
type: ignore comments for the lazy tf module import pattern
and union-attr access on the optional tf global. Remove module
from mypy check_untyped_defs exclusion list.

Part of shap#3730

@CloseChoice CloseChoice left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR but I don't see a lot of value in here. Just ignoring all warnings and using Any does not really help, it just silences mypy to a similar point as to disable it entirely.

Therefore I would suggest to use typing.Protocol to build a protocol for model, e.g.

class TFModel(typing.Protocol):
    # define all necessary methods in here

Addresses @CloseChoice review on shap#4445: instead of using bare Any for
model parameters, define a structural protocol that captures the attributes
this module actually accesses (inputs, outputs, layers).

The tuple branch is moved before the keras-model branch so mypy can narrow
the union via isinstance(model, tuple). Behavior is preserved: tuples
never matched the keras checks before, so reordering does not change
runtime semantics.

Session and graph parameters/returns kept as Any: those values are opaque
pass-throughs in this file (no method calls on them) and TensorFlow types
are not worth a TYPE_CHECKING import for parameters that are never accessed
structurally.
@SarthakB11

Copy link
Copy Markdown
Contributor Author

Pushed a follow-up: defined a TFModel Protocol over inputs/outputs/layers and applied it to _get_model_inputs and _get_model_output.

Left _get_session and _get_graph as Any since both treat their args as opaque pass-throughs (no attribute access). Happy to extend if you'd prefer.

@SarthakB11

Copy link
Copy Markdown
Contributor Author

Rebased onto latest main. Ready for another look when you have a chance.

@SarthakB11

Copy link
Copy Markdown
Contributor Author

@CloseChoice pushed the TFModel Protocol you asked for and rebased onto latest main. CI green, ready for another look when you have a chance.

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.

2 participants