From 4edb4c71c0ef7de77f7807396e99b6c9409ff9f8 Mon Sep 17 00:00:00 2001 From: hasrat17 Date: Sat, 5 Jul 2025 03:23:44 +0530 Subject: [PATCH 1/5] Fix: Add type check for category in warning.simplefilter & warning.filterwarnings --- Lib/_py_warnings.py | 13 +++++++++++-- Misc/ACKS | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Lib/_py_warnings.py b/Lib/_py_warnings.py index cbaa94458629ac..e62197898661d5 100644 --- a/Lib/_py_warnings.py +++ b/Lib/_py_warnings.py @@ -250,6 +250,11 @@ def _formatwarnmsg(msg): msg.filename, msg.lineno, msg.line) return _wm._formatwarnmsg_impl(msg) +def _valid_warning_category(category): + """Return True if category is a Warning subclass or tuple of such.""" + if isinstance(category, tuple): + return all(isinstance(c, type) and issubclass(c, Warning) for c in category) + return isinstance(category, type) and issubclass(category, Warning) def filterwarnings(action, message="", category=Warning, module="", lineno=0, append=False): @@ -267,8 +272,9 @@ 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) or not issubclass(category, Warning): - raise TypeError("category must be a Warning subclass") + if not _valid_warning_category(category): + raise TypeError("category must be a Warning subclass, " + "not '{:s}'".format(type(category).__name__)) if not isinstance(module, str): raise TypeError("module must be a string") if not isinstance(lineno, int): @@ -303,6 +309,9 @@ def simplefilter(action, category=Warning, lineno=0, append=False): """ if action not in {"error", "ignore", "always", "all", "default", "module", "once"}: raise ValueError(f"invalid action: {action!r}") + if not _valid_warning_category(category): + raise TypeError("category must be a Warning subclass, " + "not '{:s}'".format(type(category).__name__)) if not isinstance(lineno, int): raise TypeError("lineno must be an int") if lineno < 0: diff --git a/Misc/ACKS b/Misc/ACKS index d1490e1e46ccfd..e2351139a9e7a2 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -2149,5 +2149,6 @@ Jelle Zijlstra Gennadiy Zlobin Doug Zongker Peter Åstrand +Hasrat Ali Arzoo (Entries should be added in rough alphabetical order by last names) From 022e4b350c94b0bee18ce29a35c75ad5c3d40556 Mon Sep 17 00:00:00 2001 From: hasrat17 Date: Thu, 10 Jul 2025 20:38:57 +0530 Subject: [PATCH 2/5] Added testcase and refactored warning logic for debug --- Lib/_py_warnings.py | 14 +++++++--- Lib/test/test_warnings/__init__.py | 27 +++++++++++++++++++ Misc/ACKS | 2 +- ...-07-10-19-28-11.gh-issue-125893.lD8Nyd.rst | 2 ++ 4 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2025-07-10-19-28-11.gh-issue-125893.lD8Nyd.rst diff --git a/Lib/_py_warnings.py b/Lib/_py_warnings.py index e62197898661d5..cfe8ab88d8a5e6 100644 --- a/Lib/_py_warnings.py +++ b/Lib/_py_warnings.py @@ -251,10 +251,18 @@ def _formatwarnmsg(msg): return _wm._formatwarnmsg_impl(msg) def _valid_warning_category(category): - """Return True if category is a Warning subclass or tuple of such.""" + """ + Return True if category is a Warning subclass or tuple of such. + Always perform class checks; only perform tuple iteration in debug mode. + """ + if isinstance(category, type) and issubclass(category, Warning): + return True if isinstance(category, tuple): - return all(isinstance(c, type) and issubclass(c, Warning) for c in category) - return isinstance(category, type) and issubclass(category, Warning) + if __debug__: + return all(isinstance(c, type) and issubclass(c, Warning) + for c in category) + return True + return False def filterwarnings(action, message="", category=Warning, module="", lineno=0, append=False): diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py index 5c3b1250ceb045..cd63d0500e34ef 100644 --- a/Lib/test/test_warnings/__init__.py +++ b/Lib/test/test_warnings/__init__.py @@ -398,6 +398,33 @@ def test_argument_validation(self): with self.assertRaises(ValueError): self.module.simplefilter('ignore', lineno=-1) + def test_invalid_category_types(self): + with self.assertRaises(TypeError): + self.module.filterwarnings("ignore", category="notawarning") + with self.assertRaises(TypeError): + self.module.filterwarnings("ignore", category=123) + with self.assertRaises(TypeError): + self.module.filterwarnings("ignore", category=17.02) + with self.assertRaises(TypeError): + self.module.filterwarnings("ignore", category=True) + with self.assertRaises(TypeError): + self.module.filterwarnings( + "ignore", category=(UserWarning, 17) + ) + + with self.assertRaises(TypeError): + self.module.simplefilter("ignore", category="notawarning") + with self.assertRaises(TypeError): + self.module.simplefilter("ignore", category=123) + with self.assertRaises(TypeError): + self.module.filterwarnings("ignore", category=17.02) + with self.assertRaises(TypeError): + self.module.filterwarnings("ignore", category=True) + with self.assertRaises(TypeError): + self.module.simplefilter( + "ignore", category=(UserWarning, 'abc') + ) + def test_catchwarnings_with_simplefilter_ignore(self): with self.module.catch_warnings(module=self.module): self.module.resetwarnings() diff --git a/Misc/ACKS b/Misc/ACKS index e2351139a9e7a2..4e19115bb81c88 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -74,6 +74,7 @@ Emmanuel Arias Alicia Arlen Jeffrey Armstrong Justin Turner Arthur +Hasrat Ali Arzoo Jason Asbahr David Ascher Ammar Askar @@ -2149,6 +2150,5 @@ Jelle Zijlstra Gennadiy Zlobin Doug Zongker Peter Åstrand -Hasrat Ali Arzoo (Entries should be added in rough alphabetical order by last names) diff --git a/Misc/NEWS.d/next/Windows/2025-07-10-19-28-11.gh-issue-125893.lD8Nyd.rst b/Misc/NEWS.d/next/Windows/2025-07-10-19-28-11.gh-issue-125893.lD8Nyd.rst new file mode 100644 index 00000000000000..37fd0d1e194ae3 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2025-07-10-19-28-11.gh-issue-125893.lD8Nyd.rst @@ -0,0 +1,2 @@ +Added validation for the ``category`` argument in +``warnings.filterwarnings()`` and ``warnings.simplefilter()`` From e8e6b31cf35e57dc6f5f99ad26e83600ff34fa39 Mon Sep 17 00:00:00 2001 From: Hasrat <56307533+hasrat17@users.noreply.github.com> Date: Thu, 14 Aug 2025 00:32:56 +0530 Subject: [PATCH 3/5] Update Misc/NEWS.d/next/Windows/2025-07-10-19-28-11.gh-issue-125893.lD8Nyd.rst Co-authored-by: Peter Bierma --- .../next/Windows/2025-07-10-19-28-11.gh-issue-125893.lD8Nyd.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Windows/2025-07-10-19-28-11.gh-issue-125893.lD8Nyd.rst b/Misc/NEWS.d/next/Windows/2025-07-10-19-28-11.gh-issue-125893.lD8Nyd.rst index 37fd0d1e194ae3..3c1213ec479f72 100644 --- a/Misc/NEWS.d/next/Windows/2025-07-10-19-28-11.gh-issue-125893.lD8Nyd.rst +++ b/Misc/NEWS.d/next/Windows/2025-07-10-19-28-11.gh-issue-125893.lD8Nyd.rst @@ -1,2 +1,2 @@ Added validation for the ``category`` argument in -``warnings.filterwarnings()`` and ``warnings.simplefilter()`` +:func:`warnings.filterwarnings()` and :func:`warnings.simplefilter()`. From 00eb17c2c78ec74b16cc1a640aad5b33b64d6f58 Mon Sep 17 00:00:00 2001 From: hasrat17 Date: Thu, 14 Aug 2025 00:58:09 +0530 Subject: [PATCH 4/5] Update _valid_warning_category and test for debug mode --- Lib/_py_warnings.py | 8 ++++---- Lib/test/test_warnings/__init__.py | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Lib/_py_warnings.py b/Lib/_py_warnings.py index cfe8ab88d8a5e6..8852e9d186909d 100644 --- a/Lib/_py_warnings.py +++ b/Lib/_py_warnings.py @@ -255,13 +255,13 @@ def _valid_warning_category(category): Return True if category is a Warning subclass or tuple of such. Always perform class checks; only perform tuple iteration in debug mode. """ + if not __debug__: + return True if isinstance(category, type) and issubclass(category, Warning): return True if isinstance(category, tuple): - if __debug__: - return all(isinstance(c, type) and issubclass(c, Warning) - for c in category) - return True + return all(isinstance(c, type) and issubclass(c, Warning) + for c in category) return False def filterwarnings(action, message="", category=Warning, module="", lineno=0, diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py index fafdfbbf5ad50a..afa6178ed2aa97 100644 --- a/Lib/test/test_warnings/__init__.py +++ b/Lib/test/test_warnings/__init__.py @@ -398,6 +398,8 @@ def test_argument_validation(self): with self.assertRaises(ValueError): self.module.simplefilter('ignore', lineno=-1) + # these tests fail if python is run with -O, so check __debug__ + @unittest.skipUnless(__debug__, "Won't work if __debug__ is False") def test_invalid_category_types(self): with self.assertRaises(TypeError): self.module.filterwarnings("ignore", category="notawarning") From 2a28591cb3867c6dc7d0ffbba0b96acd1fb43c12 Mon Sep 17 00:00:00 2001 From: Hasrat <56307533+hasrat17@users.noreply.github.com> Date: Thu, 14 Aug 2025 01:09:00 +0530 Subject: [PATCH 5/5] Update 2025-07-10-19-28-11.gh-issue-125893.lD8Nyd.rst Fixed the linting error --- .../next/Windows/2025-07-10-19-28-11.gh-issue-125893.lD8Nyd.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Windows/2025-07-10-19-28-11.gh-issue-125893.lD8Nyd.rst b/Misc/NEWS.d/next/Windows/2025-07-10-19-28-11.gh-issue-125893.lD8Nyd.rst index 3c1213ec479f72..6c0a212a6c8483 100644 --- a/Misc/NEWS.d/next/Windows/2025-07-10-19-28-11.gh-issue-125893.lD8Nyd.rst +++ b/Misc/NEWS.d/next/Windows/2025-07-10-19-28-11.gh-issue-125893.lD8Nyd.rst @@ -1,2 +1,2 @@ Added validation for the ``category`` argument in -:func:`warnings.filterwarnings()` and :func:`warnings.simplefilter()`. +:func:`warnings.filterwarnings` and :func:`warnings.simplefilter`.