Skip to content

Commit 576692b

Browse files
committed
allow refreshing of backends
1 parent 5f766b1 commit 576692b

File tree

10 files changed

+71
-26
lines changed

10 files changed

+71
-26
lines changed

xarray/backends/cfgrib_.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
BACKEND_ENTRYPOINTS,
1010
AbstractDataStore,
1111
BackendArray,
12-
BackendEntrypoint,
12+
_InternalBackendEntrypoint,
1313
_normalize_path,
1414
)
1515
from xarray.backends.locks import SerializableLock, ensure_lock
@@ -90,7 +90,8 @@ def get_encoding(self):
9090
return {"unlimited_dims": {k for k, v in dims.items() if v is None}}
9191

9292

93-
class CfgribfBackendEntrypoint(BackendEntrypoint):
93+
class CfgribfBackendEntrypoint(_InternalBackendEntrypoint):
94+
_module_name = "cfgrib"
9495
available = module_available("cfgrib")
9596

9697
def guess_can_open(self, filename_or_obj):

xarray/backends/common.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@
1212
from xarray.conventions import cf_encoder
1313
from xarray.core import indexing
1414
from xarray.core.pycompat import is_duck_dask_array
15-
from xarray.core.utils import FrozenDict, NdimSizeLenMixin, is_remote_uri
15+
from xarray.core.utils import (
16+
FrozenDict,
17+
NdimSizeLenMixin,
18+
is_remote_uri,
19+
module_available,
20+
)
1621

