From 414008bb0796632f412293334447c0e0e51771bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 19 Feb 2024 12:41:32 +0100 Subject: [PATCH 1/5] Lazy load iris.cube --- geoviews/element/geo.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/geoviews/element/geo.py b/geoviews/element/geo.py index eb00ff71..24d1b9ae 100644 --- a/geoviews/element/geo.py +++ b/geoviews/element/geo.py @@ -26,13 +26,16 @@ ) from shapely.ops import unary_union -try: - from iris.cube import Cube -except (ImportError, OSError): - # OSError because environment variable $UDUNITS2_XML_PATH - # is sometimes not set. Should be done automatically - # when installing the package. - Cube = None +def _get_iris_cube(): + try: + from iris.cube import Cube + except (ImportError, OSError): + # OSError because environment variable $UDUNITS2_XML_PATH + # is sometimes not set. Should be done automatically + # when installing the package. + Cube = None + return Cube + try: from owslib.wmts import WebMapTileService @@ -99,7 +102,7 @@ def __init__(self, data, kdims=None, vdims=None, **kwargs): crs_data = data.data else: crs_data = data - if Cube and isinstance(crs_data, Cube): + if hasattr(crs_data, 'coord_system') and _get_iris_cube() and isinstance(crs_data, _get_iris_cube()): coord_sys = crs_data.coord_system() if hasattr(coord_sys, 'as_cartopy_projection'): crs = coord_sys.as_cartopy_projection() From 911b6a5b1506a1d6b6dea84152e6f1909cf56914 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 19 Feb 2024 13:00:43 +0100 Subject: [PATCH 2/5] Lazy load project and annotate --- geoviews/__init__.py | 17 ++++++++++++++--- geoviews/tests/test_operation.py | 2 ++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/geoviews/__init__.py b/geoviews/__init__.py index 01d11226..363ab5fb 100644 --- a/geoviews/__init__.py +++ b/geoviews/__init__.py @@ -6,7 +6,6 @@ from holoviews import render, save # noqa (API import) -from .annotators import annotate # noqa (API import) from .element import ( # noqa (API import) _Element, Feature, Tiles, WMTS, LineContours, FilledContours, Text, Image, ImageStack, Points, Path, Polygons, Shape, Dataset, RGB, @@ -14,10 +13,8 @@ HexTiles, Labels, Rectangles, Segments, WindBarbs ) from .util import load_tiff, from_xarray # noqa (API import) -from .operation import project # noqa (API import) from ._warnings import GeoviewsDeprecationWarning, GeoviewsUserWarning # noqa: F401 from . import data # noqa (API import) -from . import operation # noqa (API import) from . import plotting # noqa (API import) from . import feature # noqa (API import) from . import tile_sources # noqa (API import) @@ -42,3 +39,17 @@ def _missing_cmd(*args,**kw): return("install pyct to enable this command (e.g. def _err(): raise ValueError(_missing_cmd()) fetch_data = copy_examples = examples = _err del partial, _examples, _copy, _fetch + + +def __getattr__(attr): + # Lazy loading heavy modules + if attr == 'annotate': + from .annotators import annotate + return annotate + elif attr == 'project': + from .operation import project + return project + elif attr == 'operation': + from . import operation + return operation + raise AttributeError(f"module {__name__} has no attribute {attr!r}") diff --git a/geoviews/tests/test_operation.py b/geoviews/tests/test_operation.py index 9558c1df..1a095c73 100644 --- a/geoviews/tests/test_operation.py +++ b/geoviews/tests/test_operation.py @@ -9,6 +9,8 @@ "ignore:numpy.ndarray size changed, may indicate binary incompatibility" # https://github.com/pydata/xarray/issues/7259 ) def test_quadmesh_contoures_filled(): + gv.extension("bokeh") + # Regression test for: https://github.com/holoviz/holoviews/pull/5925 ds = xr.tutorial.open_dataset("air_temperature").isel(time=0) p1 = gv.QuadMesh(ds, kdims=["lon", "lat"]) From 6b5263d182a854910dc3bdfa1eb0c61cedfb5665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 19 Feb 2024 13:01:04 +0100 Subject: [PATCH 3/5] Add import test --- geoviews/tests/test_import.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 geoviews/tests/test_import.py diff --git a/geoviews/tests/test_import.py b/geoviews/tests/test_import.py new file mode 100644 index 00000000..66750249 --- /dev/null +++ b/geoviews/tests/test_import.py @@ -0,0 +1,20 @@ +import sys +from subprocess import check_output +from textwrap import dedent + + +def test_no_blocklist_imports(): + check = """\ + import sys + import geoviews as gv + + blocklist = {"panel", "IPython", "datashader", "iris", "dask"} + mods = blocklist & set(sys.modules) + + if mods: + print(", ".join(mods), end="") + """ + + output = check_output([sys.executable, '-c', dedent(check)]) + + assert output == b"" From 12ca97ca82ccce81d985ea3b1d1a7ba343133021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 19 Feb 2024 13:13:59 +0100 Subject: [PATCH 4/5] Initalize gv.extension in conftest.py --- geoviews/tests/conftest.py | 9 +++++++++ geoviews/tests/test_operation.py | 2 -- 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 geoviews/tests/conftest.py diff --git a/geoviews/tests/conftest.py b/geoviews/tests/conftest.py new file mode 100644 index 00000000..715839c6 --- /dev/null +++ b/geoviews/tests/conftest.py @@ -0,0 +1,9 @@ +from contextlib import suppress + +import geoviews as gv + +with suppress(Exception): + gv.extension("bokeh") + +with suppress(Exception): + gv.extension("matplotlib") diff --git a/geoviews/tests/test_operation.py b/geoviews/tests/test_operation.py index 1a095c73..9558c1df 100644 --- a/geoviews/tests/test_operation.py +++ b/geoviews/tests/test_operation.py @@ -9,8 +9,6 @@ "ignore:numpy.ndarray size changed, may indicate binary incompatibility" # https://github.com/pydata/xarray/issues/7259 ) def test_quadmesh_contoures_filled(): - gv.extension("bokeh") - # Regression test for: https://github.com/holoviz/holoviews/pull/5925 ds = xr.tutorial.open_dataset("air_temperature").isel(time=0) p1 = gv.QuadMesh(ds, kdims=["lon", "lat"]) From 84cd75d5bc860364f0066920a47cd30959dcd836 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro=20Hansen?= Date: Mon, 19 Feb 2024 20:45:16 +0100 Subject: [PATCH 5/5] Add autocomplete in IPython and import if type hinting --- geoviews/__init__.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/geoviews/__init__.py b/geoviews/__init__.py index 363ab5fb..3f6960cb 100644 --- a/geoviews/__init__.py +++ b/geoviews/__init__.py @@ -53,3 +53,16 @@ def __getattr__(attr): from . import operation return operation raise AttributeError(f"module {__name__} has no attribute {attr!r}") + +__all__ = [k for k in locals() if not k.startswith('_')] +__all__ += ['annotate', 'project', 'operation'] + +def __dir__(): + return __all__ + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from .annotators import annotate + from .operation import project + from . import operation