Files
shap--shap/pyproject.toml
T
2026-07-13 13:22:52 +08:00

366 lines
11 KiB
TOML

[build-system]
# Note for maintainers: this numpy constraint is specific to wheels for PyPI. See:
# https://numpy.org/doc/stable/dev/depending_on_numpy.html#numpy-2-abi-handling
requires = [
"scikit-build-core>=0.10.0",
"setuptools-scm>=8.0",
"numpy>=2.0",
"packaging>20.9",
"nanobind>=2.0.0",
]
build-backend = "scikit_build_core.build"
[project]
name = "shap"
description = "A unified approach to explain the output of any machine learning model."
readme = "README.md"
license = {text = "MIT License"}
authors = [
{name = "Scott Lundberg", email = "slund1@cs.washington.edu"},
]
requires-python = ">=3.12"
dependencies = [
'numpy>=2',
'scipy',
'scikit-learn',
'pandas',
'tqdm>=4.27.0',
'packaging>20.9',
'slicer==0.0.8',
'numba<0.63; sys_platform == "darwin" and platform_machine == "x86_64"', # numba 0.63+ dropped macOS x86_64 wheels, see numba/numba#10187
'numba; sys_platform != "darwin" or platform_machine != "x86_64"',
'llvmlite<0.46; sys_platform == "darwin" and platform_machine == "x86_64"', # llvmlite 0.46+ dropped macOS x86_64 wheels, see numba/numba#10187
'llvmlite; sys_platform != "darwin" or platform_machine != "x86_64"',
'cloudpickle',
]
classifiers = [
"Operating System :: Microsoft :: Windows",
"Operating System :: POSIX",
"Operating System :: Unix",
"Operating System :: MacOS",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Intended Audience :: Information Technology",
"Intended Audience :: Science/Research",
"Topic :: Scientific/Engineering",
"Topic :: Scientific/Engineering :: Artificial Intelligence",
"Development Status :: 5 - Production/Stable",
"License :: OSI Approved :: MIT License",
]
dynamic = ["version"]
[dependency-groups]
plots = ["matplotlib", "ipython"]
download-datasets = [
# Dependencies needed to download datasets for testing
# scikit-learn is already in core dependencies, but listed here for clarity
"scikit-learn",
]
docs = [
{include-group = "plots"},
"numpydoc",
"sphinx_rtd_theme",
"sphinx",
"nbsphinx",
"sphinx_github_changelog",
"myst-parser",
"requests",
"ipywidgets", # For tqdm in notebooks
]
test-core = [
"pytest",
"pytest-mpl",
"pytest-cov",
"mypy",
"pre-commit",
"ruff",
]
test = [
{include-group = "test-core"},
"xgboost",
"lightgbm",
'catboost; python_version < "3.14"', # TODO: pending 3.14 support
'gpboost==1.6.3.1; python_version < "3.14"', # TODO: pending 3.14 support, see GH #4210
"ngboost",
"pyspark",
"pyod",
"transformers < 4.54.0", # TODO: fix once tests pass for 4.54.0
"tf-keras",
"protobuf", # See GH #3046
'torch<=2.11.0; python_version < "3.14"', # TODO: pending 3.14 support, see GH #5016
'torchvision; python_version < "3.14"', # TODO: pending 3.14 support
'tensorflow; python_version < "3.14"', # TODO: pending 3.14 support
"sentencepiece",
"opencv-python",
# Constraint to prevent the combination of tf<2.15 and numpy>=2.0.
# See GH #3707, #3768, 3922
"numpy>=2.0",
"causalml>=0.15.5",
# causalml imports private sklearn.ensemble._forest internals (DOUBLE, DTYPE, MAX_INT)
# that were removed in scikit-learn 1.9. See https://github.com/uber/causalml/issues/926
"scikit-learn<1.9",
"selenium", # needed to test the javascript based plots
]
nbtest = [
"jupyter",
"nbconvert",
"nbformat",
"nlp",
"transformers",
"datasets",
"keras",
"nbtest-plugin",
"nbtest-gen",
"nbtest-lab-extension"
]
[project.urls]
Repository = 'http://github.com/shap/shap'
Documentation = 'https://shap.readthedocs.io/en/latest/index.html'
"Release Notes" = 'https://shap.readthedocs.io/en/latest/release_notes.html'
[tool.uv]
cache-keys = [
{ file = "shap/cext/*.cc" },
{ file = "shap/cext/*.cu" },
{ file = "shap/cext/*.h" },
{ file = "shap/cutils/*.cpp" },
{ file = "shap/cutils/*.h" },
{ file = "CMakeLists.txt" },
]
[tool.mypy]
check_untyped_defs = true
disallow_untyped_calls = false
disallow_untyped_defs = false
disallow_incomplete_defs = false
exclude = ["shap/benchmark/*", "tests/benchmark/*", "shap/_cutils.pyi"]
# NOTE: numpy.typing.mypy_plugin is deprecated in NumPy 2.3+ and will be removed in a future release
# plugins = ["numpy.typing.mypy_plugin"]
[[tool.mypy.overrides]]
# Disable some checks from certain shap modules
# TODO: get these passing!
# NOTE: Modules with added type hints have been removed from this list
module = [
# "shap.explainers._additive", # NOW TYPE CHECKED - type hints added
"shap.explainers._deep.deep_pytorch",
"shap.explainers._deep.deep_tf",
# "shap.explainers._exact", # NOW TYPE CHECKED - type hints added
# "shap.explainers._explainer", # NOW TYPE CHECKED - type hints added
# "shap.explainers._gradient", # NOW TYPE CHECKED - type hints added
# "shap.explainers._kernel", # NOW TYPE CHECKED - type hints added
# "shap.explainers._linear", # NOW TYPE CHECKED - type hints added
# "shap.explainers._partition", # NOW TYPE CHECKED - type hints added
# "shap.explainers._permutation", # NOW TYPE CHECKED - type hints added
# "shap.explainers._sampling", # NOW TYPE CHECKED - type hints added
# "shap.explainers._tree", # NOW TYPE CHECKED - type hints added
# "shap.explainers._coalition", # NOW TYPE CHECKED - type hints added
# "shap.explainers.other._random", # NOW TYPE CHECKED - type hints added
"shap.explainers.pytree",
"shap.explainers.tf_utils",
# "shap.maskers._composite", # NOW TYPE CHECKED - type hints added
# "shap.maskers._fixed", # NOW TYPE CHECKED - type hints added
"shap.maskers._image",
# "shap.maskers._masker", # NOW TYPE CHECKED - type hints added
"shap.maskers._tabular",
"shap.maskers._text",
"shap.plots._benchmark",
"shap.plots._force_matplotlib",
"shap.plots._force",
"shap.plots._text",
"shap.plots._waterfall",
]
check_untyped_defs = false
[[tool.mypy.overrides]]
# Ignore missing types for 3rd party libraries
module = [
"catboost.*",
"cloudpickle",
"cv2",
"IPython.*",
"lightgbm.*",
"lime.*",
"numba",
"pandas",
"pyod.*",
"pyspark.*",
"scipy.*",
"sklearn.*",
"slicer",
"tensorflow.*",
"transformers.*",
"torch.*",
"tqdm.*",
"xgboost.*",
"causalml.*",
"selenium.*",
]
ignore_missing_imports = true
[tool.setuptools_scm]
version_file = "shap/_version.py"
# Use "no-local-version" so dev releases are compatibile with PyPI
local_scheme = "no-local-version"
[tool.scikit-build]
# List of packages to include in the wheel
wheel.packages = [
'shap',
'shap.cext',
'shap.explainers',
'shap.explainers.other',
'shap.explainers._deep',
'shap.plots',
'shap.plots.colors',
'shap.plots.resources',
'shap.benchmark',
'shap.maskers',
'shap.utils',
'shap.actions',
'shap.models',
]
metadata.version.provider = "scikit_build_core.metadata.setuptools_scm"
sdist.include = ["shap/_version.py"]
sdist.exclude = ["docs/", "notebooks/", ".claude/", "appveyor/"]
# Protect the configuration against future changes in scikit-build-core
minimum-version = "build-system.requires"
# Setuptools-style build caching in a local directory
build-dir = "build/{wheel_tag}"
# Exclude C/C++/CUDA source files from the wheel (compiled .so is sufficient)
wheel.exclude = ["**/*.cc", "**/*.cpp", "**/*.h", "**/*.cu"]
# Build stable ABI wheels for CPython 3.12+
wheel.py-api = "cp312"
[tool.pytest.ini_options]
addopts = "--mpl -m 'not xslow'"
mpl-default-style = "default"
testpaths = ["tests"]
filterwarnings = [
# Ignore warnings that are entirely from 3rd party libs outside our control
"ignore:.*distutils Version classes are deprecated.*:DeprecationWarning:.*pandas.*",
"ignore:.*typing.io is deprecated.*:DeprecationWarning:.*pyspark.*",
"ignore:.*is_datetime64tz_dtype is deprecated.*:DeprecationWarning:.*pyspark.*",
"ignore:.*'force_all_finite' was renamed to 'ensure_all_finite' in 1.6.*:FutureWarning:.*sklearn.*",
]
markers = ["xslow: mark test as extremely slow (not run unless explicitly requested)"]
[tool.ruff]
# Careful: when running on pre-commit, ruff's "include" and "exclude" config
# options are ignored! So, instead of "exclude", use the "per-file-ignores"
# config to always disable linting for specific files.
include = ["*.py", "*.pyi", "**/pyproject.toml", "*.ipynb"]
extend-exclude = ["**/tree_shap_paper/**", "docs/user_studies/*"]
line-length = 120
[tool.ruff.lint]
select = [
"F", # pyflakes
"I", # isort
"ISC", # string literal concatenation.
"UP", # pyupgrade
"E", # pycodestyle
"W", # warning
"D", # pydocstyle
"NPY", # Numpy
"SIM101", # flake8-simplify
"FA", # future annotations
"TCH", # Move type only imports to type-checking condition.
# D417 # undocumented parameter. FIXME: get this passing
]
ignore = [
# Recommended rules to disable when using ruff formatter:
# https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules
"D206",
"D300",
"E111",
"E114",
"E117",
"E501",
"W191",
# pydocstyle issues not yet fixed
"D100", # Missing docstring in public module
"D101", # Missing docstring in public class
"D102", # Missing docstring in public method
"D103", # Missing docstring in public function
"D104", # Missing docstring in public package
"D105", # Missing docstring in magic method
"D205", # 1 blank line required between summary line and description
"D400", # First line should end with a period
"D401", # First line of docstring should be in imperative mood: "A basic partial dependence plot function."
"D404", # First word of the docstring should not be "This"
"NPY002", # Allow numpy RandomState objects in tests
]
[tool.ruff.lint.pydocstyle]
convention = "numpy"
[tool.ruff.lint.per-file-ignores]
# Don't apply linting/formatting to vendored code
"shap/explainers/other/_maple.py" = ["ALL"]
# Ignore notebooks in user_studies, which are not maintained
"docs/user_studies/*.ipynb" = ["ALL"]
# Ignore SHAP Paper, as it is an unmaintained record of a published paper
"notebooks/tabular_examples/tree_based_models/tree_shap_paper/*" = ["ALL"]
# Disable some unwanted rules on Jupyter notebooks
"*.ipynb" = ["D", "E703", "E402"] # Allow trailing semicolons, allow imports not at top
# Ignore pycodestyle in tests
"tests/*py" = ["D"]
[tool.coverage.run]
source_pkgs = ["shap"]
omit = ["shap/benchmark/*"]
[tool.coverage.paths]
combine = ["shap", "*/site-packages/shap"]
[tool.cibuildwheel]
# TODO: Should we use uv as build frontend for faster builds?
# build-frontend = "uv"
# Restrict the set of builds to mirror the wheels available in scipy. See #3028
# skip cp314-macosx_x86_64 due to lack of numba and llvmlite support
# skip *t (free-threaded builds) since dependencies like llvmlite don't support it yet
skip = [
"cp314-macosx_x86_64",
"cp314t-manylinux_x86_64",
"cp314t-macosx_x86_64",
"cp314t-win_amd64",
]
build-verbosity = 2
# Change import-mode to ensure we test against installed package, not local project
test-command = "pytest -v {project}/tests --import-mode=append"
test-groups = ["test-core", "plots"]
# skip tests on *-musllinux*" since llvmlite and numba do not provide musllinux wheels
test-skip = "*-musllinux*"
[tool.cibuildwheel.linux]
archs = ["x86_64", "aarch64"]
[tool.cibuildwheel.windows]
# TODO: Should we support Windows ARM64 too?
archs = ["AMD64"]
[tool.cibuildwheel.macos]
# TODO: Should we build universal2 wheels for macOS to reduce wheel count?
archs = ["x86_64", "arm64"]
[tool.cibuildwheel.macos.environment]
# Needed for C++17 support
MACOSX_DEPLOYMENT_TARGET = "10.13"