283 fix(discovery): don't crash when an optional dependency (e.g. matplotlib) is missing - #293
283 fix(discovery): don't crash when an optional dependency (e.g. matplotlib) is missing#293Gnpd wants to merge 5 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR hardens chemotools.utils.discovery so all_estimators(), all_displays(), and all_functions() no longer crash when importing a subpackage fails due to a missing optional dependency (e.g. matplotlib for viz), and instead skip the failing module with a warning.
Changes:
- Add
_iter_chemotools_modules()to centralize module iteration and handle per-moduleImportErrorby warning and skipping. - Update
all_estimators(),all_displays(), andall_functions()to use the shared iterator. - Add a regression test ensuring discovery warns and still returns a list when
chemotools.plotting/chemotools.inspectorcan’t be imported.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
chemotools/utils/discovery.py |
Introduces a shared module iterator that catches ImportError during discovery and updates all discovery entrypoints to use it. |
tests/utils/test_discovery.py |
Adds a regression test that simulates an ImportError from optional-dependency-gated subpackages and asserts discovery warns instead of crashing. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| except ImportError as exc: | ||
| warnings.warn( | ||
| f"Skipping '{module_name}' during discovery: {exc}", | ||
| stacklevel=3, |
There was a problem hiding this comment.
stacklevel=3 is already correct
Tested directly, by calling all_estimators() from a notebook cell with a submodule forced to fail import:
stacklevel=3 (current):
...ipykernel_15920\875199054.py:21: Skipping 'chemotools.plotting' during discovery: ...
→ line 21 is the exact cell line that called all_estimators(). Correct.
stacklevel=4 (proposed):
...IPython\core\interactiveshell.py:3546: Skipping 'chemotools.plotting' during discovery: ...
→ overshoots past the caller entirely, into IPython's own cell-execution internals.
So stacklevel=4 is strictly worse, not a fix. Keeping stacklevel=3 as-is.
Summary
all_estimators(),all_displays(), andall_functions()crashed with an uncaughtImportErrorwhenever matplotlib (thevizextra) wasn't installed, sincechemotools.plotting/chemotools.inspectorfail to import without it and discovery had no handling for that.This is a fast fix for the immediate crash, but it's also worth keeping as a general safeguard: any future subpackage with an optional dependency will now degrade gracefully instead of breaking discovery for everyone.
Fixes #283.
Changes
_iter_chemotools_modules()generator (used by all three public functions) that catchesImportErrorper submodule and emits aUserWarningnaming the skipped module instead of propagating, a permanent safeguard, not just a one-off patch, so any future optional-dependency-gated subpackage degrades gracefully instead of crashing discovery.stacklevel=3so it's attributed to the caller's own call site (e.g. theirall_estimators()call) rather than to internal discovery-loop plumbing.test_discovery_skips_module_with_missing_optional_dependency) that fakes anImportErrorfromchemotools.plotting/chemotools.inspectorto simulate matplotlib being absent, and asserts each discovery function still returns a list and warns instead of crashing.