Skip to content

Commit 24fd09a

Browse files
author
Guido van Rossum
committed
Move check for six.with_metaclass to clean_up_bases_and_infer_type_variables (per Ivan L's review)
1 parent 53d32b6 commit 24fd09a

File tree

1 file changed

+17
-15
lines changed

1 file changed

+17
-15
lines changed

mypy/semanal.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -758,8 +758,12 @@ def clean_up_bases_and_infer_type_variables(self, defn: ClassDef) -> None:
758758
Now we will remove Generic[T] from bases of Foo and infer that the
759759
type variable 'T' is a type argument of Foo.
760760
761+
We also process six.with_metaclass() here.
762+
761763
Note that this is performed *before* semantic analysis.
762764
"""
765+
# First process six.with_metaclass if present and well-formed
766+
defn.base_type_exprs, defn.metaclass = self.check_with_metaclass(defn)
763767
removed = [] # type: List[int]
764768
declared_tvars = [] # type: TypeVarList
765769
for i, base_expr in enumerate(defn.base_type_exprs):
@@ -939,8 +943,7 @@ def analyze_base_classes(self, defn: ClassDef) -> None:
939943
base_types = [] # type: List[Instance]
940944
info = defn.info
941945

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:
944947
try:
945948
base = self.expr_to_analyzed_type(base_expr)
946949
except TypeTranslationError:
@@ -991,27 +994,26 @@ def analyze_base_classes(self, defn: ClassDef) -> None:
991994
if defn.info.is_enum and defn.type_vars:
992995
self.fail("Enum class cannot be generic", defn)
993996

994-
def check_with_metaclass(self, defn: ClassDef) -> List[Expression]:
997+
def check_with_metaclass(self, defn: ClassDef) -> Tuple[List[Expression], Optional[str]]:
995998
# 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:
9991001
base_expr = base_type_exprs[0]
10001002
if isinstance(base_expr, CallExpr) and isinstance(base_expr.callee, RefExpr):
1001-
base_expr.accept(self)
1003+
base_expr.callee.accept(self)
10021004
if (base_expr.callee.fullname == 'six.with_metaclass'
10031005
and len(base_expr.args) >= 1
10041006
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)
10101012
else:
10111013
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)
10151017

10161018
def expr_to_analyzed_type(self, expr: Expression) -> Type:
10171019
if isinstance(expr, CallExpr):

0 commit comments

Comments
 (0)