Skip to content

Instantly share code, notes, and snippets.

@stephenworsley
Created September 25, 2023 12:39
Show Gist options
  • Save stephenworsley/7716fdba4cc634e73454462ad60b3f67 to your computer and use it in GitHub Desktop.
Save stephenworsley/7716fdba4cc634e73454462ad60b3f67 to your computer and use it in GitHub Desktop.
Warning Duplication
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "c884f567-84fb-4352-aacd-58f18bd0399c",
"metadata": {},
"outputs": [],
"source": [
"import iris"
]
},
{
"cell_type": "code",
"execution_count": 47,
"id": "6b1718fb-14a7-47b9-bf66-e094173ec19f",
"metadata": {},
"outputs": [],
"source": [
"import iris.tests\n",
"src_file = iris.tests.get_data_path((\"NetCDF\", \"regrid\", \"regrid_template_global_latlon.nc\"))"
]
},
{
"cell_type": "markdown",
"id": "69a563d6-b177-4875-9974-09c64df21128",
"metadata": {},
"source": [
"## Warning Duplication"
]
},
{
"cell_type": "markdown",
"id": "be65774a-c9c5-4804-a6c2-3983522e3570",
"metadata": {},
"source": [
"Some cubes give warnings when they load. This is expected behaviour."
]
},
{
"cell_type": "code",
"execution_count": 48,
"id": "25c67fb8-3bd2-4fd8-9371-65cafb2aeeb4",
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/1165832100.py:1: FutureWarning: Ignoring a datum in netCDF load for consistency with existing behaviour. In a future version of Iris, this datum will be applied. To apply the datum when loading, use the iris.FUTURE.datum_support flag.\n",
" iris.load_cube(src_file)\n"
]
},
{
"data": {
"text/html": [
"\n",
"<style>\n",
" a.iris {\n",
" text-decoration: none !important;\n",
" }\n",
" table.iris {\n",
" white-space: pre;\n",
" border: 1px solid;\n",
" border-color: #9c9c9c;\n",
" font-family: monaco, monospace;\n",
" }\n",
" th.iris {\n",
" background: #303f3f;\n",
" color: #e0e0e0;\n",
" border-left: 1px solid;\n",
" border-color: #9c9c9c;\n",
" font-size: 1.05em;\n",
" min-width: 50px;\n",
" max-width: 125px;\n",
" }\n",
" tr.iris :first-child {\n",
" border-right: 1px solid #9c9c9c !important;\n",
" }\n",
" td.iris-title {\n",
" background: #d5dcdf;\n",
" border-top: 1px solid #9c9c9c;\n",
" font-weight: bold;\n",
" }\n",
" .iris-word-cell {\n",
" text-align: left !important;\n",
" white-space: pre;\n",
" }\n",
" .iris-subheading-cell {\n",
" padding-left: 2em !important;\n",
" }\n",
" .iris-inclusion-cell {\n",
" padding-right: 1em !important;\n",
" }\n",
" .iris-panel-body {\n",
" padding-top: 0px;\n",
" }\n",
" .iris-panel-title {\n",
" padding-left: 3em;\n",
" }\n",
" .iris-panel-title {\n",
" margin-top: 7px;\n",
" }\n",
"</style>\n",
"<table class=\"iris\" id=\"140074740537376\">\n",
" <tr class=\"iris\">\n",
"<th class=\"iris iris-word-cell\">Sample Grid (unknown)</th>\n",
"<th class=\"iris iris-word-cell\">latitude</th>\n",
"<th class=\"iris iris-word-cell\">longitude</th>\n",
"</tr>\n",
" <tr class=\"iris\">\n",
"<td class=\"iris-word-cell iris-subheading-cell\">Shape</td>\n",
"<td class=\"iris iris-inclusion-cell\">180</td>\n",
"<td class=\"iris iris-inclusion-cell\">360</td>\n",
"</tr>\n",
" <tr class=\"iris\">\n",
" <td class=\"iris-title iris-word-cell\">Dimension coordinates</td>\n",
" <td class=\"iris-title\"></td>\n",
" <td class=\"iris-title\"></td>\n",
"</tr>\n",
"<tr class=\"iris\">\n",
" <td class=\"iris-word-cell iris-subheading-cell\">\tlatitude</td>\n",
" <td class=\"iris-inclusion-cell\">x</td>\n",
" <td class=\"iris-inclusion-cell\">-</td>\n",
"</tr>\n",
"<tr class=\"iris\">\n",
" <td class=\"iris-word-cell iris-subheading-cell\">\tlongitude</td>\n",
" <td class=\"iris-inclusion-cell\">-</td>\n",
" <td class=\"iris-inclusion-cell\">x</td>\n",
"</tr>\n",
"<tr class=\"iris\">\n",
" <td class=\"iris-title iris-word-cell\">Attributes</td>\n",
" <td class=\"iris-title\"></td>\n",
" <td class=\"iris-title\"></td>\n",
"</tr>\n",
"<tr class=\"iris\">\n",
" <td class=\"iris-word-cell iris-subheading-cell\">\tConventions</td>\n",
" <td class=\"iris-word-cell\" colspan=\"2\">&#x27;CF-1.7&#x27;</td>\n",
"</tr>\n",
"</table>\n",
" "
],
"text/plain": [
"<iris 'Cube' of sample_grid / (unknown) (latitude: 180; longitude: 360)>"
]
},
"execution_count": 48,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"iris.load_cube(src_file)"
]
},
{
"cell_type": "markdown",
"id": "1e2fcd00-3503-4ea4-a523-017dfe8ae8bb",
"metadata": {},
"source": [
"When multiple cubes are loaded, these warnings can end up duplicated. This is a bug."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "a487a2ef-043a-4266-aeb3-40c1f42d359b",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/2985628163.py:2: FutureWarning: Ignoring a datum in netCDF load for consistency with existing behaviour. In a future version of Iris, this datum will be applied. To apply the datum when loading, use the iris.FUTURE.datum_support flag.\n",
" iris.load_cube(src_file)\n",
"/var/tmp/ipykernel_60451/2985628163.py:2: FutureWarning: Ignoring a datum in netCDF load for consistency with existing behaviour. In a future version of Iris, this datum will be applied. To apply the datum when loading, use the iris.FUTURE.datum_support flag.\n",
" iris.load_cube(src_file)\n"
]
}
],
"source": [
"for _ in range(2):\n",
" iris.load_cube(src_file)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "a3db8712-e638-4411-9532-8b6f8675c9a7",
"metadata": {},
"outputs": [],
"source": [
"import warnings"
]
},
{
"cell_type": "markdown",
"id": "6f30ee28-5b08-446a-a221-91436ab109df",
"metadata": {},
"source": [
"Normally, warnings from the same source are grouped together and only raise one warning."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "34b46453-7a9d-4cdb-a518-0c17ec58527e",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/1364601749.py:2: UserWarning: warned once\n",
" warnings.warn(\"warned once\")\n"
]
}
],
"source": [
"for _ in range(2):\n",
" warnings.warn(\"warned once\")"
]
},
{
"cell_type": "markdown",
"id": "a1580ff2-aa3d-4d0c-a07c-32c83ce648be",
"metadata": {},
"source": [
"Even when `warnings` is explicitly set to raise one warning, they are still duplicated."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "48281a73-9d75-40da-9bfb-1d381a4ff285",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/3734422316.py:4: FutureWarning: Ignoring a datum in netCDF load for consistency with existing behaviour. In a future version of Iris, this datum will be applied. To apply the datum when loading, use the iris.FUTURE.datum_support flag.\n",
" iris.load_cube(src_file)\n",
"/var/tmp/ipykernel_60451/3734422316.py:4: FutureWarning: Ignoring a datum in netCDF load for consistency with existing behaviour. In a future version of Iris, this datum will be applied. To apply the datum when loading, use the iris.FUTURE.datum_support flag.\n",
" iris.load_cube(src_file)\n"
]
}
],
"source": [
"with warnings.catch_warnings():\n",
" warnings.simplefilter(\"once\")\n",
" for _ in range(2):\n",
" iris.load_cube(src_file)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "4c21c0f1-5b89-4845-8e6c-8c5af6074c73",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/262650537.py:4: UserWarning: warned once\n",
" warnings.warn(\"warned once\")\n"
]
}
],
"source": [
"with warnings.catch_warnings():\n",
" warnings.simplefilter(\"once\")\n",
" for _ in range(2):\n",
" warnings.warn(\"warned once\")"
]
},
{
"cell_type": "markdown",
"id": "e5e109f0-0aee-46b1-be8b-7c679ae0cc02",
"metadata": {},
"source": [
"### Replicating the Warning Duplication Bug\n",
"\n",
"We believe this is due to a known bug with the `warnings` module where warnings are repeated if a `catch_warnings` context manager is entered in between. See https://github.com/python/cpython/issues/73858"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "aca04b4b-aa90-49be-9e25-902aff38f40b",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/3930640416.py:2: UserWarning: warned twice\n",
" warnings.warn(\"warned twice\")\n",
"/var/tmp/ipykernel_60451/3930640416.py:2: UserWarning: warned twice\n",
" warnings.warn(\"warned twice\")\n"
]
}
],
"source": [
"for _ in range(2):\n",
" warnings.warn(\"warned twice\")\n",
" with warnings.catch_warnings():\n",
" pass"
]
},
{
"cell_type": "markdown",
"id": "0b9d46c6-8e04-48f9-9f63-892f052ce4d5",
"metadata": {},
"source": [
"This context manager can show up in many odd places: e.g. importing packages\n",
"\n",
"Notably, this happens with numpy and dask.array"
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "d69a0e52-b1b0-4748-b588-0efc46ebabb9",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/3985990569.py:2: UserWarning: import warning\n",
" warnings.warn(\"import warning\")\n"
]
}
],
"source": [
"for _ in range(3):\n",
" warnings.warn(\"import warning\")\n",
" import pandas"
]
},
{
"cell_type": "markdown",
"id": "cc9f21bd-8b90-4d26-90eb-ed6d718d24ba",
"metadata": {},
"source": [
"---\n",
"### Duplication Bug Workarounds\n",
"\n",
"One way we can solve this problem by using the lru_cache decorator."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "ea761aec-eaba-4275-be63-4b5350e89198",
"metadata": {},
"outputs": [],
"source": [
"from functools import lru_cache"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "9462cdd1-0a6a-45f3-9086-5067125e9f08",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"once\n"
]
}
],
"source": [
"@lru_cache(None)\n",
"def print_once(msg):\n",
" print(msg)\n",
"\n",
"for _ in range(2):\n",
" print_once(\"once\")"
]
},
{
"cell_type": "code",
"execution_count": 33,
"id": "b0d5f452-9de6-4c31-8eae-e42adbe60984",
"metadata": {},
"outputs": [],
"source": [
"print_once(\"once\")"
]
},
{
"cell_type": "code",
"execution_count": 34,
"id": "f0e5df9c-9807-4fd8-9089-f3ca2d184444",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/27440559.py:3: UserWarning: warned once\n",
" warnings.warn(msg)\n"
]
}
],
"source": [
"@lru_cache(None)\n",
"def warn_once(msg):\n",
" warnings.warn(msg)\n",
"\n",
"for _ in range(2):\n",
" warn_once(\"warned once\")\n",
" with warnings.catch_warnings():\n",
" pass"
]
},
{
"cell_type": "markdown",
"id": "641a6eb1-d68e-4c91-8f76-bbdcc95cf953",
"metadata": {},
"source": [
"However, this comes at the expense of flexibility in choosing the frequency of warnings."
]
},
{
"cell_type": "code",
"execution_count": 35,
"id": "45241b17-5c6e-4ca1-9842-38c732d40029",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/2874389630.py:3: UserWarning: normal warning\n",
" warnings.warn(\"normal warning\")\n",
"/var/tmp/ipykernel_60451/2874389630.py:4: UserWarning: normal warning\n",
" warnings.warn(\"normal warning\")\n"
]
}
],
"source": [
"with warnings.catch_warnings():\n",
" warnings.simplefilter(\"default\")\n",
" warnings.warn(\"normal warning\")\n",
" warnings.warn(\"normal warning\")"
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "fedc97d7-18ce-4426-8834-50ee3dae7b83",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/27440559.py:3: UserWarning: cached warning\n",
" warnings.warn(msg)\n"
]
}
],
"source": [
"with warnings.catch_warnings():\n",
" warnings.simplefilter(\"default\")\n",
" warn_once(\"cached warning\")\n",
" warn_once(\"cached warning\")"
]
},
{
"cell_type": "markdown",
"id": "a88c6320-810f-4956-a45c-63785d21effc",
"metadata": {},
"source": [
"With a bit of work it's possible to replicate the behaviour of \"default\" with a similar warning function."
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "275d29ae-cd81-4e2c-9798-d081d0e0f2a2",
"metadata": {},
"outputs": [],
"source": [
"import traceback"
]
},
{
"cell_type": "code",
"execution_count": 37,
"id": "f564eb4f-fda3-4ae7-a589-9ad4435179d2",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/933927709.py:13: UserWarning: cached warning\n",
" warn_default(\"cached warning\", 1)\n",
"/var/tmp/ipykernel_60451/933927709.py:14: UserWarning: cached warning\n",
" warn_default(\"cached warning\", 1)\n"
]
}
],
"source": [
"@lru_cache(None)\n",
"def warn_default_inner(msg, frame, stacklevel):\n",
" warnings.warn(msg, stacklevel=stacklevel)\n",
"\n",
"def warn_default(msg, stacklevel):\n",
" stacklevel += 1\n",
" stack = traceback.format_stack()\n",
" frame = stack[-stacklevel]\n",
" warn_default_inner(msg, frame, stacklevel + 1)\n",
"\n",
"with warnings.catch_warnings():\n",
" warnings.simplefilter(\"default\")\n",
" warn_default(\"cached warning\", 1)\n",
" warn_default(\"cached warning\", 1)"
]
},
{
"cell_type": "markdown",
"id": "80c20184-a83b-4c79-bc43-eb90a0e448cb",
"metadata": {},
"source": [
"This is flexible enough to allow stricter behaviour."
]
},
{
"cell_type": "code",
"execution_count": 38,
"id": "9b321ac7-63f4-41f9-89f0-93abf869b8a2",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/3150170836.py:3: UserWarning: cached warning\n",
" warn_default(\"cached warning\", 1)\n"
]
}
],
"source": [
"with warnings.catch_warnings():\n",
" warnings.simplefilter(\"once\")\n",
" warn_default(\"cached warning\", 1)\n",
" warn_default(\"cached warning\", 1)"
]
},
{
"cell_type": "markdown",
"id": "24ec60bc-2afc-4d50-854b-868e7d318dfb",
"metadata": {},
"source": [
"Though this is not flexible enough to fix bugs that force warnings to be stricter in a stricter context."
]
},
{
"cell_type": "code",
"execution_count": 39,
"id": "e1b6d33e-bdde-4ac2-94a8-927782aa2a82",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/1408376727.py:3: UserWarning: cached warning\n",
" warn_default(\"cached warning\", 1)\n",
"/var/tmp/ipykernel_60451/1408376727.py:6: UserWarning: cached warning\n",
" warn_default(\"cached warning\", 1)\n"
]
}
],
"source": [
"with warnings.catch_warnings():\n",
" warnings.simplefilter(\"once\")\n",
" warn_default(\"cached warning\", 1)\n",
" with warnings.catch_warnings():\n",
" pass\n",
" warn_default(\"cached warning\", 1)"
]
},
{
"cell_type": "markdown",
"id": "1802f155-4eb1-46db-8488-601d836d1c71",
"metadata": {},
"source": [
"This is not flexible enough to allow more lenient behaviour in more lenient contexts"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "bf5ba22e-e160-4e93-9b3b-5bf61d562226",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/3639898056.py:4: UserWarning: cached warning\n",
" warn_default(\"cached warning\", stacklevel=1)\n"
]
}
],
"source": [
"with warnings.catch_warnings():\n",
" warnings.simplefilter(\"always\")\n",
" for _ in range(2):\n",
" warn_default(\"cached warning\", stacklevel=1)"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "391ff050-e194-459c-85ac-54e7838ccd23",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/278831279.py:4: UserWarning: normal warning\n",
" warnings.warn(\"normal warning\", stacklevel=1)\n",
"/var/tmp/ipykernel_60451/278831279.py:4: UserWarning: normal warning\n",
" warnings.warn(\"normal warning\", stacklevel=1)\n"
]
}
],
"source": [
"with warnings.catch_warnings():\n",
" warnings.simplefilter(\"always\")\n",
" for _ in range(2):\n",
" warnings.warn(\"normal warning\", stacklevel=1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c30c7a26-6c87-4cc6-a951-17aa4c9f7672",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"id": "c9529521-e3e9-4d98-a723-1e05e1281aed",
"metadata": {},
"source": [
"---\n",
"### What exactly is default behaviour?\n",
"\n",
"Default behaviour calls one warning _per line_ that called the warning."
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "b7ff82c4-4c56-47a5-b838-19efcc0c61a3",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/263019615.py:3: UserWarning: warn twice\n",
" warnings.warn(\"warn twice\")\n",
"/var/tmp/ipykernel_60451/263019615.py:4: UserWarning: warn twice\n",
" warnings.warn(\"warn twice\")\n"
]
}
],
"source": [
"with warnings.catch_warnings():\n",
" warnings.simplefilter(\"default\")\n",
" warnings.warn(\"warn twice\")\n",
" warnings.warn(\"warn twice\")"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "a1b4af0f-9a16-4850-a5b4-107f27584374",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/3794237510.py:4: UserWarning: warn once\n",
" warnings.warn(\"warn once\")\n"
]
}
],
"source": [
"with warnings.catch_warnings():\n",
" warnings.simplefilter(\"default\")\n",
" for _ in range(2):\n",
" warnings.warn(\"warn once\")"
]
},
{
"cell_type": "markdown",
"id": "8f3cdc78-427d-4dc2-92dc-0f5bd2ce5b36",
"metadata": {},
"source": [
"Warnings have a stacklevel argument which allows the warning to be called lower down the call stack."
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "c71b4353-0485-4b56-b59d-492d7dfcd239",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/2884063885.py:4: UserWarning: warned by function\n",
" raise_warning()\n"
]
}
],
"source": [
"def raise_warning(level=2):\n",
" warnings.warn(\"warned by function\", stacklevel=level)\n",
"\n",
"raise_warning()"
]
},
{
"cell_type": "markdown",
"id": "1a05e011-f0cb-4b9b-a95d-fb3423194bc4",
"metadata": {},
"source": [
"What matters to default behaviour is if the line _where the warning is raised_ is the same."
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "cf7e7b6e-91ea-44aa-affb-c18a543b558b",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/922400754.py:3: UserWarning: warned by function\n",
" raise_warning()\n",
"/var/tmp/ipykernel_60451/922400754.py:4: UserWarning: warned by function\n",
" raise_warning()\n"
]
}
],
"source": [
"with warnings.catch_warnings():\n",
" warnings.simplefilter(\"default\")\n",
" raise_warning()\n",
" raise_warning()"
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "5ab696e0-7cc6-4b29-99da-30f4755bc365",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/2884063885.py:2: UserWarning: warned by function\n",
" warnings.warn(\"warned by function\", stacklevel=level)\n"
]
}
],
"source": [
"with warnings.catch_warnings():\n",
" warnings.simplefilter(\"default\")\n",
" raise_warning(1)\n",
" raise_warning(1)"
]
},
{
"cell_type": "markdown",
"id": "deba21d6-ecba-402a-81cd-9eabc0ffbd9b",
"metadata": {},
"source": [
"We can demonstrate that as long as the lines where the warning is raised are the same, it doesn't even matter if _subsequent_ frames of the stack differ, default behaviour will still only raise one warning."
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "2110ce85-57a6-4212-beb2-367ade1ffe85",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/3618860832.py:10: UserWarning: warned by case\n",
" raise_warning_case(case, 2)\n"
]
}
],
"source": [
"def raise_warning_case(case, level):\n",
" if case:\n",
" warnings.warn(\"warned by case\", stacklevel=level)\n",
" else:\n",
" warnings.warn(\"warned by case\", stacklevel=level)\n",
"\n",
"with warnings.catch_warnings():\n",
" warnings.simplefilter(\"default\")\n",
" for case in (True, False):\n",
" raise_warning_case(case, 2)"
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "6ed1794d-477d-4b49-b9eb-d9d56c8144b2",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/3618860832.py:3: UserWarning: warned by case\n",
" warnings.warn(\"warned by case\", stacklevel=level)\n",
"/var/tmp/ipykernel_60451/3618860832.py:5: UserWarning: warned by case\n",
" warnings.warn(\"warned by case\", stacklevel=level)\n"
]
}
],
"source": [
"with warnings.catch_warnings():\n",
" warnings.simplefilter(\"default\")\n",
" for case in (True, False):\n",
" raise_warning_case(case, 1)"
]
},
{
"cell_type": "markdown",
"id": "ab10ac0d-4e79-4a76-931d-c51a05b650b8",
"metadata": {},
"source": [
"This same propertyholds for the `warn_default` function we have created."
]
},
{
"cell_type": "code",
"execution_count": 40,
"id": "4f8327e1-53b7-4fd5-a13d-1a4235e2686c",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/55505891.py:10: UserWarning: warned by case default\n",
" raise_warning_case_default(case, 2)\n"
]
}
],
"source": [
"def raise_warning_case_default(case, level):\n",
" if case:\n",
" warn_default(\"warned by case default\", stacklevel=level)\n",
" else:\n",
" warn_default(\"warned by case default\", stacklevel=level)\n",
"\n",
"with warnings.catch_warnings():\n",
" warnings.simplefilter(\"default\")\n",
" for case in (True, False):\n",
" raise_warning_case_default(case, 2)"
]
},
{
"cell_type": "code",
"execution_count": 41,
"id": "48269ab0-5fc3-47c9-8486-bf5bc5c9a2aa",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/tmp/ipykernel_60451/55505891.py:3: UserWarning: warned by case default\n",
" warn_default(\"warned by case default\", stacklevel=level)\n",
"/var/tmp/ipykernel_60451/55505891.py:5: UserWarning: warned by case default\n",
" warn_default(\"warned by case default\", stacklevel=level)\n"
]
}
],
"source": [
"with warnings.catch_warnings():\n",
" warnings.simplefilter(\"default\")\n",
" for case in (True, False):\n",
" raise_warning_case_default(case, 1)"
]
},
{
"cell_type": "markdown",
"id": "9a1a13d7-10f2-491b-894d-75f8cb88a898",
"metadata": {},
"source": [
"---\n",
"### Conclusion\n",
"\n",
"There are two alternate functions we could use to replace the regular warning call; one where we force \"default\" behaviour and one where we force \"once\" behaviour. The table below describes how flexible each solution would be at handling other contexts.\n",
"\n",
"|Method|Handles \"once\"|Handles \"default\"|Handles \"always\"\n",
"|:---|:---|:---|:---|\n",
"|Regular|sometimes|sometimes|always|\n",
"|Forced default|sometimes|always|never|\n",
"|Forced once|always|never|never|\n",
"\n",
"### Actions\n",
"\n",
"- Replace calls in iris to `warnings.catch_warnings()`.\n",
"- Replace calls to `warnings.warn` with more robust functions (decision needed)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "420b225f-6364-4f97-bc1e-ef4e56cb85ef",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.17"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment