Skip to content

Commit ee9cadc

Browse files
lbdreyerbjlittle
andauthored
Fix load_http bug, extend testing, and note to docs (#4580)
* Fix opendap bug, add docs and extra testing * Add whats new entry * Update docs/src/whatsnew/3.2.rst Co-authored-by: Bill Little <[email protected]> * Add warning box Co-authored-by: Bill Little <[email protected]>
1 parent 6114167 commit ee9cadc

File tree

5 files changed

+45
-13
lines changed

5 files changed

+45
-13
lines changed

docs/src/whatsnew/3.2.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,9 @@ This document explains the changes made to Iris for this release
177177
to indicate cloud fraction greater than 7.9 oktas, rather than 7.5
178178
(:issue:`3305`, :pull:`4535`)
179179

180+
#. `@lbdreyer`_ fixed a bug in :class:`iris.io.load_http` which was missing an import
181+
(:pull:`4580`)
182+
180183

181184
💣 Incompatible Changes
182185
=======================

lib/iris/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@
4444
standard library function :func:`os.path.expanduser` and
4545
module :mod:`fnmatch` for more details.
4646
47+
.. warning::
48+
49+
If supplying a URL, only OPeNDAP Data Sources are supported.
50+
4751
* constraints:
4852
Either a single constraint, or an iterable of constraints.
4953
Each constraint can be either a string, an instance of
@@ -287,6 +291,7 @@ def load(uris, constraints=None, callback=None):
287291
288292
* uris:
289293
One or more filenames/URIs, as a string or :class:`pathlib.PurePath`.
294+
If supplying a URL, only OPeNDAP Data Sources are supported.
290295
291296
Kwargs:
292297
@@ -315,6 +320,7 @@ def load_cube(uris, constraint=None, callback=None):
315320
316321
* uris:
317322
One or more filenames/URIs, as a string or :class:`pathlib.PurePath`.
323+
If supplying a URL, only OPeNDAP Data Sources are supported.
318324
319325
Kwargs:
320326
@@ -354,6 +360,7 @@ def load_cubes(uris, constraints=None, callback=None):
354360
355361
* uris:
356362
One or more filenames/URIs, as a string or :class:`pathlib.PurePath`.
363+
If supplying a URL, only OPeNDAP Data Sources are supported.
357364
358365
Kwargs:
359366
@@ -399,6 +406,7 @@ def load_raw(uris, constraints=None, callback=None):
399406
400407
* uris:
401408
One or more filenames/URIs, as a string or :class:`pathlib.PurePath`.
409+
If supplying a URL, only OPeNDAP Data Sources are supported.
402410
403411
Kwargs:
404412

lib/iris/fileformats/netcdf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -825,12 +825,12 @@ def inner(cf_datavar):
825825

826826
def load_cubes(filenames, callback=None, constraints=None):
827827
"""
828-
Loads cubes from a list of NetCDF filenames/URLs.
828+
Loads cubes from a list of NetCDF filenames/OPeNDAP URLs.
829829
830830
Args:
831831
832832
* filenames (string/list):
833-
One or more NetCDF filenames/DAP URLs to load from.
833+
One or more NetCDF filenames/OPeNDAP URLs to load from.
834834
835835
Kwargs:
836836

lib/iris/io/__init__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ def load_files(filenames, callback, constraints=None):
216216

217217
def load_http(urls, callback):
218218
"""
219-
Takes a list of urls and a callback function, and returns a generator
219+
Takes a list of OPeNDAP URLs and a callback function, and returns a generator
220220
of Cubes from the given URLs.
221221
222222
.. note::
@@ -226,11 +226,11 @@ def load_http(urls, callback):
226226
227227
"""
228228
# Create default dict mapping iris format handler to its associated filenames
229+
from iris.fileformats import FORMAT_AGENT
230+
229231
handler_map = collections.defaultdict(list)
230232
for url in urls:
231-
handling_format_spec = iris.fileformats.FORMAT_AGENT.get_spec(
232-
url, None
233-
)
233+
handling_format_spec = FORMAT_AGENT.get_spec(url, None)
234234
handler_map[handling_format_spec].append(url)
235235

236236
# Call each iris format handler with the appropriate filenames

lib/iris/tests/test_load.py

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
import iris.tests as tests # isort:skip
1313

1414
import pathlib
15+
from unittest import mock
16+
17+
import netCDF4
1518

1619
import iris
1720
import iris.io
@@ -148,19 +151,20 @@ def test_path_object(self):
148151
self.assertEqual(len(cubes), 1)
149152

150153

151-
class TestOpenDAP(tests.IrisTest):
152-
def test_load(self):
153-
# Check that calling iris.load_* with a http URI triggers a call to
154-
# ``iris.io.load_http``
154+
class TestOPeNDAP(tests.IrisTest):
155+
def setUp(self):
156+
self.url = "http://geoport.whoi.edu:80/thredds/dodsC/bathy/gom15"
155157

156-
url = "http://geoport.whoi.edu:80/thredds/dodsC/bathy/gom15"
158+
def test_load_http_called(self):
159+
# Check that calling iris.load_* with an http URI triggers a call to
160+
# ``iris.io.load_http``
157161

158162
class LoadHTTPCalled(Exception):
159163
pass
160164

161165
def new_load_http(passed_urls, *args, **kwargs):
162166
self.assertEqual(len(passed_urls), 1)
163-
self.assertEqual(url, passed_urls[0])
167+
self.assertEqual(self.url, passed_urls[0])
164168
raise LoadHTTPCalled()
165169

166170
try:
@@ -174,11 +178,28 @@ def new_load_http(passed_urls, *args, **kwargs):
174178
iris.load_cubes,
175179
]:
176180
with self.assertRaises(LoadHTTPCalled):
177-
fn(url)
181+
fn(self.url)
178182

179183
finally:
180184
iris.io.load_http = orig
181185

186+
def test_netCDF_Dataset_call(self):
187+
# Check that load_http calls netCDF4.Dataset and supplies the expected URL.
188+
189+
# To avoid making a request to an OPeNDAP server in a test, instead
190+
# mock the call to netCDF.Dataset so that it returns a dataset for a
191+
# local file.
192+
filename = tests.get_data_path(
193+
("NetCDF", "global", "xyt", "SMALL_total_column_co2.nc")
194+
)
195+
fake_dataset = netCDF4.Dataset(filename)
196+
197+
with mock.patch(
198+
"netCDF4.Dataset", return_value=fake_dataset
199+
) as dataset_loader:
200+
next(iris.io.load_http([self.url], callback=None))
201+
dataset_loader.assert_called_with(self.url, mode="r")
202+
182203

183204
if __name__ == "__main__":
184205
tests.main()

0 commit comments

Comments
 (0)