.. include:: ../common_links.inc v3.0 (25 Jan 2021) ****************** This document explains the changes made to Iris for this release (:doc:`View all changes `.) .. dropdown:: v3.0.0 Release Highlights :color: primary :icon: info :animate: fade-in :open: The highlights for this major release of Iris include: * We've finally dropped support for ``Python 2``, so welcome to ``Iris 3`` and ``Python 3``! * We've extended our coverage of the `CF Conventions and Metadata`_ by introducing support for `CF Ancillary Data`_ and `Quality Flags`_, * Lazy regridding is now available for several regridding schemes, * Managing and manipulating metadata within Iris is now easier and more consistent thanks to the introduction of a new common metadata API, * :ref:`Cube arithmetic ` has been significantly improved with regards to extended broadcasting, auto-transposition and a more lenient behaviour towards handling metadata and coordinates, * Our :ref:`documentation ` has been refreshed, restructured, revitalised and rehosted on `readthedocs`_, * It's now easier than ever to :ref:`install Iris ` as a user or a developer, and the newly revamped developers guide walks you though how you can :ref:`get involved ` and contribute to Iris, * Also, this is a major release of Iris, so please be aware of the :ref:`incompatible changes ` and :ref:`deprecations `. And finally, get in touch with us on :issue:`GitHub` if you have any issues or feature requests for improving Iris. Enjoy! v3.0.1 (27 Jan 2021) ==================== .. dropdown:: v3.0.1 Patches :color: secondary :icon: alert :animate: fade-in The patches included in this release include: 💼 **Internal** #. `@bjlittle`_ gracefully promote formula terms within :mod:`~iris.aux_factory` that have ``units`` of ``unknown`` to ``units`` of ``1`` (dimensionless), where the formula term **must** have dimensionless ``units``. Without this graceful treatment of ``units`` the resulting :class:`~iris.cube.Cube` will **not** contain the expected auxiliary factory, and the associated derived coordinate will be missing. (:pull:`3965`) v3.0.2 (27 May 2021) ==================== .. dropdown:: v3.0.2 Patches :color: secondary :icon: alert :animate: fade-in The patches included in this release include: 🐛 **Bugs Fixed** #. `@jonseddon`_ handled a malformed ``um_stash_source`` CF variable attribute in a netCDF file rather than raising a ``ValueError``. (:pull:`4035`) #. `@rcomer`_ fixed :meth:`~iris.cube.Cube.intersection` for special cases where one cell's bounds align with the requested maximum and minimum, as reported in :issue:`3391`. (:pull:`4059`) #. `@bjlittle`_ resolved a regression in arithmetic behaviour between a coordinate and a cube which resulted in a ``NotYetImplementedError`` being raised, as reported in :issue:`4000`. This fix supports ``+``, ``-``, ``*``, and ``/`` operations between a coordinate and a cube, and for convenience additionally includes :meth:`iris.cube.Cube.__neg__` support. (:pull:`4159`) 📚 **Documentation** #. `@bjlittle`_ updated the ``intersphinx_mapping`` and fixed documentation to use ``stable`` URLs for `matplotlib`_. (:pull:`4003`) [``pre-v3.1.0``] 💼 **Internal** #. `@jamesp`_ updated a test to the latest numpy version (:pull:`3977`) [``pre-v3.1.0``] #. `@bjlittle`_ enabled `cirrus-ci`_ compute credits for non-draft pull-requests from collaborators targeting the Iris ``master`` branch. (:pull:`4007`) [``pre-v3.1.0``] #. `@bjlittle`_ added conditional task execution to ``.cirrus.yml`` to allow developers to easily disable `cirrus-ci`_ tasks. (:pull:`4019`) [``pre-v3.1.0``] #. `@pp-mo`_ adjusted the use of :func:`dask.array.from_array` in :func:`iris._lazy_data.as_lazy_data`, to avoid the dask 'test access'. This makes loading of netcdf files with a large number of variables significantly faster. (:pull:`4135`) #. `@pp-mo`_ reverted a change made previously in (:pull:`3659`) to :meth:`iris.fileformats.pp.PPDataProxy.__getitem__`. The check for empty slicings is no longer needed since (:pull:`4135`) was added. (:pull:`4141`) Note that, the above contributions labelled with ``pre-v3.1.0`` are part of the forthcoming Iris v3.1.0 release, but require to be included in this patch release. v3.0.3 (07 July 2021) ===================== .. dropdown:: v3.0.3 Patches :color: secondary :icon: alert :animate: fade-in The patches included in this release include: 🐛 **Bugs Fixed** #. `@lbdreyer`_ modified :meth:`~iris.cube.Cube.intersection` to use a tolerant equality check, when looking for cells that straddle the wrapping point. (:pull:`4220`) v3.0.4 (22 July 2021) ===================== .. dropdown:: v3.0.4 Patches :color: secondary :icon: alert :animate: fade-in The patches included in this release include: 🐛 **Bugs Fixed** #. `@pp-mo`_ fixed 2 bugs in cube printout: Firstly, ancillary-variables or cell-measures with long names can now widen the cube "dimensions map" to fit, whereas previously printing these cases caused an Exception. Secondly, cube units are now always printed, whereas previously they were missed out any time that the "dimensions map" was widened to accommodate long coordinate names. (:pull:`4233`)(:pull:`4238`) 💼 **Internal** #. `@bjlittle`_ Unpinned the `cftime`_ package dependency within Iris in order to allow use of the latest versions of `cftime`_, `cf-units`_ and `nc-time-axis`_. (:pull:`4222`) #. `@rcomer`_ modified test modules so they run consistently under ``pytest`` and ``nose``, and also fixed some minor issues with :class:`~iris.time.PartialDateTime`. (:pull:`4249`) Note that, we are forced to drop support for ``Python 3.6`` in this patch due to the third-party package dependencies required by (:pull:`4222`). 📢 Announcements ================ #. Congratulations to `@bouweandela`_, `@jvegasbsc`_, and `@zklaus`_ who recently became Iris core developers. They bring a wealth of expertise to the team, and are using Iris to underpin `ESMValTool`_ - "*A community diagnostic and performance metrics tool for routine evaluation of Earth system models in CMIP*". Welcome aboard! 🎉 #. Congratulations also goes to `@jonseddon`_ who recently became an Iris core developer. We look forward to seeing more of your awesome contributions! 🎉 ✨ Features =========== #. `@MoseleyS`_ greatly enhanced the :mod:`~iris.fileformats.nimrod` module to provide richer meta-data translation when loading ``Nimrod`` data into cubes. This covers most known operational use-cases. (:pull:`3647`) #. `@stephenworsley`_ improved the handling of :class:`iris.coords.CellMeasure`\ s in the :class:`~iris.cube.Cube` statistical operations :meth:`~iris.cube.Cube.collapsed`, :meth:`~iris.cube.Cube.aggregated_by` and :meth:`~iris.cube.Cube.rolling_window`. These previously removed every :class:`~iris.coords.CellMeasure` attached to the cube. Now, a :class:`~iris.coords.CellMeasure` will only be removed if it is associated with an axis over which the statistic is being run. (:pull:`3549`) #. `@stephenworsley`_, `@pp-mo`_ and `@abooton`_ added support for `CF Ancillary Data`_ variables. These are created as :class:`iris.coords.AncillaryVariable`, and appear as components of cubes much like :class:`~iris.coords.AuxCoord`\ s, with the new :class:`~iris.cube.Cube` methods :meth:`~iris.cube.Cube.add_ancillary_variable`, :meth:`~iris.cube.Cube.remove_ancillary_variable`, :meth:`~iris.cube.Cube.ancillary_variable`, :meth:`~iris.cube.Cube.ancillary_variables` and :meth:`~iris.cube.Cube.ancillary_variable_dims`. They are loaded from and saved to NetCDF-CF files. Special support for `Quality Flags`_ is also provided, to ensure they load and save with appropriate units. (:pull:`3800`) #. `@bouweandela`_ implemented lazy regridding for the :class:`~iris.analysis.Linear`, :class:`~iris.analysis.Nearest`, and :class:`~iris.analysis.AreaWeighted` regridding schemes. (:pull:`3701`) #. `@bjlittle`_ added `logging`_ support within :mod:`iris.analysis.maths`, :mod:`iris.common.metadata`, and :mod:`iris.common.resolve`. Each module defines a :class:`logging.Logger` instance called ``logger`` with a default ``level`` of ``INFO``. To enable ``DEBUG`` logging use ``logger.setLevel("DEBUG")``. (:pull:`3785`) #. `@bjlittle`_ added the :mod:`iris.common.resolve` module, which provides infrastructure to support the analysis, identification and combination of metadata common between two :class:`~iris.cube.Cube` operands into a single resultant :class:`~iris.cube.Cube` that will be auto-transposed, and with the appropriate broadcast shape. (:pull:`3785`) #. `@bjlittle`_ added the :ref:`common metadata API `, which provides a unified treatment of metadata across Iris, and allows users to easily manage and manipulate their metadata in a consistent way. (:pull:`3785`) #. `@bjlittle`_ added :ref:`lenient metadata ` support, to allow users to control **strict** or **lenient** metadata equivalence, difference and combination. (:pull:`3785`) #. `@bjlittle`_ added :ref:`lenient cube maths ` support and resolved several long standing major issues with cube arithmetic regarding a more robust treatment of cube broadcasting, cube dimension auto-transposition, and preservation of common metadata and coordinates during cube math operations. Resolves :issue:`1887`, :issue:`2765`, and :issue:`3478`. (:pull:`3785`) #. `@pp-mo`_ and `@TomekTrzeciak`_ enhanced :meth:`~iris.cube.Cube.collapse` to allow a 1-D weights array when collapsing over a single dimension. Previously, the weights had to be the same shape as the whole cube, which could cost a lot of memory in some cases. The 1-D form is supported by most weighted array statistics (such as :meth:`np.average`), so this now works with the corresponding Iris schemes (in that case, :const:`~iris.analysis.MEAN`). (:pull:`3943`) 🐛 Bugs Fixed ============= #. `@stephenworsley`_ fixed :meth:`~iris.cube.Cube.remove_coord` to now also remove derived coordinates by removing aux_factories. (:pull:`3641`) #. `@jonseddon`_ fixed ``isinstance(cube, collections.Iterable)`` to now behave as expected if a :class:`~iris.cube.Cube` is iterated over, while also ensuring that ``TypeError`` is still raised. (Fixed by setting the ``__iter__()`` method in :class:`~iris.cube.Cube` to ``None``). (:pull:`3656`) #. `@stephenworsley`_ enabled cube concatenation along an axis shared by cell measures; these cell measures are now concatenated together in the resulting cube. Such a scenario would previously cause concatenation to inappropriately fail. (:pull:`3566`) #. `@stephenworsley`_ newly included :class:`~iris.coords.CellMeasure`\ s in :class:`~iris.cube.Cube` copy operations. Previously copying a :class:`~iris.cube.Cube` would ignore any attached :class:`~iris.coords.CellMeasure`. (:pull:`3546`) #. `@bjlittle`_ set a :class:`~iris.coords.CellMeasure`'s ``measure`` attribute to have a default value of ``area``. Previously, the ``measure`` was provided as a keyword argument to :class:`~iris.coords.CellMeasure` with a default value of ``None``, which caused a ``TypeError`` when no ``measure`` was provided, since ``area`` or ``volume`` are the only accepted values. (:pull:`3533`) #. `@trexfeathers`_ set **all** plot types in :mod:`iris.plot` to now use :obj:`matplotlib.dates.date2num` to format date/time coordinates for use on a plot axis (previously :meth:`~iris.plot.pcolor` and :meth:`~iris.plot.pcolormesh` did not include this behaviour). (:pull:`3762`) #. `@trexfeathers`_ changed date/time axis labels in :mod:`iris.quickplot` to now **always** be based on the ``epoch`` used in :obj:`matplotlib.dates.date2num` (previously would take the unit from a time coordinate, if present, even though the coordinate's value had been changed via ``date2num``). (:pull:`3762`) #. `@pp-mo`_ newly included attributes of cell measures in NETCDF-CF file loading; they were previously being discarded. They are now available on the :class:`~iris.coords.CellMeasure` in the loaded :class:`~iris.cube.Cube`. (:pull:`3800`) #. `@pp-mo`_ fixed the netcdf loader to now handle any grid-mapping variables with missing ``false_easting`` and ``false_northing`` properties, which was previously failing for some coordinate systems. See :issue:`3629`. (:pull:`3804`) #. `@stephenworsley`_ changed the way tick labels are assigned from string coords. Previously, the first tick label would occasionally be duplicated. This also removes the use of the deprecated `matplotlib`_ ``IndexFormatter``. (:pull:`3857`) #. `@znicholls`_ fixed :meth:`~iris.quickplot._title` to only check ``units.is_time_reference`` if the ``units`` symbol is not used. (:pull:`3902`) #. `@rcomer`_ fixed a bug whereby numpy array type attributes on a cube's coordinates could prevent printing it. See :issue:`3921`. (:pull:`3922`) .. _whatsnew 3.0 changes: 💣 Incompatible Changes ======================= #. `@pp-mo`_ rationalised :class:`~iris.cube.CubeList` extraction methods: The former method ``iris.cube.CubeList.extract_strict``, and the ``strict`` keyword of the :meth:`~iris.cube.CubeList.extract` method have been removed, and are replaced by the new routines :meth:`~iris.cube.CubeList.extract_cube` and :meth:`~iris.cube.CubeList.extract_cubes`. The new routines perform the same operation, but in a style more like other ``Iris`` functions such as :meth:`~iris.load_cube` and :meth:`~iris.load_cubes`. Unlike ``strict`` extraction, the type of return value is now completely consistent : :meth:`~iris.cube.CubeList.extract_cube` always returns a :class:`~iris.cube.Cube`, and :meth:`~iris.cube.CubeList.extract_cubes` always returns an :class:`iris.cube.CubeList` of a length equal to the number of constraints. (:pull:`3715`) #. `@pp-mo`_ removed the former function ``iris.analysis.coord_comparison``. (:pull:`3562`) #. `@bjlittle`_ moved the :func:`iris.experimental.equalise_cubes.equalise_attributes` function from the :mod:`iris.experimental` module into the :mod:`iris.util` module. Please use the :func:`iris.util.equalise_attributes` function instead. (:pull:`3527`) #. `@bjlittle`_ removed the module ``iris.experimental.concatenate``. In ``v1.6.0`` the experimental ``concatenate`` functionality was moved to the :meth:`iris.cube.CubeList.concatenate` method. Since then, calling the :func:`iris.experimental.concatenate.concatenate` function raised an exception. (:pull:`3523`) #. `@stephenworsley`_ changed the default units of :class:`~iris.coords.DimCoord` and :class:`~iris.coords.AuxCoord` from `"1"` to `"unknown"`. (:pull:`3795`) #. `@stephenworsley`_ changed Iris objects loaded from NetCDF-CF files to have ``units='unknown'`` where the corresponding NetCDF variable has no ``units`` property. Previously these cases defaulted to ``units='1'``. This affects loading of coordinates whose file variable has no "units" attribute (not valid, under `CF units rules`_): These will now have units of `"unknown"`, rather than `"1"`, which **may prevent the creation of a hybrid vertical coordinate**. While these cases used to "work", this was never really correct behaviour. (:pull:`3795`) #. `@SimonPeatman`_ added attribute ``var_name`` to coordinates created by the :func:`iris.analysis.trajectory.interpolate` function. This prevents duplicate coordinate errors in certain circumstances. (:pull:`3718`) #. `@bjlittle`_ aligned the :func:`iris.analysis.maths.apply_ufunc` with the rest of the :mod:`iris.analysis.maths` API by changing its keyword argument from ``other_cube`` to ``other``. (:pull:`3785`) #. `@bjlittle`_ changed the :meth:`iris.analysis.maths.IFunc.__call__` to ignore any surplus ``other`` keyword argument for a ``data_func`` that requires **only one** argument. This aligns the behaviour of :meth:`iris.analysis.maths.IFunc.__call__` with :func:`~iris.analysis.maths.apply_ufunc`. Previously a ``ValueError`` exception was raised. (:pull:`3785`) .. _whatsnew 3.0 deprecations: 🔥 Deprecations =============== #. `@stephenworsley`_ removed the deprecated :class:`iris.Future` flags ``cell_date_time_objects``, ``netcdf_promote``, ``netcdf_no_unlimited`` and ``clip_latitudes``. (:pull:`3459`) #. `@stephenworsley`_ changed :attr:`iris.fileformats.pp.PPField.lbproc` to be an ``int``. The deprecated attributes ``flag1``, ``flag2`` etc. have been removed from it. (:pull:`3461`) #. `@bjlittle`_ deprecated :func:`~iris.util.as_compatible_shape` in preference for :class:`~iris.common.resolve.Resolve` e.g., ``Resolve(src, tgt)(tgt.core_data())``. The :func:`~iris.util.as_compatible_shape` function will be removed in a future release of Iris. (:pull:`3892`) 🔗 Dependencies =============== #. `@stephenworsley`_, `@trexfeathers`_ and `@bjlittle`_ removed ``Python2`` support, modernising the codebase by switching to exclusive ``Python3`` support. (:pull:`3513`) #. `@bjlittle`_ improved the developer set up process. Configuring Iris and :ref:`installing_from_source` as a developer with all the required package dependencies is now easier with our curated conda environment YAML files. (:pull:`3812`) #. `@stephenworsley`_ pinned Iris to require `Dask`_ ``>=2.0``. (:pull:`3460`) #. `@stephenworsley`_ and `@trexfeathers`_ pinned Iris to require `Cartopy`_ ``>=0.18``, in order to remain compatible with the latest version of `matplotlib`_. (:pull:`3762`) #. `@bjlittle`_ unpinned Iris to use the latest version of `matplotlib`_. Supporting ``Iris`` for both ``Python2`` and ``Python3`` had resulted in pinning our dependency on `matplotlib`_ at ``v2.x``. But this is no longer necessary now that ``Python2`` support has been dropped. (:pull:`3468`) #. `@stephenworsley`_ and `@trexfeathers`_ unpinned Iris to use the latest version of `Proj`_. (:pull:`3762`) #. `@stephenworsley`_ and `@trexfeathers`_ removed GDAL from the extensions dependency group. We no longer consider it to be an extension. (:pull:`3762`) .. _whatsnew 3.0 docs: 📚 Documentation ================ #. `@tkknight`_ moved the :ref:`sphx_glr_generated_gallery_oceanography_plot_orca_projection.py` from the general part of the gallery to oceanography. (:pull:`3761`) #. `@tkknight`_ updated documentation to use a modern sphinx theme and be served from https://scitools-iris.readthedocs.io/en/latest/. (:pull:`3752`) #. `@bjlittle`_ added support for the `black`_ code formatter. This is now automatically checked on GitHub PRs, replacing the older, unittest-based ``iris.tests.test_coding_standards.TestCodeFormat``. Black provides automatic code format correction for most IDEs. See the new developer guide section on :ref:`code_formatting`. (:pull:`3518`) #. `@tkknight`_ and `@trexfeathers`_ refreshed the :ref:`whats_new_contributions` for the :ref:`iris_whatsnew`. This includes always creating the ``latest`` what's new page so it appears on the latest documentation at https://scitools-iris.readthedocs.io/en/latest/whatsnew. This resolves :issue:`2104`, :issue:`3451`, :issue:`3818`, :issue:`3837`. Also updated the :ref:`iris_development_releases_steps` to follow when making a release. (:pull:`3769`, :pull:`3838`, :pull:`3843`) #. `@tkknight`_ enabled the PDF creation of the documentation on the `Read the Docs`_ service. The PDF may be accessed by clicking on the version at the bottom of the side bar, then selecting ``PDF`` from the ``Downloads`` section. (:pull:`3765`) #. `@stephenworsley`_ added a warning to the :func:`iris.analysis.cartography.project` function regarding its behaviour on projections with non-rectangular boundaries. (:pull:`3762`) #. `@stephenworsley`_ added the :ref:`cube_maths_combining_units` section to the user guide to clarify how ``Units`` are handled during cube arithmetic. (:pull:`3803`) #. `@tkknight`_ overhauled the :ref:`developers_guide` including information on getting involved in becoming a contributor and general structure of the guide. This resolves :issue:`2170`, :issue:`2331`, :issue:`3453`, :issue:`314`, :issue:`2902`. (:pull:`3852`) #. `@rcomer`_ added argument descriptions to the :class:`~iris.coords.DimCoord` docstring. (:pull:`3681`) #. `@tkknight`_ added two url's to be ignored for the ``make linkcheck``. This will ensure the Iris github project is not repeatedly hit during the linkcheck for issues and pull requests as it can result in connection refused and thus travis-ci_ job failures. For more information on linkcheck, see :ref:`contributing.documentation.testing`. (:pull:`3873`) #. `@tkknight`_ enabled the napolean_ package that is used by sphinx_ to cater for the existing google style docstrings and to also allow for `numpy`_ docstrings. This resolves :issue:`3841`. (:pull:`3871`) #. `@tkknight`_ configured ``sphinx-build`` to promote warnings to errors when building the documentation via ``make html``. This will minimise technical debt accruing for the documentation. (:pull:`3877`) #. `@tkknight`_ updated :ref:`installing_iris` to include a reference to Windows Subsystem for Linux. (:pull:`3885`) #. `@tkknight`_ updated the :ref:`iris_docs` homepage to include panels so the links are more visible to users. This uses the sphinx-panels_ extension. (:pull:`3884`) #. `@bjlittle`_ created the :ref:`Further topics ` section and included documentation for :ref:`metadata`, :ref:`lenient metadata`, and :ref:`lenient maths`. (:pull:`3890`) #. `@jonseddon`_ updated the CF version of the netCDF saver in the :ref:`saving_iris_cubes` section and in the equivalent function docstring. (:pull:`3925`) #. `@bjlittle`_ applied `Title Case Capitalization`_ to the documentation. (:pull:`3940`) 💼 Internal =========== #. `@pp-mo`_ and `@lbdreyer`_ removed all Iris test dependencies on `iris-grib`_ by transferring all relevant content to the `iris-grib`_ repository. (:pull:`3662`, :pull:`3663`, :pull:`3664`, :pull:`3665`, :pull:`3666`, :pull:`3669`, :pull:`3670`, :pull:`3671`, :pull:`3672`, :pull:`3742`, :pull:`3746`) #. `@lbdreyer`_ and `@pp-mo`_ overhauled the handling of dimensional metadata to remove duplication. (:pull:`3422`, :pull:`3551`) #. `@trexfeathers`_ simplified the standard license header for all files, which removes the need to repeatedly update year numbers in the header. (:pull:`3489`) #. `@stephenworsley`_ changed the numerical values in tests involving the Robinson projection due to improvements made in `Proj`_. (:pull:`3762`) (see also `Proj#1292`_ and `Proj#2151`_) #. `@stephenworsley`_ changed tests to account for more detailed descriptions of projections in `GDAL`_. (:pull:`3762`) (see also `GDAL#1185`_) #. `@stephenworsley`_ changed tests to account for `GDAL`_ now saving fill values for data without masked points. (:pull:`3762`) #. `@trexfeathers`_ changed every graphics test that includes `Cartopy's coastlines`_ to account for new adaptive coastline scaling. (:pull:`3762`) (see also `Cartopy#1105`_) #. `@trexfeathers`_ changed graphics tests to account for some new default grid-line spacing in `Cartopy`_. (:pull:`3762`) (see also `Cartopy#1117`_) #. `@trexfeathers`_ added additional acceptable graphics test targets to account for very minor changes in `matplotlib`_ version ``3.3`` (colormaps, fonts and axes borders). (:pull:`3762`) #. `@rcomer`_ corrected the `matplotlib`_ backend in Iris tests to ignore :obj:`matplotlib.rcdefaults`, instead the tests will **always** use ``agg``. (:pull:`3846`) #. `@bjlittle`_ migrated the `black`_ support from ``19.10b0`` to ``20.8b1``. (:pull:`3866`) #. `@lbdreyer`_ updated the CF standard name table to the latest version: `v75`_. (:pull:`3867`) #. `@bjlittle`_ added :pep:`517` and :pep:`518` support for building and installing Iris, in particular to handle the `PyKE`_ package dependency. (:pull:`3812`) #. `@bjlittle`_ added metadata support for comparing :attr:`~iris.cube.Cube.attributes` dictionaries that contain `numpy`_ arrays using `xxHash`_, an extremely fast non-cryptographic hash algorithm, running at RAM speed limits. #. `@bjlittle`_ added the ``iris.tests.assertDictEqual`` method to override :meth:`unittest.TestCase.assertDictEqual` in order to cope with testing metadata :attr:`~iris.cube.Cube.attributes` dictionary comparison where the value of a key may be a `numpy`_ array. (:pull:`3785`) #. `@bjlittle`_ added the :func:`~iris.config.get_logger` function for creating a generic :class:`logging.Logger` with a :class:`logging.StreamHandler` and custom :class:`logging.Formatter`. (:pull:`3785`) #. `@owena11`_ identified and optimised a bottleneck in ``FieldsFile`` header loading due to the use of :func:`numpy.fromfile`. (:pull:`3791`) #. `@znicholls`_ added a test for plotting with the label being taken from the unit's symbol, see :meth:`~iris.tests.test_quickplot.TestLabels.test_pcolormesh_str_symbol` (:pull:`3902`). #. `@znicholls`_ made :func:`~iris.tests.idiff.step_over_diffs` robust to hyphens (``-``) in the input path (i.e. the ``result_dir`` argument) (:pull:`3902`). #. `@bjlittle`_ migrated the CIaaS from `travis-ci`_ to `cirrus-ci`_, and removed `stickler-ci`_ support. (:pull:`3928`) #. `@bjlittle`_ introduced `nox`_ as a common and easy entry-point for test automation. It can be used both from `cirrus-ci`_ in the cloud, and locally by the developer to run the Iris tests, the doc-tests, the gallery doc-tests, and lint Iris with `flake8`_ and `black`_. (:pull:`3928`) .. _Read the Docs: https://scitools-iris.readthedocs.io/en/latest/ .. _CF units rules: https://cfconventions.org/Data/cf-conventions/cf-conventions-1.8/cf-conventions.html#units .. _CF Ancillary Data: https://cfconventions.org/Data/cf-conventions/cf-conventions-1.8/cf-conventions.html#ancillary-data .. _Quality Flags: https://cfconventions.org/Data/cf-conventions/cf-conventions-1.8/cf-conventions.html#flags .. _iris-grib: https://github.com/SciTools/iris-grib .. _Cartopy: https://github.com/SciTools/cartopy .. _Cartopy's coastlines: https://scitools.org.uk/cartopy/docs/latest/reference/generated/cartopy.mpl.geoaxes.GeoAxes.html?highlight=coastlines#cartopy.mpl.geoaxes.GeoAxes.coastlines .. _Cartopy#1105: https://github.com/SciTools/cartopy/pull/1105 .. _Cartopy#1117: https://github.com/SciTools/cartopy/pull/1117 .. _Dask: https://github.com/dask/dask .. _Proj: https://github.com/OSGeo/PROJ .. _black: https://black.readthedocs.io/en/stable/ .. _Proj#1292: https://github.com/OSGeo/PROJ/pull/1292 .. _Proj#2151: https://github.com/OSGeo/PROJ/pull/2151 .. _GDAL: https://github.com/OSGeo/gdal .. _GDAL#1185: https://github.com/OSGeo/gdal/pull/1185 .. _@MoseleyS: https://github.com/MoseleyS .. _@stephenworsley: https://github.com/stephenworsley .. _@pp-mo: https://github.com/pp-mo .. _@abooton: https://github.com/abooton .. _@bouweandela: https://github.com/bouweandela .. _@bjlittle: https://github.com/bjlittle .. _@trexfeathers: https://github.com/trexfeathers .. _@jonseddon: https://github.com/jonseddon .. _@tkknight: https://github.com/tkknight .. _@lbdreyer: https://github.com/lbdreyer .. _@SimonPeatman: https://github.com/SimonPeatman .. _@TomekTrzeciak: https://github.com/TomekTrzeciak .. _@rcomer: https://github.com/rcomer .. _@jvegasbsc: https://github.com/jvegasbsc .. _@zklaus: https://github.com/zklaus .. _@znicholls: https://github.com/znicholls .. _ESMValTool: https://github.com/ESMValGroup/ESMValTool .. _v75: https://cfconventions.org/Data/cf-standard-names/75/build/cf-standard-name-table.html .. _sphinx-panels: https://sphinx-panels.readthedocs.io/en/latest/ .. _logging: https://docs.python.org/3/library/logging.html .. _numpy: https://github.com/numpy/numpy .. _xxHash: https://github.com/Cyan4973/xxHash .. _PyKE: https://pypi.org/project/scitools-pyke/ .. _@owena11: https://github.com/owena11 .. _readthedocs: https://readthedocs.org/ .. _CF Conventions and Metadata: https://cfconventions.org/ .. _flake8: https://flake8.pycqa.org/en/stable/ .. _nox: https://nox.thea.codes/en/stable/ .. _Title Case Capitalization: https://apastyle.apa.org/style-grammar-guidelines/capitalization/title-case .. _travis-ci: https://travis-ci.org/github/SciTools/iris .. _stickler-ci: https://stickler-ci.com/ .. _cf-units: https://github.com/SciTools/cf-units .. _cftime: https://github.com/Unidata/cftime .. _nc-time-axis: https://github.com/SciTools/nc-time-axis