Fix: fix: handle None module in module_available() to avoid TypeError
Fixed pydata/xarray#11344 — 5 line bug-fix adding explicit None guard to module_available().
The Bug
Repo: pydata/xarray Issue: #11344 Status: PR-submitted PR: https://github.com/pydata/xarray/pull/11448
Description: When module_available() is called with None — for example, through a third-party plugin import chain — importlib.util.find_spec(None) raises TypeError instead of gracefully returning False.
Fix scope: 5 lines changed in xarray/namedarray/utils.py
Root Cause
The module_available() function uses importlib.util.find_spec() to check whether a Python module is installed. The function signature previously required module: str, meaning callers should always pass a string. However, in practice, some third-party code paths could pass None — for example, when a plugin’s configuration uses optional dependencies that might not resolve during import.
When importlib.util.find_spec(None) is called, it raises TypeError: the 'package' argument is required to perform a relative import for ''. The error message is confusing because the term “None” is never mentioned, making it hard to trace back to the null input.
Impact: Low for end users, but disruptive for plugin authors and developers integrating xarray with dynamic import systems. Any third-party extension that calls module_available() with an optional module reference (which could be None when a configuration is incomplete) would crash with a TypeError instead of gracefully degrading. The fix ensures module_available(None) returns False, matching the intuitive expectation: if no module is provided, it’s not available.
The Fix
Two changes in xarray/namedarray/utils.py:
- Type hint update:
module: str→module: str | Noneto reflect the accepted input types. - Early return guard: Added a
Nonecheck at the top of the function body that returnsFalse.
if module is None:
return False
This tiny guard (5 lines with the type hint change) prevents the confusing TypeError from propagating and matches how similar functions in the Python ecosystem handle null input — for example, many find_spec() wrappers in other projects use this exact pattern.
Pattern & Takeaways
Pattern: Functions that delegate to stdlib functions with strict type expectations (find_spec requires str) should guard against None input when there’s any possibility it could arrive through user-facing or plugin-facing APIs. The guard is cheap (one comparison) and prevents an opaque TypeError from masking the real issue.
Key insight: Type hints don’t enforce runtime behavior. Even with module: str, callers can pass None. The safest approach is to add an explicit guard at API boundaries, especially for utility functions that may be called from dynamic or plugin-based code paths. The cost of a single if module is None: return False is negligible, but it saves debugging time.
Transfer Potential
High — module_available()-style functions exist in every Python project that does optional dependency checking. The pattern of guarding None for functions wrapping importlib.util.find_spec() is directly applicable anywhere a module name string could be None at runtime.
Auto-generated from PR #11448. View all patches on GitHub.
References
[1] pydata/xarray [2] #11344 [3] https://github.com/pydata/xarray/pull/11448