Skip to content

Commit c7cfb69

Browse files
gnpricegvanrossum
authored andcommitted
Cut the attribute ClassDef.base_types (#1694)
This seems to be always equivalent to `bases` on the corresponding TypeInfo, so keep the information in just one place. This is part of clearing out the old branches I've had lying around on my local clone of the repo -- back in December I was studying how we handle the MRO, found this confusing, and had a note that this attribute seemed to be redundant. Further investigation bears that out: in particular, the fact that the tests pass after this change which cuts it out entirely.
1 parent c2eefec commit c7cfb69

File tree

4 files changed

+16
-17
lines changed

4 files changed

+16
-17
lines changed

mypy/nodes.py

-5
Original file line numberDiff line numberDiff line change
@@ -627,8 +627,6 @@ class ClassDef(Node):
627627
type_vars = None # type: List[mypy.types.TypeVarDef]
628628
# Base class expressions (not semantically analyzed -- can be arbitrary expressions)
629629
base_type_exprs = None # type: List[Node]
630-
# Semantically analyzed base types, derived from base_type_exprs during semantic analysis
631-
base_types = None # type: List[mypy.types.Instance]
632630
info = None # type: TypeInfo # Related TypeInfo
633631
metaclass = ''
634632
decorators = None # type: List[Node]
@@ -645,7 +643,6 @@ def __init__(self,
645643
self.defs = defs
646644
self.type_vars = type_vars or []
647645
self.base_type_exprs = base_type_exprs or []
648-
self.base_types = [] # Not yet semantically analyzed --> don't know base types
649646
self.metaclass = metaclass
650647
self.decorators = []
651648

@@ -661,7 +658,6 @@ def serialize(self) -> JsonDict:
661658
'name': self.name,
662659
'fullname': self.fullname,
663660
'type_vars': [v.serialize() for v in self.type_vars],
664-
'base_types': [t.serialize() for t in self.base_types],
665661
'metaclass': self.metaclass,
666662
'is_builtinclass': self.is_builtinclass,
667663
}
@@ -675,7 +671,6 @@ def deserialize(self, data: JsonDict) -> 'ClassDef':
675671
metaclass=data['metaclass'],
676672
)
677673
res.fullname = data['fullname']
678-
res.base_types = [mypy.types.Instance.deserialize(t) for t in data['base_types']]
679674
res.is_builtinclass = data['is_builtinclass']
680675
return res
681676

mypy/semanal.py

+11-5
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,13 @@ def setup_class_def_analysis(self, defn: ClassDef) -> None:
732732
self.add_symbol(defn.name, SymbolTableNode(kind, defn.info), defn)
733733

734734
def analyze_base_classes(self, defn: ClassDef) -> None:
735-
"""Analyze and set up base classes."""
735+
"""Analyze and set up base classes.
736+
737+
This computes several attributes on the corresponding TypeInfo defn.info
738+
related to the base classes: defn.info.bases, defn.info.mro, and
739+
miscellaneous others (at least tuple_type, fallback_to_any, and is_enum.)
740+
"""
741+
base_types = []
736742
for base_expr in defn.base_type_exprs:
737743
# The base class is originally an expression; convert it to a type.
738744
try:
@@ -750,7 +756,7 @@ def analyze_base_classes(self, defn: ClassDef) -> None:
750756
base.type.fullname() == 'builtins.tuple'):
751757
self.fail("Tuple[...] not supported as a base class outside a stub file", defn)
752758
if isinstance(base, Instance):
753-
defn.base_types.append(base)
759+
base_types.append(base)
754760
elif isinstance(base, TupleType):
755761
assert False, "Internal error: Unexpected TupleType base class"
756762
elif isinstance(base, AnyType):
@@ -760,10 +766,10 @@ def analyze_base_classes(self, defn: ClassDef) -> None:
760766
elif not isinstance(base, UnboundType):
761767
self.fail('Invalid base class', base_expr)
762768
# Add 'object' as implicit base if there is no other base class.
763-
if (not defn.base_types and defn.fullname != 'builtins.object'):
769+
if (not base_types and defn.fullname != 'builtins.object'):
764770
obj = self.object_type()
765-
defn.base_types.insert(0, obj)
766-
defn.info.bases = defn.base_types
771+
base_types.insert(0, obj)
772+
defn.info.bases = base_types
767773
# Calculate the MRO. It might be incomplete at this point if
768774
# the bases of defn include classes imported from other
769775
# modules in an import loop. We'll recompute it in ThirdPass.

mypy/strconv.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,11 @@ def visit_class_def(self, o):
130130
a = [o.name, o.defs.body]
131131
# Display base types unless they are implicitly just builtins.object
132132
# (in this case base_type_exprs is empty).
133-
if o.base_types and o.base_type_exprs:
134-
a.insert(1, ('BaseType', o.base_types))
135-
elif len(o.base_type_exprs) > 0:
136-
a.insert(1, ('BaseTypeExpr', o.base_type_exprs))
133+
if o.base_type_exprs:
134+
if o.info and o.info.bases:
135+
a.insert(1, ('BaseType', o.info.bases))
136+
else:
137+
a.insert(1, ('BaseTypeExpr', o.base_type_exprs))
137138
if o.type_vars:
138139
a.insert(1, ('TypeVars', o.type_vars))
139140
if o.metaclass:

mypy/treetransform.py

-3
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,6 @@ def visit_class_def(self, node: ClassDef) -> Node:
160160
node.metaclass)
161161
new.fullname = node.fullname
162162
new.info = node.info
163-
new.base_types = []
164-
for base in node.base_types:
165-
new.base_types.append(cast(Instance, self.type(base)))
166163
new.decorators = [decorator.accept(self)
167164
for decorator in node.decorators]
168165
new.is_builtinclass = node.is_builtinclass

0 commit comments

Comments
 (0)