Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 4 additions & 13 deletions mypy/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2175,8 +2175,7 @@ def __init__(self, names: 'SymbolTable', defn: ClassDef, module_name: str) -> No
self.module_name = module_name
self.type_vars = []
self.bases = []
# Leave self.mro uninitialized until we compute it for real,
# so we don't accidentally try to use it prematurely.
self.mro = []
self._fullname = defn.fullname
self.is_abstract = False
self.abstract_attributes = []
Expand All @@ -2203,9 +2202,6 @@ def is_generic(self) -> bool:
return len(self.type_vars) > 0

def get(self, name: str) -> 'Optional[SymbolTableNode]':
if self.mro is None: # Might be because of a previous error.
return None

for cls in self.mro:
n = cls.names.get(name)
if n:
Expand Down Expand Up @@ -2244,8 +2240,6 @@ def has_readable_member(self, name: str) -> bool:
return self.get(name) is not None

def get_method(self, name: str) -> Optional[FuncBase]:
if self.mro is None: # Might be because of a previous error.
return None
for cls in self.mro:
if name in cls.names:
node = cls.names[name].node
Expand All @@ -2266,8 +2260,6 @@ def calculate_metaclass_type(self) -> 'Optional[mypy.types.Instance]':
if s.declared_metaclass is not None
and s.declared_metaclass.type is not None]
for c in candidates:
if c.type.mro is None:
continue
if all(other.type in c.type.mro for other in candidates):
return c
return None
Expand All @@ -2281,10 +2273,9 @@ def has_base(self, fullname: str) -> bool:

This can be either via extension or via implementation.
"""
if self.mro:
for cls in self.mro:
if cls.fullname() == fullname:
return True
for cls in self.mro:
if cls.fullname() == fullname:
return True
return False

def direct_base_classes(self) -> 'List[TypeInfo]':
Expand Down
4 changes: 2 additions & 2 deletions mypy/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -2149,7 +2149,7 @@ def basic_new_typeinfo(self, name: str, basetype_or_fallback: Instance) -> TypeI
info = TypeInfo(SymbolTable(), class_def, self.cur_mod_id)
class_def.info = info
mro = basetype_or_fallback.type.mro
if mro is None:
if not mro:
# Forward reference, MRO should be recalculated in third pass.
mro = [basetype_or_fallback.type, self.object_type().type]
info.mro = [info] + mro
Expand Down Expand Up @@ -3068,7 +3068,7 @@ def lookup_qualified(self, name: str, ctx: Context,
if n:
for i in range(1, len(parts)):
if isinstance(n.node, TypeInfo):
if n.node.mro is None:
if not n.node.mro:
# We haven't yet analyzed the class `n.node`. Fall back to direct
# lookup in the names declared directly under it, without its base
# classes. This can happen when we have a forward reference to a
Expand Down
17 changes: 7 additions & 10 deletions mypy/subtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,16 +154,13 @@ def visit_instance(self, left: Instance) -> bool:
if isinstance(right, Instance):
if TypeState.is_cached_subtype_check(left, right):
return True
# NOTE: left.type.mro may be None in quick mode if there
# was an error somewhere.
if left.type.mro is not None:
for base in left.type.mro:
# TODO: Also pass recursively ignore_declared_variance
if base._promote and is_subtype(
base._promote, self.right, self.check_type_parameter,
ignore_pos_arg_names=self.ignore_pos_arg_names):
TypeState.record_subtype_cache_entry(left, right)
return True
for base in left.type.mro:
# TODO: Also pass recursively ignore_declared_variance
if base._promote and is_subtype(
base._promote, self.right, self.check_type_parameter,
ignore_pos_arg_names=self.ignore_pos_arg_names):
TypeState.record_subtype_cache_entry(left, right)
return True
rname = right.type.fullname()
# Always try a nominal check if possible,
# there might be errors that a user wants to silence *once*.
Expand Down