Skip to content

Commit

Permalink
New semantic analyzer: add comments and refactor (#7130)
Browse files Browse the repository at this point in the history
Document deferral logic in some detail and remove redundant
calls to `defer()`.

Work towards #7071.
  • Loading branch information
JukkaL authored Jul 2, 2019
1 parent 0ee6cbe commit ec45983
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 6 deletions.
22 changes: 17 additions & 5 deletions mypy/newsemanal/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -2182,7 +2182,6 @@ def process_type_annotation(self, s: AssignmentStmt) -> None:
analyzed = self.anal_type(s.type, allow_tuple_literal=allow_tuple_literal)
# Don't store not ready types (including placeholders).
if analyzed is None or has_placeholder(analyzed):
self.defer()
return
s.type = analyzed
if (self.type and self.type.is_protocol and isinstance(lvalue, NameExpr) and
Expand Down Expand Up @@ -3565,7 +3564,6 @@ def analyze_type_application_args(self, expr: IndexExpr) -> Optional[List[Type]]
analyzed = self.anal_type(typearg, allow_unbound_tvars=True,
allow_placeholder=True)
if analyzed is None:
self.defer()
return None
types.append(analyzed)
return types
Expand Down Expand Up @@ -4507,9 +4505,23 @@ def anal_type(self,
third_pass: bool = False) -> Optional[Type]:
"""Semantically analyze a type.
Return None only if some part of the type couldn't be bound *and* it referred
to an incomplete namespace. In case of other errors, report an error message
and return AnyType.
Args:
typ: Type to analyze (if already analyzed, this is a no-op)
allow_placeholder: If True, may return PlaceholderType if
encountering an incomplete definition
third_pass: Unused; only for compatibility with old semantic
analyzer
Return None only if some part of the type couldn't be bound *and* it
referred to an incomplete namespace or definition. In this case also
defer as needed. During a final iteration this won't return None;
instead report an error if the type can't be analyzed and return
AnyType.
In case of other errors, report an error message and return AnyType.
NOTE: The caller shouldn't defer even if this returns None or a
placeholder type.
"""
a = self.type_analyzer(tvar_scope=tvar_scope,
allow_unbound_tvars=allow_unbound_tvars,
Expand Down
6 changes: 5 additions & 1 deletion mypy/newsemanal/typeanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,11 @@ def no_subscript_builtin_alias(name: str, propose_alt: bool = True) -> str:
class TypeAnalyser(SyntheticTypeVisitor[Type], TypeAnalyzerPluginInterface):
"""Semantic analyzer for types.
Converts unbound types into bound types.
Converts unbound types into bound types. This is a no-op for already
bound types.
If an incomplete reference is encountered, this does a defer. The
caller never needs to defer.
"""

# Is this called from an untyped function definition?
Expand Down

0 comments on commit ec45983

Please sign in to comment.