1
1
import os .path
2
2
import warnings
3
- from collections .abc import MutableMapping
4
3
from glob import glob
5
4
from io import BytesIO
6
5
from numbers import Number
41
40
DATAARRAY_NAME = "__xarray_dataarray_name__"
42
41
DATAARRAY_VARIABLE = "__xarray_dataarray_variable__"
43
42
43
+ ENGINES = {
44
+ "netcdf4" : backends .NetCDF4DataStore .open ,
45
+ "scipy" : backends .ScipyDataStore ,
46
+ "pydap" : backends .PydapDataStore .open ,
47
+ "h5netcdf" : backends .H5NetCDFStore .open ,
48
+ "pynio" : backends .NioDataStore ,
49
+ "pseudonetcdf" : backends .PseudoNetCDFDataStore .open ,
50
+ "cfgrib" : backends .CfGribDataStore ,
51
+ "zarr" : backends .ZarrStore .open_group ,
52
+ }
53
+
44
54
45
55
def _get_default_engine_remote_uri ():
46
56
try :
@@ -153,6 +163,17 @@ def _get_default_engine(path, allow_remote=False):
153
163
return engine
154
164
155
165
166
+ def _get_backend_cls (engine ):
167
+ """Select open_dataset method based on current engine"""
168
+ try :
169
+ return ENGINES [engine ]
170
+ except KeyError :
171
+ raise ValueError (
172
+ "unrecognized engine for open_dataset: {}\n "
173
+ "must be one of: {}" .format (engine , list (ENGINES ))
174
+ )
175
+
176
+
156
177
def _normalize_path (path ):
157
178
if is_remote_uri (path ):
158
179
return path
@@ -407,23 +428,6 @@ def open_dataset(
407
428
--------
408
429
open_mfdataset
409
430
"""
410
- engines = [
411
- None ,
412
- "netcdf4" ,
413
- "scipy" ,
414
- "pydap" ,
415
- "h5netcdf" ,
416
- "pynio" ,
417
- "cfgrib" ,
418
- "pseudonetcdf" ,
419
- "zarr" ,
420
- ]
421
- if engine not in engines :
422
- raise ValueError (
423
- "unrecognized engine for open_dataset: {}\n "
424
- "must be one of: {}" .format (engine , engines )
425
- )
426
-
427
431
if autoclose is not None :
428
432
warnings .warn (
429
433
"The autoclose argument is no longer used by "
@@ -450,6 +454,7 @@ def open_dataset(
450
454
451
455
if backend_kwargs is None :
452
456
backend_kwargs = {}
457
+ extra_kwargs = {}
453
458
454
459
def maybe_decode_store (store , chunks , lock = False ):
455
460
ds = conventions .decode_cf (
@@ -532,68 +537,35 @@ def maybe_decode_store(store, chunks, lock=False):
532
537
533
538
if isinstance (filename_or_obj , AbstractDataStore ):
534
539
store = filename_or_obj
540
+ else :
541
+ if isinstance (filename_or_obj , str ):
542
+ filename_or_obj = _normalize_path (filename_or_obj )
535
543
536
- elif isinstance (filename_or_obj , MutableMapping ) and engine == "zarr" :
537
- # Zarr supports a wide range of access modes, but for now xarray either
538
- # reads or writes from a store, never both.
539
- # For open_dataset(engine="zarr"), we only read (i.e. mode="r")
540
- mode = "r"
541
- _backend_kwargs = backend_kwargs .copy ()
542
- overwrite_encoded_chunks = _backend_kwargs .pop ("overwrite_encoded_chunks" , None )
543
- store = backends .ZarrStore .open_group (
544
- filename_or_obj , mode = mode , group = group , ** _backend_kwargs
545
- )
546
-
547
- elif isinstance (filename_or_obj , str ):
548
- filename_or_obj = _normalize_path (filename_or_obj )
544
+ if engine is None :
545
+ engine = _get_default_engine (filename_or_obj , allow_remote = True )
546
+ elif engine != "zarr" :
547
+ if engine not in [None , "scipy" , "h5netcdf" ]:
548
+ raise ValueError (
549
+ "can only read bytes or file-like objects "
550
+ "with engine='scipy' or 'h5netcdf'"
551
+ )
552
+ engine = _get_engine_from_magic_number (filename_or_obj )
549
553
550
- if engine is None :
551
- engine = _get_default_engine (filename_or_obj , allow_remote = True )
552
- if engine == "netcdf4" :
553
- store = backends .NetCDF4DataStore .open (
554
- filename_or_obj , group = group , lock = lock , ** backend_kwargs
555
- )
556
- elif engine == "scipy" :
557
- store = backends .ScipyDataStore (filename_or_obj , ** backend_kwargs )
558
- elif engine == "pydap" :
559
- store = backends .PydapDataStore .open (filename_or_obj , ** backend_kwargs )
560
- elif engine == "h5netcdf" :
561
- store = backends .H5NetCDFStore .open (
562
- filename_or_obj , group = group , lock = lock , ** backend_kwargs
563
- )
564
- elif engine == "pynio" :
565
- store = backends .NioDataStore (filename_or_obj , lock = lock , ** backend_kwargs )
566
- elif engine == "pseudonetcdf" :
567
- store = backends .PseudoNetCDFDataStore .open (
568
- filename_or_obj , lock = lock , ** backend_kwargs
569
- )
570
- elif engine == "cfgrib" :
571
- store = backends .CfGribDataStore (
572
- filename_or_obj , lock = lock , ** backend_kwargs
573
- )
554
+ if engine in ["netcdf4" , "h5netcdf" ]:
555
+ extra_kwargs ["group" ] = group
556
+ extra_kwargs ["lock" ] = lock
557
+ elif engine in ["pynio" , "pseudonetcdf" , "cfgrib" ]:
558
+ extra_kwargs ["lock" ] = lock
574
559
elif engine == "zarr" :
575
- # on ZarrStore, mode='r', synchronizer=None, group=None,
576
- # consolidated=False.
577
- _backend_kwargs = backend_kwargs .copy ()
578
- overwrite_encoded_chunks = _backend_kwargs .pop (
560
+ backend_kwargs = backend_kwargs .copy ()
561
+ overwrite_encoded_chunks = backend_kwargs .pop (
579
562
"overwrite_encoded_chunks" , None
580
563
)
581
- store = backends .ZarrStore .open_group (
582
- filename_or_obj , group = group , ** _backend_kwargs
583
- )
584
- else :
585
- if engine not in [None , "scipy" , "h5netcdf" ]:
586
- raise ValueError (
587
- "can only read bytes or file-like objects "
588
- "with engine='scipy' or 'h5netcdf'"
589
- )
590
- engine = _get_engine_from_magic_number (filename_or_obj )
591
- if engine == "scipy" :
592
- store = backends .ScipyDataStore (filename_or_obj , ** backend_kwargs )
593
- elif engine == "h5netcdf" :
594
- store = backends .H5NetCDFStore .open (
595
- filename_or_obj , group = group , lock = lock , ** backend_kwargs
596
- )
564
+ extra_kwargs ["mode" ] = "r"
565
+ extra_kwargs ["group" ] = group
566
+
567
+ opener = _get_backend_cls (engine )
568
+ store = opener (filename_or_obj , ** extra_kwargs , ** backend_kwargs )
597
569
598
570
with close_on_error (store ):
599
571
ds = maybe_decode_store (store , chunks )
0 commit comments