Skip to content

ENH: Declare SciPy and scikit-learn as a tract_math extra - #146

Open
demianw wants to merge 1 commit into
masterfrom
tract-math-optional-deps
Open

demianw wants to merge 1 commit into
masterfrom
tract-math-optional-deps

Conversation

@demianw

@demianw demianw commented Nov 4, 2026

Copy link
Copy Markdown
Owner

What was wrong

Some tract_math operations import packages that are not declared anywhere: SciPy (scipy.ndimage in tract_map_image, tract_deform, tract_generate_population_probability_map; scipy.interpolate in tract_prototype_mean) and scikit-learn (sklearn.neighbors.BallTree in tract_smooth). Without them, users get a bare ModuleNotFoundError: No module named 'scipy' at run time.

The change

  • pyproject.toml: new optional extra tract_math = ["scipy", "scikit-learn"] (4 added lines, nothing else changed).
  • operations.py: a small _import_optional(module_name) helper (not a registered operation) used by the four operations above; when the module is missing it raises ImportError: This operation needs scipy: install it, or install tract_querier with the tract_math extra, e.g. pip install '.[tract_math]' from the source tree (chained to the original error). tract_prototype_mean keeps its existing behaviour (warns and skips the smoothing without SciPy); only its warning now names the extra.
  • doc/installation_instructions.rst: one sentence after the requirements list.

The message suggests pip install '.[tract_math]' rather than tract_querier[tract_math] because the package is not on PyPI (the docs install from GitHub or a source tree).

tensor_operations.tract_expand_tensor_metrics also imports SciPy, but it is dead code (undefined name, no callers) and is removed in the #107 PR, so it is left alone here. tract_label_indices.py imports SciPy too, outside tract_math (handled by #135).

Testing

  • New parametrized test_tract_math_missing_optional_dependency: hides scipy/sklearn via sys.modules and checks that tract_map_image, tract_deform and tract_smooth raise an ImportError naming the tract_math extra. Passes here.
  • python -m pytest -q -p no:cacheprovider tract_querier: 45 passed, 1 skipped (pre-existing unconditional skip).
  • I did not build the docs for this one-sentence change.

Maintainer decision: CI installs .[test] only, so SciPy-dependent tests (e.g. those in #143, which use pytest.importorskip) are skipped there; installing .[test,tract_math] in .github/workflows/test_package.yaml would run them. Not changed here.

Merge order

pyproject.toml is also edited by #98 (moves VTK to an optional extra in the same [project.optional-dependencies] table, so it will conflict textually next to this one), #120 and #121 (other tables; probably merge cleanly). doc/installation_instructions.rst is also edited by #98 (requirements list, adjacent lines). operations.py is also edited by #143 and #145 (different lines).

Closes #112

🤖 Generated with Claude Code

Some tract_math operations import SciPy (ndimage, interpolate) or
scikit-learn (BallTree), which were not declared anywhere, so users
only found out from a bare ImportError. Declare them as the optional
`tract_math` extra and make those operations raise an ImportError
naming the extra when the package is missing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

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.

ENH: declare the optional dependencies of tract_math

1 participant