Skip to content

Commit b9d1199

Browse files
committed
Fully promote __init_subclass__ to a classmethod.
PiperOrigin-RevId: 623325031
1 parent 97a39a0 commit b9d1199

3 files changed

Lines changed: 16 additions & 3 deletions

File tree

pytype/abstract/_interpreter_function.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,6 @@ def __init__(self, name, def_opcode, code, f_locals, f_globals, defaults,
186186
self.last_frame = None # for BuildClass
187187
self._store_call_records = False
188188
self.is_class_builder = False # Will be set by BuildClass.
189-
if name.endswith(".__init_subclass__"):
190-
# __init_subclass__ is automatically promoted to a classmethod
191-
self.is_classmethod = True
192189
# Whether to cache the return value irrespective of call args
193190
self.cache_return = False
194191

pytype/tests/test_classes2.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,16 @@ class X:
583583
x: int
584584
""")
585585

586+
def test_init_subclass_super(self):
587+
self.Check("""
588+
class A:
589+
def __init_subclass__(cls):
590+
pass
591+
class B(A):
592+
def __init_subclass__(cls):
593+
super().__init_subclass__()
594+
""")
595+
586596

587597
if __name__ == "__main__":
588598
test_base.main()

pytype/vm_utils.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,12 @@ def make_class(node, props, ctx):
526526
annotations_dict, ctx).to_variable(node)
527527
class_dict.members["__annotations__"] = annotations_member
528528
class_dict.pyval["__annotations__"] = annotations_member
529+
if "__init_subclass__" in class_dict.members:
530+
# __init_subclass__ is automatically promoted to a classmethod
531+
underlying = class_dict.pyval["__init_subclass__"]
532+
_, method = ctx.vm.load_special_builtin("classmethod").call(
533+
node, func=None, args=function.Args(posargs=(underlying,)))
534+
class_dict.pyval["__init_subclass__"] = method
529535
try:
530536
class_type = props.class_type or abstract.InterpreterClass
531537
assert issubclass(class_type, abstract.InterpreterClass)

0 commit comments

Comments
 (0)