Import an optional dependency, and raise an informative error on failure. Parameters ---------- module : str Module to import. For example, ``'zarr'`` or ``'matplotlib.pyplot'``. Returns ------- module : ModuleType The Imported module. Raises ------
(module: str)
| 1332 | |
| 1333 | |
| 1334 | def attempt_import(module: str) -> ModuleType: |
| 1335 | """Import an optional dependency, and raise an informative error on failure. |
| 1336 | |
| 1337 | Parameters |
| 1338 | ---------- |
| 1339 | module : str |
| 1340 | Module to import. For example, ``'zarr'`` or ``'matplotlib.pyplot'``. |
| 1341 | |
| 1342 | Returns |
| 1343 | ------- |
| 1344 | module : ModuleType |
| 1345 | The Imported module. |
| 1346 | |
| 1347 | Raises |
| 1348 | ------ |
| 1349 | ImportError |
| 1350 | If the module could not be imported. |
| 1351 | |
| 1352 | Notes |
| 1353 | ----- |
| 1354 | Static type checkers will not be able to infer the type of the returned module, |
| 1355 | so it is recommended to precede this function with a direct import of the module, |
| 1356 | guarded by an ``if TYPE_CHECKING`` block, to preserve type checker functionality. |
| 1357 | See the examples section below for a demonstration. |
| 1358 | |
| 1359 | Examples |
| 1360 | -------- |
| 1361 | >>> from xarray.core.utils import attempt_import |
| 1362 | >>> if TYPE_CHECKING: |
| 1363 | ... import zarr |
| 1364 | ... else: |
| 1365 | ... zarr = attempt_import("zarr") |
| 1366 | ... |
| 1367 | """ |
| 1368 | install_mapping = dict(nc_time_axis="nc-time-axis") |
| 1369 | package_purpose = dict( |
| 1370 | zarr="for working with Zarr stores", |
| 1371 | cftime="for working with non-standard calendars", |
| 1372 | matplotlib="for plotting", |
| 1373 | hypothesis="for the `xarray.testing.strategies` submodule", |
| 1374 | ) |
| 1375 | package_name = module.split(".", maxsplit=1)[0] # e.g. "zarr" from "zarr.storage" |
| 1376 | install_name = install_mapping.get(package_name, package_name) |
| 1377 | reason = package_purpose.get(package_name, "") |
| 1378 | try: |
| 1379 | return importlib.import_module(module) |
| 1380 | except ImportError as e: |
| 1381 | raise ImportError( |
| 1382 | f"The {install_name} package is required {reason}" |
| 1383 | " but could not be imported." |
| 1384 | " Please install it with your package manager (e.g. conda or pip)." |
| 1385 | ) from e |
| 1386 | |
| 1387 | |
| 1388 | _DEFAULT_NAME = ReprObject("<default-name>") |
searching dependent graphs…