From 82fe7b335f5f66ed734a054ce7c6caba2c2f7db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Lapeyre?= Date: Mon, 9 Mar 2020 15:10:35 +0100 Subject: [PATCH 1/5] Raise appropriate exceptions in filterwarnings() and simplefilter() --- Lib/test/test_warnings/__init__.py | 23 +++++++++++++ Lib/warnings.py | 32 ++++++++++++------- .../2020-03-09-15-08-29.bpo-39912.xPOBBY.rst | 3 ++ 3 files changed, 46 insertions(+), 12 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-03-09-15-08-29.bpo-39912.xPOBBY.rst diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py index 268ecb03f4dc65..cd606457c80bbe 100644 --- a/Lib/test/test_warnings/__init__.py +++ b/Lib/test/test_warnings/__init__.py @@ -367,6 +367,29 @@ def test_append_duplicate(self): "appended duplicate changed order of filters" ) + def test_argument_validation(self): + with self.assertRaises(ValueError): + self.module.filterwarnings(action='foo') + with self.assertRaises(TypeError): + self.module.filterwarnings('ignore', message=0) + with self.assertRaises(TypeError): + self.module.filterwarnings('ignore', category=0) + with self.assertRaises(TypeError): + self.module.filterwarnings('ignore', category=int) + with self.assertRaises(TypeError): + self.module.filterwarnings('ignore', module=0) + with self.assertRaises(TypeError): + self.module.filterwarnings('ignore', lineno=int) + with self.assertRaises(ValueError): + self.module.filterwarnings('ignore', lineno=-1) + with self.assertRaises(ValueError): + self.module.simplefilter(action='foo') + with self.assertRaises(TypeError): + self.module.simplefilter('ignore', lineno=int) + with self.assertRaises(ValueError): + self.module.simplefilter('ignore', lineno=-1) + + class CFilterTests(FilterTests, unittest.TestCase): module = c_warnings diff --git a/Lib/warnings.py b/Lib/warnings.py index 691ccddfa450ad..f234fc58388362 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -139,14 +139,20 @@ def filterwarnings(action, message="", category=Warning, module="", lineno=0, 'lineno' -- an integer line number, 0 matches all warnings 'append' -- if true, append to the list of filters """ - assert action in ("error", "ignore", "always", "default", "module", - "once"), "invalid action: %r" % (action,) - assert isinstance(message, str), "message must be a string" - assert isinstance(category, type), "category must be a class" - assert issubclass(category, Warning), "category must be a Warning subclass" - assert isinstance(module, str), "module must be a string" - assert isinstance(lineno, int) and lineno >= 0, \ - "lineno must be an int >= 0" + if action not in ("error", "ignore", "always", "default", "module", "once"): + raise ValueError(f"invalid action: {action!r}") + if not isinstance(message, str): + raise TypeError("message must be a string") + if not isinstance(category, type): + raise TypeError("category must be a class") + if not issubclass(category, Warning): + raise TypeError("category must be a Warning subclass") + if not isinstance(module, str): + raise TypeError("module must be a string") + if not isinstance(lineno, int): + raise TypeError("lineno must be an int") + if lineno < 0: + raise ValueError("lineno must be an int >= 0") if message or module: import re @@ -172,10 +178,12 @@ def simplefilter(action, category=Warning, lineno=0, append=False): 'lineno' -- an integer line number, 0 matches all warnings 'append' -- if true, append to the list of filters """ - assert action in ("error", "ignore", "always", "default", "module", - "once"), "invalid action: %r" % (action,) - assert isinstance(lineno, int) and lineno >= 0, \ - "lineno must be an int >= 0" + if action not in ("error", "ignore", "always", "default", "module", "once"): + raise ValueError(f"invalid action: {action!r}") + if not isinstance(lineno, int): + raise TypeError("lineno must be an int") + if lineno < 0: + raise ValueError("lineno must be an int >= 0") _add_filter(action, None, category, None, lineno, append=append) def _add_filter(*item, append): diff --git a/Misc/NEWS.d/next/Library/2020-03-09-15-08-29.bpo-39912.xPOBBY.rst b/Misc/NEWS.d/next/Library/2020-03-09-15-08-29.bpo-39912.xPOBBY.rst new file mode 100644 index 00000000000000..fb8579725a2d7d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-03-09-15-08-29.bpo-39912.xPOBBY.rst @@ -0,0 +1,3 @@ +:func:`warnings.filterwarnings()` and :func:`warnings.simplefilter()` now raise +appropriate exceptions instead of ``AssertionError``. Patch contributed by +Rémi Lapeyre. From 22e475cd6db596cfc28a6a8c779018c18a5822cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Lapeyre?= Date: Wed, 8 Apr 2020 15:26:45 +0200 Subject: [PATCH 2/5] Merge category tests Co-Authored-By: Serhiy Storchaka --- Lib/warnings.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Lib/warnings.py b/Lib/warnings.py index f234fc58388362..99037fc967bad6 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -143,9 +143,7 @@ def filterwarnings(action, message="", category=Warning, module="", lineno=0, raise ValueError(f"invalid action: {action!r}") if not isinstance(message, str): raise TypeError("message must be a string") - if not isinstance(category, type): - raise TypeError("category must be a class") - if not issubclass(category, Warning): + if not isinstance(category, type) or not issubclass(category, Warning): raise TypeError("category must be a Warning subclass") if not isinstance(module, str): raise TypeError("module must be a string") From f42eea5db20d6ce4da807fd19a3b7ac4513adc04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Lapeyre?= Date: Wed, 8 Apr 2020 15:26:57 +0200 Subject: [PATCH 3/5] Improve exception message Co-Authored-By: Serhiy Storchaka --- Lib/warnings.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Lib/warnings.py b/Lib/warnings.py index 99037fc967bad6..0487342a9136af 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -147,10 +147,8 @@ def filterwarnings(action, message="", category=Warning, module="", lineno=0, raise TypeError("category must be a Warning subclass") if not isinstance(module, str): raise TypeError("module must be a string") - if not isinstance(lineno, int): - raise TypeError("lineno must be an int") - if lineno < 0: - raise ValueError("lineno must be an int >= 0") + if not isinstance(lineno, int) or lineno < 0: + raise ValueError("lineno must be a non-negative integer") if message or module: import re From c90c08eb1f709582f3c60a546e36a57d964cbd61 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 1 Dec 2023 12:48:05 +0200 Subject: [PATCH 4/5] Apply suggestions from code review --- Lib/warnings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/warnings.py b/Lib/warnings.py index 63f4a62eb676af..708f48c1ac8d97 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -139,7 +139,7 @@ def filterwarnings(action, message="", category=Warning, module="", lineno=0, 'lineno' -- an integer line number, 0 matches all warnings 'append' -- if true, append to the list of filters """ - if action not in ("error", "ignore", "always", "default", "module", "once"): + if action not in {"error", "ignore", "always", "default", "module", "once"}: raise ValueError(f"invalid action: {action!r}") if not isinstance(message, str): raise TypeError("message must be a string") @@ -174,7 +174,7 @@ def simplefilter(action, category=Warning, lineno=0, append=False): 'lineno' -- an integer line number, 0 matches all warnings 'append' -- if true, append to the list of filters """ - if action not in ("error", "ignore", "always", "default", "module", "once"): + if action not in {"error", "ignore", "always", "default", "module", "once"}: raise ValueError(f"invalid action: {action!r}") if not isinstance(lineno, int): raise TypeError("lineno must be an int") From 5a8a25419861e348977035cf49d8bb4e42644bc2 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 1 Dec 2023 12:51:05 +0200 Subject: [PATCH 5/5] Update Lib/warnings.py --- Lib/warnings.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Lib/warnings.py b/Lib/warnings.py index 708f48c1ac8d97..b8ff078569d2ce 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -147,8 +147,10 @@ def filterwarnings(action, message="", category=Warning, module="", lineno=0, raise TypeError("category must be a Warning subclass") if not isinstance(module, str): raise TypeError("module must be a string") - if not isinstance(lineno, int) or lineno < 0: - raise ValueError("lineno must be a non-negative integer") + if not isinstance(lineno, int): + raise TypeError("lineno must be an int") + if lineno < 0: + raise ValueError("lineno must be an int >= 0") if message or module: import re