From d3896c17de6e0f054ad694fae2eb2741f3dac0a0 Mon Sep 17 00:00:00 2001 From: Martin Yeo Date: Mon, 13 Apr 2026 15:30:50 +0100 Subject: [PATCH 1/9] Add new page explaining units. --- docs/src/user_manual/explanation/units.rst | 128 +++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 docs/src/user_manual/explanation/units.rst diff --git a/docs/src/user_manual/explanation/units.rst b/docs/src/user_manual/explanation/units.rst new file mode 100644 index 0000000000..6c98f6e7ca --- /dev/null +++ b/docs/src/user_manual/explanation/units.rst @@ -0,0 +1,128 @@ +.. explanation:: Units + :tags: topic_data_model + + Read about how Iris objects such as Cubes and Coordinates are assigned scientific units. + +===== +Units +===== + +.. todo:: cross reference in navigating_a_cube, why_iris, cube_maths, um_files_loading, glossary + +A measure such as 'temperature' cannot just be described by a number - e.g. +273.15 - it must also be associated with a unit - e.g. 'Kelvin' - to give it +meaning. This is a core element of the :term:`CF Conventions`, and so is +fundamental to the design of Iris: + +- All data model objects - e.g. :term:`Cube`, :term:`Coordinate`; anything + based on :class:`~iris.common.mixin.CFVariableMixin` - have a + :attr:`~iris.common.mixin.CFVariableMixin.units` attribute. +- Operations on Iris objects are 'recorded' in their units attribute. E.g. + a :class:`~iris.cube.Cube` with units of ``m/s`` multiplied by a + :class:`~iris.cube.Cube` with units of ``s`` will have units of ``m`` after + the operation. Read more: :ref:`cube_maths_combining_units`. +- Operations between :class:`~iris.cube.Cube` objects - e.g. arithmetic or + merging - are only permitted if the units are compatible. Read more: + :doc:`/user_manual/section_indexes/metadata_arithmetic`, + :ref:`merge_and_concat`. + +In addition to the CF Conventions, the Iris ecosystem defines two further units: + +- ``no-unit`` - the associated data is not suitable for describing with a unit. +- ``unknown`` - the unit describing the associated data cannot be determined. + If a calculation is prevented because it would result in inappropriate units, + it may be forced by setting the units of the original cubes to be + ``"unknown"``. + +The Units API +------------- + +.. testsetup:: + + from iris.cube import Cube + from iris.experimental.units import USE_CFPINT + my_cube = Cube([0, 1, 2]) + +Setting the :attr:`~iris.common.mixin.CFVariableMixin.units` on an object is +simple - you provide a string and Iris will parse and store it appropriately: + + >>> my_cube.units = 'm/s' + >>> print(my_cube.units) + m/s + >>> print(repr(my_cube.units)) + Unit('m/s') + +As well as a string, you can assign objects directly from the unit-handling +library and these will also be parsed. If you want to test this: the function +:func:`iris.common.units.make_unit` outputs the same object that would be +created when assigning an input to the +:attr:`~iris.common.mixin.CFVariableMixin.units` attribute. + +You can choose which library you want Iris to use for unit parsing and operations: + +- Cf-units (:class:`iris.common.units.CfUnit`) +- Pint (:class:`iris.common.units.PintUnit`) - **experimental** at time of writing (``2026-04-13``) + +You make this choice using the :data:`iris.experimental.units.USE_CFPINT` flag: + + >>> with USE_CFPINT.context(): + ... my_cube.units = "m/s" + ... print(my_cube.units) + m s-1 + ... print(repr(my_cube.units)) + Unit('meter / second') + +In both cases Iris internals ensure the unit is CF-compliant. CF-compliance is +standard behaviour for Cf-units; while the Pint case currently (``2026-04-13``) +uses the cfpint library with some Iris-specific modifications. The intent is a +**seamless user experience** +regardless of the underlying library, hopefully allowing a +**gradual transition to Pint**, +bringing Iris users closer to the wider scientific Python ecosystem. + +To aid the above transition, any compatibility features have been marked as +deprecated, with advice on how to update your code. Example: +:attr:`iris.common.units.PintUnit.is_dimensionless`. + +The Libraries Underneath +------------------------ + +The :term:`CF Conventions` officially define unit behaviour as follows: + +- Reference time units: (e.g. + ``days since 2000-12-01 in the proleptic gregorian calendar``) behaviour + described directly in the CF Conventions pages; section x.x.x? +- All other units: behaviour provided by the UDUNITS2 package, with a small + number of modifications described in the CF Conventions pages; section x.x.x + +Since reference time units are not based on existing software, the rules given +by the CF Conventions are implemented by the cftime Python package. + +A full software implementation of CF Conventions units must therefore combine: + +- cftime +- UDUNITS2 +- The specific UDUNITS2 modifications + +The two most established packages for this are: Cf-units and Cfunits. + +Both of these packages have +struggled to find ways of combining Python with UDUNITS2, especially when it +comes to installation. These struggles have inspired attempts to implement +UDUNITS2 in Python or via the Pint Python package, all of which are experimental +at time of writing (``2026-04-13``). + +Iris' hope for the future is for a mature and well maintained implementation of +CF-compliant Pint. The CF Conventions are the de facto standard for storing +atmospheric/oceanographic data, while Pint is the most widely accepted Python +package for units. Being Pint-based (rather than UDUNITS2-based), should +improve the Iris user experience: + +- Better interoperability/collaboration with the wider scientific Python ecosystem. +- A better maintained units library - more features, more support. +- Simpler installation. Specifically: this would allow Iris to be fully + installed via Pip (UDUNITS2 needs Conda for installation). + +This is why we are future-proofing Iris to support both Cf-units and Pint, and +why we are working with international collaborators to establish a +CF-compliant Pint implementation. From dd8cac6505d20338e04e6d7baccecf47a56594d0 Mon Sep 17 00:00:00 2001 From: Martin Yeo Date: Mon, 13 Apr 2026 15:46:48 +0100 Subject: [PATCH 2/9] Unit page cross references. --- docs/src/user_manual/explanation/um_files_loading.rst | 2 ++ docs/src/user_manual/explanation/units.rst | 6 +++++- docs/src/user_manual/explanation/why_iris.rst | 2 +- docs/src/user_manual/how_to/navigating_a_cube.rst | 4 ++-- docs/src/user_manual/reference/glossary.rst | 2 +- docs/src/user_manual/section_indexes/general.rst | 1 + docs/src/user_manual/tutorial/cube_maths.rst | 4 +++- docs/src/user_manual/tutorial/merge_and_concat.rst | 2 +- 8 files changed, 16 insertions(+), 7 deletions(-) diff --git a/docs/src/user_manual/explanation/um_files_loading.rst b/docs/src/user_manual/explanation/um_files_loading.rst index 8c6718805a..2b1b6706f3 100644 --- a/docs/src/user_manual/explanation/um_files_loading.rst +++ b/docs/src/user_manual/explanation/um_files_loading.rst @@ -344,6 +344,8 @@ Time Information **Details** +More about units: :doc:`../explanation/units`. + In Iris (as in CF) times and time intervals are both expressed as simple numbers, following the approach of the `UDUNITS project `_. diff --git a/docs/src/user_manual/explanation/units.rst b/docs/src/user_manual/explanation/units.rst index 6c98f6e7ca..8a04bf33a0 100644 --- a/docs/src/user_manual/explanation/units.rst +++ b/docs/src/user_manual/explanation/units.rst @@ -72,7 +72,11 @@ You make this choice using the :data:`iris.experimental.units.USE_CFPINT` flag: ... print(repr(my_cube.units)) Unit('meter / second') -In both cases Iris internals ensure the unit is CF-compliant. CF-compliance is +Both the above classes - :class:`~iris.common.units.CfUnit` and +:class:`~iris.common.units.PintUnit` - are Iris subclasses of the original +Cf-units and Pint classes - :class:`cf_units.Unit` and :class:`pint.Unit` +respectively. In both cases Iris internals ensure the unit is CF-compliant. +CF-compliance is standard behaviour for Cf-units; while the Pint case currently (``2026-04-13``) uses the cfpint library with some Iris-specific modifications. The intent is a **seamless user experience** diff --git a/docs/src/user_manual/explanation/why_iris.rst b/docs/src/user_manual/explanation/why_iris.rst index d7df72d8ad..865427591e 100644 --- a/docs/src/user_manual/explanation/why_iris.rst +++ b/docs/src/user_manual/explanation/why_iris.rst @@ -17,7 +17,7 @@ It excels when working with multi-dimensional Earth Science data, where tabular representations become unwieldy and inefficient. `CF Standard names `_, -`units `_, and coordinate metadata +units, and coordinate metadata are built into Iris, giving you a rich and expressive interface for maintaining an accurate representation of your data. Its treatment of data and associated metadata as first-class objects includes: diff --git a/docs/src/user_manual/how_to/navigating_a_cube.rst b/docs/src/user_manual/how_to/navigating_a_cube.rst index 2e4f3c0ca9..1b85f3a59f 100644 --- a/docs/src/user_manual/how_to/navigating_a_cube.rst +++ b/docs/src/user_manual/how_to/navigating_a_cube.rst @@ -70,8 +70,8 @@ and :attr:`Cube.units ` respectively:: print(cube.units) Interrogating these with the standard :func:`type` function will tell you that ``standard_name`` and ``long_name`` -are either a string or ``None``, and ``units`` is an instance of :class:`iris.unit.Unit`. A more in depth discussion on -the cube units and their functional effects can be found at the end of :doc:`../tutorial/cube_maths`. +are either a string or ``None``, and ``units`` is a specialised unit-handling +object. Read more about units here: :doc:`../explanation/units`. You can access a string representing the "name" of a cube with the :meth:`Cube.name() ` method:: diff --git a/docs/src/user_manual/reference/glossary.rst b/docs/src/user_manual/reference/glossary.rst index 3c04b1756b..7ebe9601c6 100644 --- a/docs/src/user_manual/reference/glossary.rst +++ b/docs/src/user_manual/reference/glossary.rst @@ -203,7 +203,7 @@ Glossary The unit with which the :term:`phenomenon` is measured e.g. m / sec. | **Related:** :term:`Cube` - | **More information:** :doc:`../explanation/iris_cubes` + | **More information:** :doc:`../explanation/units` :doc:`../explanation/iris_cubes` | Xarray diff --git a/docs/src/user_manual/section_indexes/general.rst b/docs/src/user_manual/section_indexes/general.rst index f3d28824a1..43d235f481 100644 --- a/docs/src/user_manual/section_indexes/general.rst +++ b/docs/src/user_manual/section_indexes/general.rst @@ -26,3 +26,4 @@ Below are any pages not belonging to any other User Manual section. ../explanation/um_files_loading ../explanation/ux_guide ../explanation/which_regridder_to_use + ../explanation/units diff --git a/docs/src/user_manual/tutorial/cube_maths.rst b/docs/src/user_manual/tutorial/cube_maths.rst index 817b496686..f9e38b9a35 100644 --- a/docs/src/user_manual/tutorial/cube_maths.rst +++ b/docs/src/user_manual/tutorial/cube_maths.rst @@ -17,7 +17,7 @@ this attribute can then be manipulated directly:: cube.data -= 273.15 The problem with manipulating the data directly is that other metadata may -become inconsistent; in this case the units of the cube are no longer what was +become inconsistent; in this case the :term:`unit` of the cube are no longer what was intended. This example could be rectified by changing the units attribute:: cube.units = 'celsius' @@ -237,6 +237,8 @@ The result could now be plotted using the guidance provided in the Combining Units --------------- +More about units: :doc:`../explanation/units`. + It should be noted that when combining cubes by multiplication, division or power operations, the resulting cube will have a unit which is an appropriate combination of the constituent units. In the above example, since ``pressure`` diff --git a/docs/src/user_manual/tutorial/merge_and_concat.rst b/docs/src/user_manual/tutorial/merge_and_concat.rst index 3f717f064e..ddd008fed1 100644 --- a/docs/src/user_manual/tutorial/merge_and_concat.rst +++ b/docs/src/user_manual/tutorial/merge_and_concat.rst @@ -593,7 +593,7 @@ Concatenate **Time Units** -Differences in the units of the time coordinates of the input cubes probably cause +Differences in the :term:`unit` of the time coordinates of the input cubes probably cause the greatest amount of concatenate-related difficulties. In recognition of this, Iris has a helper function, :func:`~iris.util.unify_time_units`, to apply a common time unit to all the input cubes. From fa7a5af4745934bf0b5aadcfd92e53e36f28f345 Mon Sep 17 00:00:00 2001 From: Martin Yeo Date: Mon, 13 Apr 2026 16:14:25 +0100 Subject: [PATCH 3/9] More links. --- docs/src/common_links.inc | 1 + docs/src/user_manual/explanation/units.rst | 54 ++++++++++++++-------- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/docs/src/common_links.inc b/docs/src/common_links.inc index f84b8bf1ba..8c1e846531 100644 --- a/docs/src/common_links.inc +++ b/docs/src/common_links.inc @@ -49,6 +49,7 @@ .. _SciTools Contributor's License Agreement (CLA): https://cla-assistant.io/SciTools/ .. _extlinks: https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html .. _Diataxis: https://diataxis.fr/ +.. _CF Conventions: https://cfconventions.org/ .. comment diff --git a/docs/src/user_manual/explanation/units.rst b/docs/src/user_manual/explanation/units.rst index 8a04bf33a0..fde133fc21 100644 --- a/docs/src/user_manual/explanation/units.rst +++ b/docs/src/user_manual/explanation/units.rst @@ -3,6 +3,8 @@ Read about how Iris objects such as Cubes and Coordinates are assigned scientific units. +.. include:: /common_links.inc + ===== Units ===== @@ -60,8 +62,22 @@ created when assigning an input to the You can choose which library you want Iris to use for unit parsing and operations: -- Cf-units (:class:`iris.common.units.CfUnit`) -- Pint (:class:`iris.common.units.PintUnit`) - **experimental** at time of writing (``2026-04-13``) +.. list-table:: Choice of Cf-units or Pint in Iris + :header-rows: 1 + :stub-columns: 1 + + * - Library + - Iris Class + - Parent Class + - Status @ ``2026-04-13`` + * - `Cf-units`_ + - :class:`iris.common.units.CfUnit` + - :class:`cf_units.Unit` + - Default + * - `Pint`_ + - :class:`iris.common.units.PintUnit` + - :class:`pint.Unit` + - Experimental You make this choice using the :data:`iris.experimental.units.USE_CFPINT` flag: @@ -72,16 +88,12 @@ You make this choice using the :data:`iris.experimental.units.USE_CFPINT` flag: ... print(repr(my_cube.units)) Unit('meter / second') -Both the above classes - :class:`~iris.common.units.CfUnit` and -:class:`~iris.common.units.PintUnit` - are Iris subclasses of the original -Cf-units and Pint classes - :class:`cf_units.Unit` and :class:`pint.Unit` -respectively. In both cases Iris internals ensure the unit is CF-compliant. -CF-compliance is +In both cases Iris internals ensure the unit is CF-compliant. CF-compliance is standard behaviour for Cf-units; while the Pint case currently (``2026-04-13``) -uses the cfpint library with some Iris-specific modifications. The intent is a +uses the `Cfpint`_ library with some Iris-specific modifications. The intent is a **seamless user experience** regardless of the underlying library, hopefully allowing a -**gradual transition to Pint**, +**gradual transition to `Pint`_**, bringing Iris users closer to the wider scientific Python ecosystem. To aid the above transition, any compatibility features have been marked as @@ -93,14 +105,13 @@ The Libraries Underneath The :term:`CF Conventions` officially define unit behaviour as follows: -- Reference time units: (e.g. - ``days since 2000-12-01 in the proleptic gregorian calendar``) behaviour - described directly in the CF Conventions pages; section x.x.x? -- All other units: behaviour provided by the UDUNITS2 package, with a small - number of modifications described in the CF Conventions pages; section x.x.x +- Reference time units: e.g. ``days since 2000-12-01``, behaviour + described directly in the `CF Conventions`_ pages; section 4.4. +- All other units: behaviour provided by the `UDUNITS2`_ package, with a small + number of modifications described in the `CF Conventions`_ pages; section 3.1. Since reference time units are not based on existing software, the rules given -by the CF Conventions are implemented by the cftime Python package. +by the CF Conventions are implemented by the `Cftime`_ Python package. A full software implementation of CF Conventions units must therefore combine: @@ -108,16 +119,16 @@ A full software implementation of CF Conventions units must therefore combine: - UDUNITS2 - The specific UDUNITS2 modifications -The two most established packages for this are: Cf-units and Cfunits. +The two most established packages for this are: `Cf-units`_ and `Cfunits`_. Both of these packages have struggled to find ways of combining Python with UDUNITS2, especially when it comes to installation. These struggles have inspired attempts to implement -UDUNITS2 in Python or via the Pint Python package, all of which are experimental +UDUNITS2 in Python or via the `Pint`_ Python package, all of which are experimental at time of writing (``2026-04-13``). Iris' hope for the future is for a mature and well maintained implementation of -CF-compliant Pint. The CF Conventions are the de facto standard for storing +**CF-compliant Pint**. The CF Conventions are the de facto standard for storing atmospheric/oceanographic data, while Pint is the most widely accepted Python package for units. Being Pint-based (rather than UDUNITS2-based), should improve the Iris user experience: @@ -130,3 +141,10 @@ improve the Iris user experience: This is why we are future-proofing Iris to support both Cf-units and Pint, and why we are working with international collaborators to establish a CF-compliant Pint implementation. + +.. _Cf-units: https://github.com/SciTools/cf-units +.. _Cfunits: https://github.com/NCAS-CMS/cfunits +.. _Pint: https://github.com/hgrecco/pint +.. _Cfpint: https://github.com/SciTools/cfpint +.. _UDUNITS2: https://www.unidata.ucar.edu/software/udunits +.. _Cftime: https://github.com/unidata/cftime From 8040fea9cced538f0e2b60acc2077b46f1a9302f Mon Sep 17 00:00:00 2001 From: Martin Yeo Date: Mon, 13 Apr 2026 16:30:59 +0100 Subject: [PATCH 4/9] Fix doctrings. --- docs/src/index.rst | 2 +- lib/iris/common/mixin.py | 12 ++++++++---- lib/iris/cube.py | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/src/index.rst b/docs/src/index.rst index 5059bcd062..2098d2f2cb 100644 --- a/docs/src/index.rst +++ b/docs/src/index.rst @@ -8,7 +8,7 @@ Iris **A powerful, format-agnostic, community-driven Python package for analysing and visualising Earth science data.** -Iris implements a data model based on the `CF conventions `_ +Iris implements a data model based on the `CF conventions`_ giving you a powerful, format-agnostic interface for working with your data. It excels when working with multi-dimensional Earth Science data, where tabular representations become unwieldy and inefficient. diff --git a/lib/iris/common/mixin.py b/lib/iris/common/mixin.py index 856019a704..ffea5d43a2 100644 --- a/lib/iris/common/mixin.py +++ b/lib/iris/common/mixin.py @@ -14,7 +14,7 @@ from collections.abc import Mapping from functools import wraps -from typing import Any +from typing import TYPE_CHECKING, Any # Optional imports : actually only needed for type hints try: @@ -34,6 +34,9 @@ from .metadata import BaseMetadata from .units import make_unit +if TYPE_CHECKING: + from units import CfUnit, PintUnit + __all__ = ["CFVariableMixin", "LimitedAttributeDict"] @@ -229,11 +232,12 @@ def var_name(self, name: str | None) -> None: self._metadata_manager.var_name = name @property - def units(self) -> cf_units.Unit | cfpint.Unit: + def units(self) -> CfUnit | PintUnit: """The S.I. unit of the object. - If not ``None``, this is always an Iris Unit type - either :class:`CfUnit` or - :class:`cfpint.Unit`. See :func:`iris.common.units.make_unit`. + If not ``None``, this is always an Iris Unit type - either + :class:`~iris.common.units.CfUnit` or :class:`~iris.common.units.PintUnit`. + See :func:`iris.common.units.make_unit`. """ return self._metadata_manager.units diff --git a/lib/iris/cube.py b/lib/iris/cube.py index 44be3a63d7..819f3da157 100644 --- a/lib/iris/cube.py +++ b/lib/iris/cube.py @@ -1293,7 +1293,7 @@ def __init__( #: The "standard name" for the Cube's phenomenon. self.standard_name = standard_name - #: An instance of :class:`cf_units.Unit` describing the Cube's data. + #: An instance of :class:`~iris.common.units.CfUnit` or :class:`~iris.common.units.PintUnit` describing the Cube's data. self.units = units #: The "long name" for the Cube's phenomenon. From ae39fedfbf0b1dc795307655bf596aed72e357fb Mon Sep 17 00:00:00 2001 From: Martin Yeo Date: Mon, 13 Apr 2026 16:31:13 +0100 Subject: [PATCH 5/9] Missing sphinx-needs. --- lib/iris/common/units/__init__.py | 8 +++++++- lib/iris/experimental/units.py | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/iris/common/units/__init__.py b/lib/iris/common/units/__init__.py index b408ba4c9e..46cf61c449 100644 --- a/lib/iris/common/units/__init__.py +++ b/lib/iris/common/units/__init__.py @@ -2,7 +2,13 @@ # # This file is part of Iris and is released under the BSD license. # See LICENSE in the root of the repository for full licensing details. -"""Generic definition of units as used in Iris.""" +"""Generic definition of units as used in Iris. + +.. z_reference:: iris.common.units + :tags: topic_data_model + + API reference +""" from typing import Any diff --git a/lib/iris/experimental/units.py b/lib/iris/experimental/units.py index 952840e696..6487d73991 100644 --- a/lib/iris/experimental/units.py +++ b/lib/iris/experimental/units.py @@ -3,7 +3,13 @@ # This file is part of Iris and is released under the BSD license. # See LICENSE in the root of the repository for full licensing details. -"""Control for unit types.""" +"""Control for unit types. + +.. z_reference:: iris.experimental.units + :tags: topic_experimental;topic_data_model + + API reference +""" from contextlib import contextmanager import threading From c82e1a043558af52a475119b803ad661b51141fa Mon Sep 17 00:00:00 2001 From: Martin Yeo Date: Mon, 13 Apr 2026 16:43:41 +0100 Subject: [PATCH 6/9] Fix doctest. --- docs/src/user_manual/explanation/units.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/user_manual/explanation/units.rst b/docs/src/user_manual/explanation/units.rst index fde133fc21..e21d50fad6 100644 --- a/docs/src/user_manual/explanation/units.rst +++ b/docs/src/user_manual/explanation/units.rst @@ -49,7 +49,7 @@ Setting the :attr:`~iris.common.mixin.CFVariableMixin.units` on an object is simple - you provide a string and Iris will parse and store it appropriately: >>> my_cube.units = 'm/s' - >>> print(my_cube.units) + >>> print(my_cube.units, type(my_cube.units)) m/s >>> print(repr(my_cube.units)) Unit('m/s') @@ -83,9 +83,9 @@ You make this choice using the :data:`iris.experimental.units.USE_CFPINT` flag: >>> with USE_CFPINT.context(): ... my_cube.units = "m/s" - ... print(my_cube.units) + >>> print(my_cube.units) m s-1 - ... print(repr(my_cube.units)) + >>> print(repr(my_cube.units)) Unit('meter / second') In both cases Iris internals ensure the unit is CF-compliant. CF-compliance is From 0adeb5b9318877d1c25f5eef4ca95e697f81b99c Mon Sep 17 00:00:00 2001 From: Martin Yeo Date: Mon, 13 Apr 2026 16:44:09 +0100 Subject: [PATCH 7/9] Invalidate benchmark GHA cache. --- .github/workflows/benchmarks_validate.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmarks_validate.yml b/.github/workflows/benchmarks_validate.yml index 48f49bd0c4..2014608f8e 100644 --- a/.github/workflows/benchmarks_validate.yml +++ b/.github/workflows/benchmarks_validate.yml @@ -23,7 +23,7 @@ jobs: env: # Lets us manually bump the cache to rebuild - ENV_CACHE_BUILD: "1" + ENV_CACHE_BUILD: "0" steps: - name: Checkout repo From 7026830f76aa14a77853e9fb8ea54fd734983798 Mon Sep 17 00:00:00 2001 From: Martin Yeo Date: Mon, 13 Apr 2026 17:03:49 +0100 Subject: [PATCH 8/9] Fix doctest. --- docs/src/user_manual/explanation/units.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/user_manual/explanation/units.rst b/docs/src/user_manual/explanation/units.rst index e21d50fad6..ba5f35f9be 100644 --- a/docs/src/user_manual/explanation/units.rst +++ b/docs/src/user_manual/explanation/units.rst @@ -49,7 +49,7 @@ Setting the :attr:`~iris.common.mixin.CFVariableMixin.units` on an object is simple - you provide a string and Iris will parse and store it appropriately: >>> my_cube.units = 'm/s' - >>> print(my_cube.units, type(my_cube.units)) + >>> print(my_cube.units) m/s >>> print(repr(my_cube.units)) Unit('m/s') From 3c7c36e02f53ca6ea1caee3be3fec3a34eef7abc Mon Sep 17 00:00:00 2001 From: Martin Yeo Date: Mon, 13 Apr 2026 17:41:27 +0100 Subject: [PATCH 9/9] Revert "Invalidate benchmark GHA cache." This reverts commit 0adeb5b9318877d1c25f5eef4ca95e697f81b99c. --- .github/workflows/benchmarks_validate.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmarks_validate.yml b/.github/workflows/benchmarks_validate.yml index 2014608f8e..48f49bd0c4 100644 --- a/.github/workflows/benchmarks_validate.yml +++ b/.github/workflows/benchmarks_validate.yml @@ -23,7 +23,7 @@ jobs: env: # Lets us manually bump the cache to rebuild - ENV_CACHE_BUILD: "0" + ENV_CACHE_BUILD: "1" steps: - name: Checkout repo