File tree Expand file tree Collapse file tree 4 files changed +86
-4
lines changed Expand file tree Collapse file tree 4 files changed +86
-4
lines changed Original file line number Diff line number Diff line change @@ -106,7 +106,24 @@ def guess_engine(store_spec):
106
106
except Exception :
107
107
warnings .warn (f"{ engine !r} fails while guessing" , RuntimeWarning )
108
108
109
- raise ValueError ("cannot guess the engine, try passing one explicitly" )
109
+ installed = [k for k in engines if k != "store" ]
110
+ if installed :
111
+ raise ValueError (
112
+ "did not find a match in any of xarray's currently installed IO "
113
+ f"backends { installed } . Consider explicitly selecting one of the "
114
+ "installed backends via the ``engine`` parameter to "
115
+ "xarray.open_dataset(), or installing additional IO dependencies:\n "
116
+ "http://xarray.pydata.org/en/stable/getting-started-guide/installing.html\n "
117
+ "http://xarray.pydata.org/en/stable/user-guide/io.html"
118
+ )
119
+ else :
120
+ raise ValueError (
121
+ "xarray is unable to open this file because it has no currently "
122
+ "installed IO backends. Xarray's read/write support requires "
123
+ "installing optional dependencies:\n "
124
+ "http://xarray.pydata.org/en/stable/getting-started-guide/installing.html\n "
125
+ "http://xarray.pydata.org/en/stable/user-guide/io.html"
126
+ )
110
127
111
128
112
129
def get_backend (engine ):
Original file line number Diff line number Diff line change @@ -2771,7 +2771,9 @@ def test_open_badbytes(self):
2771
2771
with pytest .raises (ValueError , match = r"HDF5 as bytes" ):
2772
2772
with open_dataset (b"\211 HDF\r \n \032 \n " , engine = "h5netcdf" ):
2773
2773
pass
2774
- with pytest .raises (ValueError , match = r"cannot guess the engine" ):
2774
+ with pytest .raises (
2775
+ ValueError , match = r"match in any of xarray's currently installed IO"
2776
+ ):
2775
2777
with open_dataset (b"garbage" ):
2776
2778
pass
2777
2779
with pytest .raises (ValueError , match = r"can only read bytes" ):
@@ -2823,7 +2825,10 @@ def test_open_fileobj(self):
2823
2825
# `raises_regex`?). Ref https://github.com/pydata/xarray/pull/5191
2824
2826
with open (tmp_file , "rb" ) as f :
2825
2827
f .seek (8 )
2826
- with pytest .raises (ValueError , match = "cannot guess the engine" ):
2828
+ with pytest .raises (
2829
+ ValueError ,
2830
+ match = "match in any of xarray's currently installed IO" ,
2831
+ ):
2827
2832
with pytest .warns (
2828
2833
RuntimeWarning ,
2829
2834
match = re .escape ("'h5netcdf' fails while guessing" ),
Original file line number Diff line number Diff line change @@ -157,3 +157,23 @@ def test_build_engines_sorted():
157
157
158
158
assert set (indices ) < {0 , - 1 }
159
159
assert list (backend_entrypoints ) == sorted (backend_entrypoints )
160
+
161
+
162
+ @mock .patch (
163
+ "xarray.backends.plugins.list_engines" ,
164
+ mock .MagicMock (return_value = {"dummy" : DummyBackendEntrypointArgs ()}),
165
+ )
166
+ def test_no_matching_engine_found ():
167
+ with pytest .raises (
168
+ ValueError , match = "match in any of xarray's currently installed IO"
169
+ ):
170
+ plugins .guess_engine ("not-valid" )
171
+
172
+
173
+ @mock .patch (
174
+ "xarray.backends.plugins.list_engines" ,
175
+ mock .MagicMock (return_value = {}),
176
+ )
177
+ def test_no_engines_installed ():
178
+ with pytest .raises (ValueError , match = "no currently installed IO backends." ):
179
+ plugins .guess_engine ("not-valid" )
Original file line number Diff line number Diff line change @@ -36,13 +36,48 @@ def _construct_cache_dir(path):
36
36
"RGB.byte" : "https://github.com/mapbox/rasterio/raw/1.2.1/tests/data/RGB.byte.tif" ,
37
37
"shade" : "https://github.com/mapbox/rasterio/raw/1.2.1/tests/data/shade.tif" ,
38
38
}
39
+ file_formats = {
40
+ "air_temperature" : 3 ,
41
+ "rasm" : 3 ,
42
+ "ROMS_example" : 4 ,
43
+ "tiny" : 3 ,
44
+ "eraint_uvz" : 3 ,
45
+ }
46
+
47
+
48
+ def _check_netcdf_engine_installed (name ):
49
+ version = file_formats .get (name )
50
+ if version == 3 :
51
+ try :
52
+ import scipy # noqa
53
+ except ImportError :
54
+ try :
55
+ import netCDF4 # noqa
56
+ except ImportError :
57
+ raise ImportError (
58
+ f"opening tutorial dataset { name } requires either scipy or "
59
+ "netCDF4 to be installed."
60
+ )
61
+ if version == 4 :
62
+ try :
63
+ import h5netcdf # noqa
64
+ except ImportError :
65
+ try :
66
+ import netCDF4 # noqa
67
+ except ImportError :
68
+ raise ImportError (
69
+ f"opening tutorial dataset { name } requires either h5netcdf "
70
+ "or netCDF4 to be installed."
71
+ )
39
72
40
73
41
74
# idea borrowed from Seaborn
42
75
def open_dataset (
43
76
name ,
44
77
cache = True ,
45
78
cache_dir = None ,
79
+ * ,
80
+ engine = None ,
46
81
** kws ,
47
82
):
48
83
"""
@@ -94,13 +129,18 @@ def open_dataset(
94
129
if not path .suffix :
95
130
# process the name
96
131
default_extension = ".nc"
132
+ if engine is None :
133
+ _check_netcdf_engine_installed (name )
97
134
path = path .with_suffix (default_extension )
135
+ elif path .suffix == ".grib" :
136
+ if engine is None :
137
+ engine = "cfgrib"
98
138
99
139
url = f"{ base_url } /raw/{ version } /{ path .name } "
100
140
101
141
# retrieve the file
102
142
filepath = pooch .retrieve (url = url , known_hash = None , path = cache_dir )
103
- ds = _open_dataset (filepath , ** kws )
143
+ ds = _open_dataset (filepath , engine = engine , ** kws )
104
144
if not cache :
105
145
ds = ds .load ()
106
146
pathlib .Path (filepath ).unlink ()
You can’t perform that action at this time.
0 commit comments