|  | 
|  | 1 | +.. _filtering-warnings: | 
|  | 2 | + | 
|  | 3 | +================== | 
|  | 4 | +Filtering Warnings | 
|  | 5 | +================== | 
|  | 6 | + | 
|  | 7 | +Since Iris cannot predict your specific needs, it by default raises Warnings | 
|  | 8 | +for anything that might be a problem for **any** user, and is designed to work with | 
|  | 9 | +you to ``ignore`` Warnings which you do not find helpful. | 
|  | 10 | + | 
|  | 11 | +.. testsetup:: filtering_warnings | 
|  | 12 | + | 
|  | 13 | +    from pathlib import Path | 
|  | 14 | +    import sys | 
|  | 15 | +    import warnings | 
|  | 16 | + | 
|  | 17 | +    import iris | 
|  | 18 | +    import iris.coord_systems | 
|  | 19 | +    import iris.exceptions | 
|  | 20 | + | 
|  | 21 | +    # Hack to ensure doctests actually see Warnings that are raised, and that | 
|  | 22 | +    #  they have a relative path (so a test pass is not machine-dependent). | 
|  | 23 | +    warnings.filterwarnings("default") | 
|  | 24 | +    IRIS_FILE = Path(iris.__file__) | 
|  | 25 | +    def custom_warn(message, category, filename, lineno, file=None, line=None): | 
|  | 26 | +        filepath = Path(filename) | 
|  | 27 | +        filename = str(filepath.relative_to(IRIS_FILE.parents[1])) | 
|  | 28 | +        sys.stdout.write(warnings.formatwarning(message, category, filename, lineno)) | 
|  | 29 | +    warnings.showwarning = custom_warn | 
|  | 30 | + | 
|  | 31 | +    geog_cs_globe = iris.coord_systems.GeogCS(6400000) | 
|  | 32 | +    orthographic_coord_system = iris.coord_systems.Orthographic( | 
|  | 33 | +        longitude_of_projection_origin=0, | 
|  | 34 | +        latitude_of_projection_origin=0, | 
|  | 35 | +        ellipsoid=geog_cs_globe, | 
|  | 36 | +    ) | 
|  | 37 | + | 
|  | 38 | + | 
|  | 39 | +    def my_operation(): | 
|  | 40 | +        geog_cs_globe.inverse_flattening = 0.1 | 
|  | 41 | +        _ = orthographic_coord_system.as_cartopy_crs() | 
|  | 42 | + | 
|  | 43 | +Here is a hypothetical operation - ``my_operation()`` - which raises two | 
|  | 44 | +Warnings: | 
|  | 45 | + | 
|  | 46 | +.. doctest:: filtering_warnings | 
|  | 47 | + | 
|  | 48 | +    >>> my_operation() | 
|  | 49 | +    ... | 
|  | 50 | +    iris/coord_systems.py:454: IrisUserWarning: Setting inverse_flattening does not affect other properties of the GeogCS object. To change other properties set them explicitly or create a new GeogCS instance. | 
|  | 51 | +      warnings.warn(wmsg, category=iris.exceptions.IrisUserWarning) | 
|  | 52 | +    iris/coord_systems.py:821: IrisDefaultingWarning: Discarding false_easting and false_northing that are not used by Cartopy. | 
|  | 53 | +      warnings.warn( | 
|  | 54 | + | 
|  | 55 | +Warnings can be suppressed using the Python warnings filter with the ``ignore`` | 
|  | 56 | +action. Detailed information is available in the Python documentation: | 
|  | 57 | +:external+python:mod:`warnings`. | 
|  | 58 | + | 
|  | 59 | +The key points are: | 
|  | 60 | + | 
|  | 61 | +- :ref:`When<warning-filter-application>`: a warnings filter can be applied | 
|  | 62 | +  either from the command line or from within Python. | 
|  | 63 | +- :ref:`What<warning-filter-specificity>`: a warnings filter accepts | 
|  | 64 | +  various arguments to specify which Warnings are being filtered. Both broad | 
|  | 65 | +  and narrow filters are possible. | 
|  | 66 | + | 
|  | 67 | +.. _warning-filter-application: | 
|  | 68 | + | 
|  | 69 | +**When** a Warnings Filter can be Applied | 
|  | 70 | +----------------------------------------- | 
|  | 71 | + | 
|  | 72 | +- **Command line:** setting the :external+python:envvar:`PYTHONWARNINGS` | 
|  | 73 | +  environment variable. | 
|  | 74 | +- **Command line:** the `python -W <https://docs.python.org/3/using/cmdline.html#cmdoption-W>`_ | 
|  | 75 | +  command line argument. | 
|  | 76 | +- **Within Python:** use :func:`warnings.filterwarnings` . | 
|  | 77 | + | 
|  | 78 | +The :ref:`warning-filter-specificity` section demonstrates using | 
|  | 79 | +:func:`warnings.filterwarnings`, and shows the equivalent **command line** | 
|  | 80 | +approaches. | 
|  | 81 | + | 
|  | 82 | + | 
|  | 83 | +.. _warning-filter-specificity: | 
|  | 84 | + | 
|  | 85 | +**What** Warnings will be Filtered | 
|  | 86 | +---------------------------------- | 
|  | 87 | + | 
|  | 88 | +.. note:: | 
|  | 89 | + | 
|  | 90 | +    For all of these examples we are using the | 
|  | 91 | +    :class:`~warnings.catch_warnings` context manager to ensure any changes to | 
|  | 92 | +    settings are temporary. | 
|  | 93 | + | 
|  | 94 | +    This should always work fine for the ``ignore`` | 
|  | 95 | +    warning filter action, but note that some of the other actions | 
|  | 96 | +    may not behave correctly with all Iris operations, as | 
|  | 97 | +    :class:`~warnings.catch_warnings` is not thread-safe (e.g. using the | 
|  | 98 | +    ``once`` action may cause 1 warning per chunk of lazy data). | 
|  | 99 | + | 
|  | 100 | +Specific Warnings | 
|  | 101 | +~~~~~~~~~~~~~~~~~ | 
|  | 102 | + | 
|  | 103 | +**When you do not want a specific warning, but still want all others.** | 
|  | 104 | + | 
|  | 105 | +You can target specific Warning messages, e.g. | 
|  | 106 | + | 
|  | 107 | +.. doctest:: filtering_warnings | 
|  | 108 | + | 
|  | 109 | +    >>> with warnings.catch_warnings(): | 
|  | 110 | +    ...     warnings.filterwarnings("ignore", message="Discarding false_easting") | 
|  | 111 | +    ...     my_operation() | 
|  | 112 | +    ... | 
|  | 113 | +    iris/coord_systems.py:454: IrisUserWarning: Setting inverse_flattening does not affect other properties of the GeogCS object. To change other properties set them explicitly or create a new GeogCS instance. | 
|  | 114 | +      warnings.warn(wmsg, category=iris.exceptions.IrisUserWarning) | 
|  | 115 | + | 
|  | 116 | +:: | 
|  | 117 | + | 
|  | 118 | +    python -W ignore:"Discarding false_easting" | 
|  | 119 | +    export PYTHONWARNINGS=ignore:"Discarding false_easting" | 
|  | 120 | + | 
|  | 121 | +---- | 
|  | 122 | + | 
|  | 123 | +Or you can target Warnings raised by specific lines of specific modules, e.g. | 
|  | 124 | + | 
|  | 125 | +.. doctest:: filtering_warnings | 
|  | 126 | + | 
|  | 127 | +    >>> with warnings.catch_warnings(): | 
|  | 128 | +    ...     warnings.filterwarnings("ignore", module="iris.coord_systems", lineno=454) | 
|  | 129 | +    ...     my_operation() | 
|  | 130 | +    ... | 
|  | 131 | +    iris/coord_systems.py:821: IrisDefaultingWarning: Discarding false_easting and false_northing that are not used by Cartopy. | 
|  | 132 | +      warnings.warn( | 
|  | 133 | + | 
|  | 134 | +:: | 
|  | 135 | + | 
|  | 136 | +    python -W ignore:::iris.coord_systems:454 | 
|  | 137 | +    export PYTHONWARNINGS=ignore:::iris.coord_systems:454 | 
|  | 138 | + | 
|  | 139 | +Warnings from a Common Source | 
|  | 140 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
|  | 141 | + | 
|  | 142 | +**When you do not want ANY warnings raised by a module, or collection of | 
|  | 143 | +modules.** | 
|  | 144 | + | 
|  | 145 | +E.g. filtering the ``coord_systems`` module: | 
|  | 146 | + | 
|  | 147 | +.. doctest:: filtering_warnings | 
|  | 148 | + | 
|  | 149 | +    >>> with warnings.catch_warnings(): | 
|  | 150 | +    ...     warnings.filterwarnings("ignore", module="iris.coord_systems") | 
|  | 151 | +    ...     my_operation() | 
|  | 152 | + | 
|  | 153 | +:: | 
|  | 154 | + | 
|  | 155 | +    python -W ignore:::iris.coord_systems | 
|  | 156 | +    export PYTHONWARNINGS=ignore:::iris.coord_systems | 
|  | 157 | + | 
|  | 158 | +---- | 
|  | 159 | + | 
|  | 160 | +If using :func:`warnings.filterwarnings` , you can also use partial | 
|  | 161 | +definitions. The below example will ``ignore`` all Warnings from ``iris`` as a | 
|  | 162 | +whole. | 
|  | 163 | + | 
|  | 164 | +.. doctest:: filtering_warnings | 
|  | 165 | + | 
|  | 166 | +    >>> with warnings.catch_warnings(): | 
|  | 167 | +    ...     warnings.filterwarnings("ignore", module="iris") | 
|  | 168 | +    ...     my_operation() | 
|  | 169 | + | 
|  | 170 | +The above 'partial' filter is not available with the command line approaches. | 
|  | 171 | + | 
|  | 172 | +Warnings of a Common Type | 
|  | 173 | +~~~~~~~~~~~~~~~~~~~~~~~~~ | 
|  | 174 | + | 
|  | 175 | +**When you do not want any Warnings of the same nature, from anywhere in the | 
|  | 176 | +code you are calling.** | 
|  | 177 | + | 
|  | 178 | +The below example will ``ignore`` any | 
|  | 179 | +:class:`~iris.exceptions.IrisDefaultingWarning` that gets raised by *any* | 
|  | 180 | +module during execution: | 
|  | 181 | + | 
|  | 182 | +.. doctest:: filtering_warnings | 
|  | 183 | + | 
|  | 184 | +    >>> with warnings.catch_warnings(): | 
|  | 185 | +    ...     warnings.filterwarnings( | 
|  | 186 | +    ...         "ignore", | 
|  | 187 | +    ...         category=iris.exceptions.IrisDefaultingWarning | 
|  | 188 | +    ...     ) | 
|  | 189 | +    ...     my_operation() | 
|  | 190 | +    ... | 
|  | 191 | +    iris/coord_systems.py:454: IrisUserWarning: Setting inverse_flattening does not affect other properties of the GeogCS object. To change other properties set them explicitly or create a new GeogCS instance. | 
|  | 192 | +      warnings.warn(wmsg, category=iris.exceptions.IrisUserWarning) | 
|  | 193 | + | 
|  | 194 | +---- | 
|  | 195 | + | 
|  | 196 | +Using :class:`~iris.exceptions.IrisUserWarning` in the filter will ``ignore`` | 
|  | 197 | +both Warnings, since :class:`~iris.exceptions.IrisDefaultingWarning` subclasses | 
|  | 198 | +:class:`~iris.exceptions.IrisUserWarning` : | 
|  | 199 | + | 
|  | 200 | +.. doctest:: filtering_warnings | 
|  | 201 | + | 
|  | 202 | +    >>> with warnings.catch_warnings(): | 
|  | 203 | +    ...     warnings.filterwarnings( | 
|  | 204 | +    ...         "ignore", | 
|  | 205 | +    ...         category=iris.exceptions.IrisUserWarning | 
|  | 206 | +    ...     ) | 
|  | 207 | +    ...     my_operation() | 
|  | 208 | + | 
|  | 209 | +---- | 
|  | 210 | + | 
|  | 211 | +The command line approaches can only handle the built-in Warning | 
|  | 212 | +categories (`cpython#66733`_):: | 
|  | 213 | + | 
|  | 214 | +    python -W ignore::UserWarning | 
|  | 215 | +    export PYTHONWARNINGS=ignore::UserWarning | 
|  | 216 | + | 
|  | 217 | +---- | 
|  | 218 | + | 
|  | 219 | +There are several built-in Python warning categories that can be used here | 
|  | 220 | +(:class:`DeprecationWarning` being a popular example, see | 
|  | 221 | +:external+python:mod:`warnings` for more). Since Iris has | 
|  | 222 | +so many different warnings that might be raised, Iris subclasses | 
|  | 223 | +:class:`UserWarning` to :class:`~iris.exceptions.IrisUserWarning`, which itself | 
|  | 224 | +has **many** specialised subclasses. These subclasses exist to give you more | 
|  | 225 | +granularity in your warning filtering; you can see the full list by | 
|  | 226 | +searching the :mod:`iris.exceptions` page for ``warning`` . | 
|  | 227 | + | 
|  | 228 | +.. attention:: | 
|  | 229 | + | 
|  | 230 | +    If you have ideas for adding/altering Iris' warning categories, please | 
|  | 231 | +    :ref:`get in touch<development_where_to_start>`! The categories exist to | 
|  | 232 | +    make your life easier, and it is simple to make modifications. | 
|  | 233 | + | 
|  | 234 | + | 
|  | 235 | +More Detail | 
|  | 236 | +----------- | 
|  | 237 | + | 
|  | 238 | +Different people use Iris for very different purposes, from quick file | 
|  | 239 | +visualisation to extract-transform-load to statistical analysis. These | 
|  | 240 | +contrasting priorities mean disagreement on which Iris problems can be ignored | 
|  | 241 | +and which are critically important. | 
|  | 242 | + | 
|  | 243 | +For problems that prevent Iris functioning: **Concrete Exceptions** are raised, which | 
|  | 244 | +stop code from running any further - no debate here. For less catastrophic | 
|  | 245 | +problems: **Warnings** are raised, | 
|  | 246 | +which notify you (in ``stderr``) but allow code to continue running. The Warnings are | 
|  | 247 | +there because Iris may **OR may not** function in the way you expect, | 
|  | 248 | +depending on what you need - e.g. a problem might prevent data being saved to | 
|  | 249 | +NetCDF, but statistical analysis will still work fine. | 
|  | 250 | + | 
|  | 251 | +Examples of Iris Warnings | 
|  | 252 | +~~~~~~~~~~~~~~~~~~~~~~~~~ | 
|  | 253 | + | 
|  | 254 | +- If you attempt to plot un-bounded point data as a ``pcolormesh``: Iris will | 
|  | 255 | +  guess appropriate bounds around each point so that quadrilaterals can be | 
|  | 256 | +  plotted. This permanently modifies the relevant coordinates, so the you are | 
|  | 257 | +  warned in case downstream operations assume un-bounded coordinates. | 
|  | 258 | +- If you load a NetCDF file where a CF variable references another variable - | 
|  | 259 | +  e.g. ``my_var:coordinates = "depth_var" ;`` - but the referenced variable | 
|  | 260 | +  (``depth_var``) is not in the file: Iris will still construct | 
|  | 261 | +  its data model, but without this reference relationship. You are warned since | 
|  | 262 | +  the file includes an error and the loaded result might therefore not be as | 
|  | 263 | +  expected. | 
|  | 264 | + | 
|  | 265 | + | 
|  | 266 | +.. testcleanup:: filtering_warnings | 
|  | 267 | + | 
|  | 268 | +    warnings.filterwarnings("ignore") | 
|  | 269 | + | 
|  | 270 | + | 
|  | 271 | +.. _cpython#66733: https://github.com/python/cpython/issues/66733 | 
0 commit comments