@@ -1375,10 +1375,7 @@ def load_non_ext_class(self, ir: ClassIR, non_ext: NonExtClassInfo, line: int) -
1375
1375
1376
1376
self .finish_non_ext_dict (non_ext , line )
1377
1377
1378
- metaclass = self .primitive_op (type_object_op , [], line )
1379
- metaclass = self .primitive_op (py_calc_meta_op , [metaclass , non_ext .bases ], line )
1380
-
1381
- class_type_obj = self .py_call (metaclass ,
1378
+ class_type_obj = self .py_call (non_ext .metaclass ,
1382
1379
[cls_name , non_ext .bases , non_ext .dict ],
1383
1380
line )
1384
1381
return class_type_obj
@@ -1453,16 +1450,22 @@ def add_non_ext_class_attr(self, non_ext: NonExtClassInfo, lvalue: NameExpr,
1453
1450
):
1454
1451
attr_to_cache .append (lvalue )
1455
1452
1456
- def setup_non_ext_dict (self , cdef : ClassDef , bases : Value ) -> Value :
1453
+ def find_non_ext_metaclass (self , cdef : ClassDef , bases : Value ) -> Value :
1454
+ """Find the metaclass of a class from its defs and bases. """
1455
+ if cdef .metaclass :
1456
+ declared_metaclass = self .accept (cdef .metaclass )
1457
+ else :
1458
+ declared_metaclass = self .primitive_op (type_object_op , [], cdef .line )
1459
+
1460
+ return self .primitive_op (py_calc_meta_op , [declared_metaclass , bases ], cdef .line )
1461
+
1462
+ def setup_non_ext_dict (self , cdef : ClassDef , metaclass : Value , bases : Value ) -> Value :
1457
1463
"""
1458
1464
Initialize the class dictionary for a non-extension class. This class dictionary
1459
1465
is passed to the metaclass constructor.
1460
1466
"""
1461
1467
1462
1468
# Check if the metaclass defines a __prepare__ method, and if so, call it.
1463
- metaclass = self .primitive_op (type_object_op , [], cdef .line )
1464
- metaclass = self .primitive_op (py_calc_meta_op , [metaclass , bases ],
1465
- cdef .line )
1466
1469
has_prepare = self .primitive_op (py_hasattr_op ,
1467
1470
[metaclass ,
1468
1471
self .load_static_unicode ('__prepare__' )], cdef .line )
@@ -1506,6 +1509,7 @@ def dataclass_non_ext_info(self, cdef: ClassDef) -> Optional[NonExtClassInfo]:
1506
1509
self .primitive_op (new_dict_op , [], cdef .line ),
1507
1510
self .add (TupleSet ([], cdef .line )),
1508
1511
self .primitive_op (new_dict_op , [], cdef .line ),
1512
+ self .primitive_op (type_object_op , [], cdef .line ),
1509
1513
)
1510
1514
else :
1511
1515
return None
@@ -1560,12 +1564,13 @@ def visit_class_def(self, cdef: ClassDef) -> None:
1560
1564
dataclass_non_ext = self .dataclass_non_ext_info (cdef )
1561
1565
else :
1562
1566
non_ext_bases = self .populate_non_ext_bases (cdef )
1563
- non_ext_dict = self .setup_non_ext_dict (cdef , non_ext_bases )
1567
+ non_ext_metaclass = self .find_non_ext_metaclass (cdef , non_ext_bases )
1568
+ non_ext_dict = self .setup_non_ext_dict (cdef , non_ext_metaclass , non_ext_bases )
1564
1569
# We populate __annotations__ for non-extension classes
1565
1570
# because dataclasses uses it to determine which attributes to compute on.
1566
1571
# TODO: Maybe generate more precise types for annotations
1567
1572
non_ext_anns = self .primitive_op (new_dict_op , [], cdef .line )
1568
- non_ext = NonExtClassInfo (non_ext_dict , non_ext_bases , non_ext_anns )
1573
+ non_ext = NonExtClassInfo (non_ext_dict , non_ext_bases , non_ext_anns , non_ext_metaclass )
1569
1574
dataclass_non_ext = None
1570
1575
type_obj = None
1571
1576
0 commit comments