|
| 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