Skip to content

Commit 1486925

Browse files
committed
fix(mypyc): skip __slots__ class variable emission
Keep __slots__ classified as a class variable for type checking, but do not attach it to native classes at runtime. Native classes use their own layout, and exposing inherited slots prevents compiled subclasses from being created. Add a compiled inheritance regression that reproduces the CI failure.
1 parent bd2c051 commit 1486925

2 files changed

Lines changed: 20 additions & 0 deletions

File tree

mypyc/irbuild/classdef.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,9 @@ def add_attr(self, lvalue: NameExpr, stmt: AssignmentStmt) -> None:
329329
# Variable declaration with no body
330330
if isinstance(stmt.rvalue, TempNode):
331331
return
332+
# Native classes use mypyc's own layout, so don't emit __slots__ at runtime.
333+
if lvalue.name == "__slots__":
334+
return
332335
# Only treat marked class variables as class variables.
333336
if not (is_class_var(lvalue) or stmt.is_final_def):
334337
return

mypyc/test-data/run-classes.test

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,23 @@ assert f() == 10
11751175
A.x = 200
11761176
assert f() == 200
11771177

1178+
[case testSlotsNotEmittedAsClassVar]
1179+
class Base:
1180+
__slots__ = ("value",)
1181+
value: int
1182+
1183+
class Child(Base):
1184+
pass
1185+
1186+
def make_child() -> Child:
1187+
child = Child()
1188+
child.value = 1
1189+
return child
1190+
[file driver.py]
1191+
from native import make_child
1192+
1193+
assert make_child().value == 1
1194+
11781195
[case testClassVarDoesNotShadowMethodGlobal]
11791196
from typing import ClassVar
11801197
from testutil import assertRaises

0 commit comments

Comments
 (0)