@@ -1375,10 +1375,7 @@ def load_non_ext_class(self, ir: ClassIR, non_ext: NonExtClassInfo, line: int) -
13751375
13761376 self .finish_non_ext_dict (non_ext , line )
13771377
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 ,
13821379 [cls_name , non_ext .bases , non_ext .dict ],
13831380 line )
13841381 return class_type_obj
@@ -1453,16 +1450,22 @@ def add_non_ext_class_attr(self, non_ext: NonExtClassInfo, lvalue: NameExpr,
14531450 ):
14541451 attr_to_cache .append (lvalue )
14551452
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 :
14571463 """
14581464 Initialize the class dictionary for a non-extension class. This class dictionary
14591465 is passed to the metaclass constructor.
14601466 """
14611467
14621468 # 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 )
14661469 has_prepare = self .primitive_op (py_hasattr_op ,
14671470 [metaclass ,
14681471 self .load_static_unicode ('__prepare__' )], cdef .line )
@@ -1506,6 +1509,7 @@ def dataclass_non_ext_info(self, cdef: ClassDef) -> Optional[NonExtClassInfo]:
15061509 self .primitive_op (new_dict_op , [], cdef .line ),
15071510 self .add (TupleSet ([], cdef .line )),
15081511 self .primitive_op (new_dict_op , [], cdef .line ),
1512+ self .primitive_op (type_object_op , [], cdef .line ),
15091513 )
15101514 else :
15111515 return None
@@ -1560,12 +1564,13 @@ def visit_class_def(self, cdef: ClassDef) -> None:
15601564 dataclass_non_ext = self .dataclass_non_ext_info (cdef )
15611565 else :
15621566 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 )
15641569 # We populate __annotations__ for non-extension classes
15651570 # because dataclasses uses it to determine which attributes to compute on.
15661571 # TODO: Maybe generate more precise types for annotations
15671572 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 )
15691574 dataclass_non_ext = None
15701575 type_obj = None
15711576
0 commit comments