From 4b827af86ff4f211833af9feab4db4da12daa4ad Mon Sep 17 00:00:00 2001 From: Ryan May Date: Tue, 22 Jun 2021 15:36:03 -0600 Subject: [PATCH] ENH: Improve handling of optional Cartopy map features Use the module-level __getattr__ support in Python 3.7 to dynamically handle access to the CartoPy map features and only warn *upon use* if CartoPy isn't installed. --- src/metpy/plots/__init__.py | 21 ++++++++++++++++----- src/metpy/plots/cartopy_utils.py | 2 ++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/metpy/plots/__init__.py b/src/metpy/plots/__init__.py index 1af06cce648..3af171d215e 100644 --- a/src/metpy/plots/__init__.py +++ b/src/metpy/plots/__init__.py @@ -7,6 +7,7 @@ # Trigger matplotlib wrappers from . import _mpl # noqa: F401 +from . import cartopy_utils from ._util import (add_metpy_logo, add_timestamp, add_unidata_logo, # noqa: F401 convert_gempak_color) from .ctables import * # noqa: F403 @@ -25,10 +26,20 @@ __all__.extend(wx_symbols.__all__) # pylint: disable=undefined-variable __all__.extend(['add_metpy_logo', 'add_timestamp', 'add_unidata_logo', 'convert_gempak_color']) -try: - from .cartopy_utils import USCOUNTIES, USSTATES # noqa: F401 - __all__.extend(['USCOUNTIES', 'USSTATES']) -except ImportError: - logger.warning('Cannot import USCOUNTIES and USSTATES without Cartopy installed.') set_module(globals()) + + +def __getattr__(name): + """Handle warning if Cartopy map features are not available.""" + if name in cartopy_utils.__all__: + try: + return getattr(cartopy_utils, name) + except AttributeError: + logger.warning(f'Cannot use {name} without Cartopy installed.') + + raise AttributeError(f'module {__name__!r} has no attribute {name!r}') + + +def __dir__(): + return sorted(__all__ + cartopy_utils.__all__) diff --git a/src/metpy/plots/cartopy_utils.py b/src/metpy/plots/cartopy_utils.py index 8841f025b32..67d2b191755 100644 --- a/src/metpy/plots/cartopy_utils.py +++ b/src/metpy/plots/cartopy_utils.py @@ -56,6 +56,8 @@ def with_scale(self, new_scale): except ImportError: pass +__all__ = ['USCOUNTIES', 'USSTATES'] + def import_cartopy(): """Import CartoPy; return a stub if unable.