Skip to content

Commit 7bb1e1a

Browse files
authored
gh-132159: Do not shadow user arguments in generated __new__ by @warnings.deprecated (#132160)
1 parent c0661df commit 7bb1e1a

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

Lib/test/test_warnings/__init__.py

+19
Original file line numberDiff line numberDiff line change
@@ -1653,6 +1653,25 @@ class Child(Base, Mixin):
16531653
instance = Child(42)
16541654
self.assertEqual(instance.a, 42)
16551655

1656+
def test_do_not_shadow_user_arguments(self):
1657+
new_called = False
1658+
new_called_cls = None
1659+
1660+
@deprecated("MyMeta will go away soon")
1661+
class MyMeta(type):
1662+
def __new__(mcs, name, bases, attrs, cls=None):
1663+
nonlocal new_called, new_called_cls
1664+
new_called = True
1665+
new_called_cls = cls
1666+
return super().__new__(mcs, name, bases, attrs)
1667+
1668+
with self.assertWarnsRegex(DeprecationWarning, "MyMeta will go away soon"):
1669+
class Foo(metaclass=MyMeta, cls='haha'):
1670+
pass
1671+
1672+
self.assertTrue(new_called)
1673+
self.assertEqual(new_called_cls, 'haha')
1674+
16561675
def test_existing_init_subclass(self):
16571676
@deprecated("C will go away soon")
16581677
class C:

Lib/warnings.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ def __call__(self, arg, /):
597597
original_new = arg.__new__
598598

599599
@functools.wraps(original_new)
600-
def __new__(cls, *args, **kwargs):
600+
def __new__(cls, /, *args, **kwargs):
601601
if cls is arg:
602602
warn(msg, category=category, stacklevel=stacklevel + 1)
603603
if original_new is not object.__new__:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Do not shadow user arguments in generated :meth:`!__new__` by decorator :class:`warnings.deprecated`. Patch by Xuehai Pan.

0 commit comments

Comments
 (0)