1722
if TYPE_CHECKING:
1823
from io import BufferedIOBase
@@ -428,4 +433,24 @@ def guess_can_open(
428433
return False
429434

430435

431-
BACKEND_ENTRYPOINTS: dict[str, type[BackendEntrypoint]] = {}
436+
class _InternalBackendEntrypoint:
437+
"""
438+
Wrapper class for BackendEntrypoints that ship with xarray.
439+
440+
441+
Additional attributes
442+
----------
443+
444+
_module_name : str
445+
Name of the module that is required to enable the backend.
446+
"""
447+
448+
_module_name: ClassVar[str]
449+
450+
@classmethod
451+
def _set_availability(cls) -> None:
452+
"""Resets the backends availability."""
453+
cls.available = module_available(cls._module_name)
454+
455+
456+
BACKEND_ENTRYPOINTS: dict[str, type[_InternalBackendEntrypoint]] = {}

xarray/backends/h5netcdf_.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99
from xarray.backends.common import (
1010
BACKEND_ENTRYPOINTS,
11-
BackendEntrypoint,
1211
WritableCFDataStore,
12+
_InternalBackendEntrypoint,
1313
_normalize_path,
1414
find_root_and_group,
1515
)
@@ -343,7 +343,7 @@ def close(self, **kwargs):
343343
self._manager.close(**kwargs)
344344

345345

346-
class H5netcdfBackendEntrypoint(BackendEntrypoint):
346+
class H5netcdfBackendEntrypoint(_InternalBackendEntrypoint):
347347
"""
348348
Backend for netCDF files based on the h5netcdf package.
349349
@@ -365,6 +365,7 @@ class H5netcdfBackendEntrypoint(BackendEntrypoint):
365365
backends.ScipyBackendEntrypoint
366366
"""
367367

368+
_module_name = "h5netcdf"
368369
available = module_available("h5netcdf")
369370
description = (
370371
"Open netCDF (.nc, .nc4 and .cdf) and most HDF5 files using h5netcdf in Xarray"

xarray/backends/netCDF4_.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
from xarray.backends.common import (
1212
BACKEND_ENTRYPOINTS,
1313
BackendArray,
14-
BackendEntrypoint,
1514
WritableCFDataStore,
15+
_InternalBackendEntrypoint,
1616
_normalize_path,
1717
find_root_and_group,
1818
robust_getitem,
@@ -513,7 +513,7 @@ def close(self, **kwargs):
513513
self._manager.close(**kwargs)
514514

515515

516-
class NetCDF4BackendEntrypoint(BackendEntrypoint):
516+
class NetCDF4BackendEntrypoint(_InternalBackendEntrypoint):
517517
"""
518518
Backend for netCDF files based on the netCDF4 package.
519519
@@ -535,6 +535,7 @@ class NetCDF4BackendEntrypoint(BackendEntrypoint):
535535
backends.ScipyBackendEntrypoint
536536
"""
537537

538+
_module_name = "netCDF4"
538539
available = module_available("netCDF4")
539540
description = (
540541
"Open netCDF (.nc, .nc4 and .cdf) and most HDF5 files using netCDF4 in Xarray"

xarray/backends/plugins.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,21 @@
66
import sys
77
import warnings
88
from importlib.metadata import entry_points
9-
from typing import TYPE_CHECKING, Any
9+
from typing import TYPE_CHECKING, Any, Callable
1010

1111
from xarray.backends.common import BACKEND_ENTRYPOINTS, BackendEntrypoint
1212

1313
if TYPE_CHECKING:
1414
import os
15+
from importlib.metadata import EntryPoint, EntryPoints
1516
from io import BufferedIOBase
1617

1718
from xarray.backends.common import AbstractDataStore
1819

1920
STANDARD_BACKENDS_ORDER = ["netcdf4", "h5netcdf", "scipy"]
2021

2122

22-
def remove_duplicates(entrypoints):
23+
def remove_duplicates(entrypoints: EntryPoints) -> list[EntryPoint]:
2324
# sort and group entrypoints by name
2425
entrypoints = sorted(entrypoints, key=lambda ep: ep.name)
2526
entrypoints_grouped = itertools.groupby(entrypoints, key=lambda ep: ep.name)
@@ -42,7 +43,7 @@ def remove_duplicates(entrypoints):
4243
return unique_entrypoints
4344

4445

45-
def detect_parameters(open_dataset):
46+
def detect_parameters(open_dataset: Callable) -> tuple[str, ...]:
4647
signature = inspect.signature(open_dataset)
4748
parameters = signature.parameters
4849
parameters_list = []
@@ -60,7 +61,9 @@ def detect_parameters(open_dataset):
6061
return tuple(parameters_list)
6162

6263

63-
def backends_dict_from_pkg(entrypoints):
64+
def backends_dict_from_pkg(
65+
entrypoints: list[EntryPoint],
66+
) -> dict[str, BackendEntrypoint]:
6467
backend_entrypoints = {}
6568
for entrypoint in entrypoints:
6669
name = entrypoint.name
@@ -72,14 +75,16 @@ def backends_dict_from_pkg(entrypoints):
7275
return backend_entrypoints
7376

7477

75-
def set_missing_parameters(backend_entrypoints):
76-
for name, backend in backend_entrypoints.items():
78+
def set_missing_parameters(backend_entrypoints: dict[str, BackendEntrypoint]):
79+
for _, backend in backend_entrypoints.items():
7780
if backend.open_dataset_parameters is None:
7881
open_dataset = backend.open_dataset
7982
backend.open_dataset_parameters = detect_parameters(open_dataset)
8083

8184

82-
def sort_backends(backend_entrypoints):
85+
def sort_backends(
86+
backend_entrypoints: dict[str, BackendEntrypoint]
87+
) -> dict[str, BackendEntrypoint]:
8388
ordered_backends_entrypoints = {}
8489
for be_name in STANDARD_BACKENDS_ORDER:
8590
if backend_entrypoints.get(be_name, None) is not None:
@@ -90,7 +95,7 @@ def sort_backends(backend_entrypoints):
9095
return ordered_backends_entrypoints
9196

9297

93-
def build_engines(entrypoints) -> dict[str, BackendEntrypoint]:
98+
def build_engines(entrypoints: EntryPoints) -> dict[str, BackendEntrypoint]:
9499
backend_entrypoints = {}
95100
for backend_name, backend in BACKEND_ENTRYPOINTS.items():
96101
if backend.available:
@@ -126,6 +131,13 @@ def list_engines() -> dict[str, BackendEntrypoint]:
126131
return build_engines(entrypoints)
127132

128133

134+
def refresh_engines() -> None:
135+
"""Refreshes the backend engines based on installed packages."""
136+
list_engines.cache_clear()
137+
for backend_entrypoint in BACKEND_ENTRYPOINTS.values():
138+
backend_entrypoint._set_availability()
139+
140+
129141
def guess_engine(
130142
store_spec: str | os.PathLike[Any] | BufferedIOBase | AbstractDataStore,
131143
):

xarray/backends/pseudonetcdf_.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
BACKEND_ENTRYPOINTS,
77
AbstractDataStore,
88
BackendArray,
9-
BackendEntrypoint,
9+
_InternalBackendEntrypoint,
1010
_normalize_path,
1111
)
1212
from xarray.backends.file_manager import CachingFileManager
@@ -96,7 +96,7 @@ def close(self):
9696
self._manager.close()
9797

9898

99-
class PseudoNetCDFBackendEntrypoint(BackendEntrypoint):
99+
class PseudoNetCDFBackendEntrypoint(_InternalBackendEntrypoint):
100100
"""
101101
Backend for netCDF-like data formats in the air quality field
102102
based on the PseudoNetCDF package.
@@ -121,6 +121,7 @@ class PseudoNetCDFBackendEntrypoint(BackendEntrypoint):
121121
backends.PseudoNetCDFDataStore
122122
"""
123123

124+
_module_name = "PseudoNetCDF"
124125
available = module_available("PseudoNetCDF")
125126
description = (
126127
"Open many atmospheric science data formats using PseudoNetCDF in Xarray"

xarray/backends/pydap_.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
BACKEND_ENTRYPOINTS,
88
AbstractDataStore,
99
BackendArray,
10-
BackendEntrypoint,
10+
_InternalBackendEntrypoint,
1111
robust_getitem,
1212
)
1313
from xarray.backends.store import StoreBackendEntrypoint
@@ -138,7 +138,7 @@ def get_dimensions(self):
138138
return Frozen(self.ds.dimensions)
139139

140140

141-
class PydapBackendEntrypoint(BackendEntrypoint):
141+
class PydapBackendEntrypoint(_InternalBackendEntrypoint):
142142
"""
143143
Backend for steaming datasets over the internet using
144144
the Data Access Protocol, also known as DODS or OPeNDAP
@@ -154,6 +154,7 @@ class PydapBackendEntrypoint(BackendEntrypoint):
154154
backends.PydapDataStore
155155
"""
156156

157+
_module_name = "pydap"
157158
available = module_available("pydap")
158159
description = "Open remote datasets via OPeNDAP using pydap in Xarray"
159160
url = "https://docs.xarray.dev/en/stable/generated/xarray.backends.PydapBackendEntrypoint.html"

xarray/backends/pynio_.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
BACKEND_ENTRYPOINTS,
99
AbstractDataStore,
1010
BackendArray,
11-
BackendEntrypoint,
11+
_InternalBackendEntrypoint,
1212
_normalize_path,
1313
)
1414
from xarray.backends.file_manager import CachingFileManager
@@ -107,7 +107,7 @@ def close(self):
107107
self._manager.close()
108108

109109

110-
class PynioBackendEntrypoint(BackendEntrypoint):
110+
class PynioBackendEntrypoint(_InternalBackendEntrypoint):
111111
"""
112112
PyNIO backend
113113
@@ -117,6 +117,7 @@ class PynioBackendEntrypoint(BackendEntrypoint):
117117
https://github.com/pydata/xarray/issues/4491 for more information
118118
"""
119119

120+
_module_name = "Nio"
120121
available = module_available("Nio")
121122

122123
def open_dataset(

xarray/backends/scipy_.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
from xarray.backends.common import (
1010
BACKEND_ENTRYPOINTS,
1111
BackendArray,
12-
BackendEntrypoint,
1312
WritableCFDataStore,
13+
_InternalBackendEntrypoint,
1414
_normalize_path,
1515
)
1616
from xarray.backends.file_manager import CachingFileManager, DummyFileManager
@@ -240,7 +240,7 @@ def close(self):
240240
self._manager.close()
241241

242242

243-
class ScipyBackendEntrypoint(BackendEntrypoint):
243+
class ScipyBackendEntrypoint(_InternalBackendEntrypoint):
244244
"""
245245
Backend for netCDF files based on the scipy package.
246246
@@ -261,6 +261,7 @@ class ScipyBackendEntrypoint(BackendEntrypoint):
261261
backends.H5netcdfBackendEntrypoint
262262
"""
263263

264+
_module_name = "scipy"
264265
available = module_available("scipy")
265266
description = "Open netCDF files (.nc, .nc4, .cdf and .gz) using scipy in Xarray"
266267
url = "https://docs.xarray.dev/en/stable/generated/xarray.backends.ScipyBackendEntrypoint.html"

xarray/backends/zarr.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
BACKEND_ENTRYPOINTS,
1212
AbstractWritableDataStore,
1313
BackendArray,
14-
BackendEntrypoint,
1514
_encode_variable_name,
15+
_InternalBackendEntrypoint,
1616
_normalize_path,
1717
)
1818
from xarray.backends.store import StoreBackendEntrypoint
@@ -845,7 +845,7 @@ def open_zarr(
845845
return ds
846846

847847

848-
class ZarrBackendEntrypoint(BackendEntrypoint):
848+
class ZarrBackendEntrypoint(_InternalBackendEntrypoint):
849849
"""
850850
Backend for ".zarr" files based on the zarr package.
851851
@@ -857,6 +857,7 @@ class ZarrBackendEntrypoint(BackendEntrypoint):
857857
backends.ZarrStore
858858
"""
859859

860+
_module_name = "zarr"
860861
available = module_available("zarr")
861862
description = "Open zarr files (.zarr) using zarr in Xarray"
862863
url = "https://docs.xarray.dev/en/stable/generated/xarray.backends.ZarrBackendEntrypoint.html"

0 commit comments

Comments
 (0)