@@ -758,8 +758,12 @@ def clean_up_bases_and_infer_type_variables(self, defn: ClassDef) -> None:
758
758
Now we will remove Generic[T] from bases of Foo and infer that the
759
759
type variable 'T' is a type argument of Foo.
760
760
761
+ We also process six.with_metaclass() here.
762
+
761
763
Note that this is performed *before* semantic analysis.
762
764
"""
765
+ # First process six.with_metaclass if present and well-formed
766
+ defn .base_type_exprs , defn .metaclass = self .check_with_metaclass (defn )
763
767
removed = [] # type: List[int]
764
768
declared_tvars = [] # type: TypeVarList
765
769
for i , base_expr in enumerate (defn .base_type_exprs ):
@@ -939,8 +943,7 @@ def analyze_base_classes(self, defn: ClassDef) -> None:
939
943
base_types = [] # type: List[Instance]
940
944
info = defn .info
941
945
942
- base_type_exprs = self .check_with_metaclass (defn )
943
- for base_expr in base_type_exprs :
946
+ for base_expr in defn .base_type_exprs :
944
947
try :
945
948
base = self .expr_to_analyzed_type (base_expr )
946
949
except TypeTranslationError :
@@ -991,27 +994,26 @@ def analyze_base_classes(self, defn: ClassDef) -> None:
991
994
if defn .info .is_enum and defn .type_vars :
992
995
self .fail ("Enum class cannot be generic" , defn )
993
996
994
- def check_with_metaclass (self , defn : ClassDef ) -> List [Expression ]:
997
+ def check_with_metaclass (self , defn : ClassDef ) -> Tuple [ List [Expression ], Optional [ str ] ]:
995
998
# Special-case six.with_metaclass(M, B1, B2, ...).
996
- # May update defn.metaclass.
997
- base_type_exprs = defn .base_type_exprs
998
- if defn .metaclass is None and len (base_type_exprs ) == 1 :
999
+ base_type_exprs , metaclass = defn .base_type_exprs , defn .metaclass
1000
+ if metaclass is None and len (base_type_exprs ) == 1 :
999
1001
base_expr = base_type_exprs [0 ]
1000
1002
if isinstance (base_expr , CallExpr ) and isinstance (base_expr .callee , RefExpr ):
1001
- base_expr .accept (self )
1003
+ base_expr .callee . accept (self )
1002
1004
if (base_expr .callee .fullname == 'six.with_metaclass'
1003
1005
and len (base_expr .args ) >= 1
1004
1006
and all (kind == ARG_POS for kind in base_expr .arg_kinds )):
1005
- metaclass = base_expr .args [0 ]
1006
- if isinstance (metaclass , NameExpr ):
1007
- defn . metaclass = metaclass .name
1008
- elif isinstance (metaclass , MemberExpr ):
1009
- defn . metaclass = get_member_expr_fullname (metaclass )
1007
+ metaclass_expr = base_expr .args [0 ]
1008
+ if isinstance (metaclass_expr , NameExpr ):
1009
+ metaclass = metaclass_expr .name
1010
+ elif isinstance (metaclass_expr , MemberExpr ):
1011
+ metaclass = get_member_expr_fullname (metaclass_expr )
1010
1012
else :
1011
1013
self .fail ("Dynamic metaclass not supported for '%s'" % defn .name ,
1012
- metaclass )
1013
- return base_expr .args [1 :]
1014
- return base_type_exprs
1014
+ metaclass_expr )
1015
+ return ( base_expr .args [1 :], metaclass )
1016
+ return ( base_type_exprs , metaclass )
1015
1017
1016
1018
def expr_to_analyzed_type (self , expr : Expression ) -> Type :
1017
1019
if isinstance (expr , CallExpr ):
0 commit comments