Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitcf62144

Browse files
[3.13]gh-138010: Fix__init_subclass__ forwarding bywarnings.deprecated (GH-138210) (#138564)
(cherry picked from commite2c038f)
1 parent4e25f01 commitcf62144

File tree

3 files changed

+36
-13
lines changed

3 files changed

+36
-13
lines changed

‎Lib/test/test_warnings/__init__.py‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1683,6 +1683,25 @@ class D(C, x=3):
16831683

16841684
self.assertEqual(D.inited,3)
16851685

1686+
deftest_existing_init_subclass_in_sibling_base(self):
1687+
@deprecated("A will go away soon")
1688+
classA:
1689+
pass
1690+
classB:
1691+
def__init_subclass__(cls,x):
1692+
super().__init_subclass__()
1693+
cls.inited=x
1694+
1695+
withself.assertWarnsRegex(DeprecationWarning,"A will go away soon"):
1696+
classC(A,B,x=42):
1697+
pass
1698+
self.assertEqual(C.inited,42)
1699+
1700+
withself.assertWarnsRegex(DeprecationWarning,"A will go away soon"):
1701+
classD(B,A,x=42):
1702+
pass
1703+
self.assertEqual(D.inited,42)
1704+
16861705
deftest_init_subclass_has_correct_cls(self):
16871706
init_subclass_saw=None
16881707

‎Lib/warnings.py‎

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -602,27 +602,27 @@ def __new__(cls, /, *args, **kwargs):
602602

603603
arg.__new__=staticmethod(__new__)
604604

605-
original_init_subclass=arg.__init_subclass__
606-
# We need slightly different behavior if __init_subclass__
607-
# is a bound method (likely if it was implemented in Python)
608-
ifisinstance(original_init_subclass,MethodType):
609-
original_init_subclass=original_init_subclass.__func__
605+
if"__init_subclass__"inarg.__dict__:
606+
# __init_subclass__ is directly present on the decorated class.
607+
# Synthesize a wrapper that calls this method directly.
608+
original_init_subclass=arg.__init_subclass__
609+
# We need slightly different behavior if __init_subclass__
610+
# is a bound method (likely if it was implemented in Python).
611+
# Otherwise, it likely means it's a builtin such as
612+
# object's implementation of __init_subclass__.
613+
ifisinstance(original_init_subclass,MethodType):
614+
original_init_subclass=original_init_subclass.__func__
610615

611616
@functools.wraps(original_init_subclass)
612617
def__init_subclass__(*args,**kwargs):
613618
warn(msg,category=category,stacklevel=stacklevel+1)
614619
returnoriginal_init_subclass(*args,**kwargs)
615-
616-
arg.__init_subclass__=classmethod(__init_subclass__)
617-
# Or otherwise, which likely means it's a builtin such as
618-
# object's implementation of __init_subclass__.
619620
else:
620-
@functools.wraps(original_init_subclass)
621-
def__init_subclass__(*args,**kwargs):
621+
def__init_subclass__(cls,*args,**kwargs):
622622
warn(msg,category=category,stacklevel=stacklevel+1)
623-
returnoriginal_init_subclass(*args,**kwargs)
623+
returnsuper(arg,cls).__init_subclass__(*args,**kwargs)
624624

625-
arg.__init_subclass__=__init_subclass__
625+
arg.__init_subclass__=classmethod(__init_subclass__)
626626

627627
arg.__deprecated__=__new__.__deprecated__=msg
628628
__init_subclass__.__deprecated__=msg
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fix an issue where defining a class with an:func:`@warnings.deprecated
2+
<warnings.deprecated>`-decorated base class may not invoke the correct
3+
:meth:`~object.__init_subclass__` method in cases involving multiple
4+
inheritance. Patch by Brian Schubert.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp