Skip to content

Commit f395458

Browse files
authored
Merge branch 'main' into add_cov
2 parents ef86cd0 + 11da71b commit f395458

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1795
-1176
lines changed

docs/src/common_links.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
.. _issues on GitHub: https://github.com/SciTools/iris/issues?q=is%3Aopen+is%3Aissue+sort%3Areactions-%2B1-desc
4242
.. _python-stratify: https://github.com/SciTools/python-stratify
4343
.. _iris-esmf-regrid: https://github.com/SciTools-incubator/iris-esmf-regrid
44+
.. _netCDF4: https://github.com/Unidata/netcdf4-python
4445

4546

4647
.. comment

docs/src/userguide/glossary.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.. include:: ../common_links.inc
2+
13
.. _glossary:
24

35
Glossary
@@ -125,7 +127,7 @@ Glossary
125127
of formats.
126128

127129
| **Related:** :term:`CartoPy` **|** :term:`NumPy`
128-
| **More information:** `Matplotlib <https://scitools.org.uk/cartopy/docs/latest/>`_
130+
| **More information:** `matplotlib`_
129131
|
130132
131133
Metadata
@@ -143,9 +145,11 @@ Glossary
143145
When Iris loads this format, it also especially recognises and interprets data
144146
encoded according to the :term:`CF Conventions`.
145147

148+
__ `NetCDF4`_
149+
146150
| **Related:** :term:`Fields File (FF) Format`
147151
**|** :term:`GRIB Format` **|** :term:`Post Processing (PP) Format`
148-
| **More information:** `NetCDF-4 Python Git <https://github.com/Unidata/netcdf4-python>`_
152+
| **More information:** `NetCDF-4 Python Git`__
149153
|
150154
151155
NumPy

docs/src/whatsnew/2.1.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.. include:: ../common_links.inc
2+
13
v2.1 (06 Jun 2018)
24
******************
35

@@ -67,7 +69,7 @@ Incompatible Changes
6769
as an alternative.
6870

6971
* This release of Iris contains a number of updated metadata translations.
70-
See this
72+
See this
7173
`changelist <https://github.com/SciTools/iris/commit/69597eb3d8501ff16ee3d56aef1f7b8f1c2bb316#diff-1680206bdc5cfaa83e14428f5ba0f848>`_
7274
for further information.
7375

@@ -84,14 +86,16 @@ Internal
8486
calendar.
8587

8688
* Iris updated its time-handling functionality from the
87-
`netcdf4-python <http://unidata.github.io/netcdf4-python/>`_
89+
`netcdf4-python`__
8890
``netcdftime`` implementation to the standalone module
8991
`cftime <https://github.com/Unidata/cftime>`_.
9092
cftime is entirely compatible with netcdftime, but some issues may
9193
occur where users are constructing their own datetime objects.
9294
In this situation, simply replacing ``netcdftime.datetime`` with
9395
``cftime.datetime`` should be sufficient.
9496

97+
__ `netCDF4`_
98+
9599
* Iris now requires version 2 of Matplotlib, and ``>=1.14`` of NumPy.
96100
Full requirements can be seen in the `requirements <https://github.com/SciTools/iris/>`_
97101
directory of the Iris' the source.

docs/src/whatsnew/latest.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ This document explains the changes made to Iris for this release
4040
🐛 Bugs Fixed
4141
=============
4242

43-
#. N/A
43+
#. `@trexfeathers`_ and `@pp-mo`_ made Iris' use of the `netCDF4`_ library
44+
thread-safe. (:pull:`5095`)
4445

4546

4647
💣 Incompatible Changes

lib/iris/experimental/ugrid/load.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,8 @@ def load_meshes(uris, var_name=None):
209209

210210
result = {}
211211
for source in valid_sources:
212-
meshes_dict = _meshes_from_cf(CFUGridReader(source))
212+
with CFUGridReader(source) as cf_reader:
213+
meshes_dict = _meshes_from_cf(cf_reader)
213214
meshes = list(meshes_dict.values())
214215
if var_name is not None:
215216
meshes = list(filter(lambda m: m.var_name == var_name, meshes))

lib/iris/fileformats/cf.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
import re
2121
import warnings
2222

23-
import netCDF4
2423
import numpy as np
2524
import numpy.ma as ma
2625

26+
from iris.fileformats.netcdf import _thread_safe_nc
2727
import iris.util
2828

2929
#
@@ -1050,7 +1050,9 @@ def __init__(self, filename, warn=False, monotonic=False):
10501050
#: Collection of CF-netCDF variables associated with this netCDF file
10511051
self.cf_group = self.CFGroup()
10521052

1053-
self._dataset = netCDF4.Dataset(self._filename, mode="r")
1053+
self._dataset = _thread_safe_nc.DatasetWrapper(
1054+
self._filename, mode="r"
1055+
)
10541056

10551057
# Issue load optimisation warning.
10561058
if warn and self._dataset.file_format in [
@@ -1068,6 +1070,19 @@ def __init__(self, filename, warn=False, monotonic=False):
10681070
self._build_cf_groups()
10691071
self._reset()
10701072

1073+
def __enter__(self):
1074+
# Enable use as a context manager
1075+
# N.B. this **guarantees* closure of the file, when the context is exited.
1076+
# Note: ideally, the class would not do so much work in the __init__ call, and
1077+
# would do all that here, after acquiring necessary permissions/locks.
1078+
# But for legacy reasons, we can't do that. So **effectively**, the context
1079+
# (in terms of access control) alreday started, when we created the object.
1080+
return self
1081+
1082+
def __exit__(self, exc_type, exc_value, traceback):
1083+
# When used as a context-manager, **always** close the file on exit.
1084+
self._close()
1085+
10711086
@property
10721087
def filename(self):
10731088
"""The file that the CFReader is reading."""
@@ -1294,10 +1309,15 @@ def _reset(self):
12941309
for nc_var_name in self._dataset.variables.keys():
12951310
self.cf_group[nc_var_name].cf_attrs_reset()
12961311

1297-
def __del__(self):
1312+
def _close(self):
12981313
# Explicitly close dataset to prevent file remaining open.
12991314
if self._dataset is not None:
13001315
self._dataset.close()
1316+
self._dataset = None
1317+
1318+
def __del__(self):
1319+
# Be sure to close dataset when CFReader is destroyed / garbage-collected.
1320+
self._close()
13011321

13021322

13031323
def _getncattr(dataset, attr, default=None):

0 commit comments

Comments
 (0)