[3.13] gh-138010: Fix __init_subclass__ forwarding by warnings.deprecated (GH-138210) (#138564)

(cherry picked from commit e2c038f5be)
This commit is contained in:
Brian Schubert 2025-09-05 17:21:19 -04:00 committed by GitHub
parent 4e25f012e7
commit cf62144f45
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 36 additions and 13 deletions

View file

@ -602,27 +602,27 @@ def __new__(cls, /, *args, **kwargs):
arg.__new__ = staticmethod(__new__)
original_init_subclass = arg.__init_subclass__
# We need slightly different behavior if __init_subclass__
# is a bound method (likely if it was implemented in Python)
if isinstance(original_init_subclass, MethodType):
original_init_subclass = original_init_subclass.__func__
if "__init_subclass__" in arg.__dict__:
# __init_subclass__ is directly present on the decorated class.
# Synthesize a wrapper that calls this method directly.
original_init_subclass = arg.__init_subclass__
# We need slightly different behavior if __init_subclass__
# is a bound method (likely if it was implemented in Python).
# Otherwise, it likely means it's a builtin such as
# object's implementation of __init_subclass__.
if isinstance(original_init_subclass, MethodType):
original_init_subclass = original_init_subclass.__func__
@functools.wraps(original_init_subclass)
def __init_subclass__(*args, **kwargs):
warn(msg, category=category, stacklevel=stacklevel + 1)
return original_init_subclass(*args, **kwargs)
arg.__init_subclass__ = classmethod(__init_subclass__)
# Or otherwise, which likely means it's a builtin such as
# object's implementation of __init_subclass__.
else:
@functools.wraps(original_init_subclass)
def __init_subclass__(*args, **kwargs):
def __init_subclass__(cls, *args, **kwargs):
warn(msg, category=category, stacklevel=stacklevel + 1)
return original_init_subclass(*args, **kwargs)
return super(arg, cls).__init_subclass__(*args, **kwargs)
arg.__init_subclass__ = __init_subclass__
arg.__init_subclass__ = classmethod(__init_subclass__)
arg.__deprecated__ = __new__.__deprecated__ = msg
__init_subclass__.__deprecated__ = msg