]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-132159: Do not shadow user arguments in generated `__new__` by `@warnings...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Sun, 6 Apr 2025 17:00:54 +0000 (19:00 +0200)
committerGitHub <noreply@github.com>
Sun, 6 Apr 2025 17:00:54 +0000 (17:00 +0000)
gh-132159: Do not shadow user arguments in generated `__new__` by `@warnings.deprecated` (GH-132160)
(cherry picked from commit 7bb1e1a23634bae81bf76fdb34e9f9f7e59b3793)

Co-authored-by: Xuehai Pan <XuehaiPan@pku.edu.cn>
Lib/test/test_warnings/__init__.py
Lib/warnings.py
Misc/NEWS.d/next/Library/2025-04-06-16-12-49.gh-issue-132159.WvBfBm.rst [new file with mode: 0644]

index 5ed71495d84af0dbdb5c4481b4959c9cf424373e..e2dd909647078b5cee61e3558095a7d7f642cca1 100644 (file)
@@ -1628,6 +1628,25 @@ class DeprecatedTests(unittest.TestCase):
         instance = Child(42)
         self.assertEqual(instance.a, 42)
 
+    def test_do_not_shadow_user_arguments(self):
+        new_called = False
+        new_called_cls = None
+
+        @deprecated("MyMeta will go away soon")
+        class MyMeta(type):
+            def __new__(mcs, name, bases, attrs, cls=None):
+                nonlocal new_called, new_called_cls
+                new_called = True
+                new_called_cls = cls
+                return super().__new__(mcs, name, bases, attrs)
+
+        with self.assertWarnsRegex(DeprecationWarning, "MyMeta will go away soon"):
+            class Foo(metaclass=MyMeta, cls='haha'):
+                pass
+
+        self.assertTrue(new_called)
+        self.assertEqual(new_called_cls, 'haha')
+
     def test_existing_init_subclass(self):
         @deprecated("C will go away soon")
         class C:
index 8d340b5b578992802c42048683bf978c198f7011..f83aaf231eaa55bb4b99f438154cbb59548a744e 100644 (file)
@@ -589,7 +589,7 @@ class deprecated:
             original_new = arg.__new__
 
             @functools.wraps(original_new)
-            def __new__(cls, *args, **kwargs):
+            def __new__(cls, /, *args, **kwargs):
                 if cls is arg:
                     warn(msg, category=category, stacklevel=stacklevel + 1)
                 if original_new is not object.__new__:
diff --git a/Misc/NEWS.d/next/Library/2025-04-06-16-12-49.gh-issue-132159.WvBfBm.rst b/Misc/NEWS.d/next/Library/2025-04-06-16-12-49.gh-issue-132159.WvBfBm.rst
new file mode 100644 (file)
index 0000000..8cec76e
--- /dev/null
@@ -0,0 +1 @@
+Do not shadow user arguments in generated :meth:`!__new__` by decorator :class:`warnings.deprecated`. Patch by Xuehai Pan.