diff --git a/mypy/newsemanal/semanal.py b/mypy/newsemanal/semanal.py index 9c8bff7a335d..6602d5dd3b93 100644 --- a/mypy/newsemanal/semanal.py +++ b/mypy/newsemanal/semanal.py @@ -2640,7 +2640,7 @@ def analyze_types(self, items: List[Expression]) -> List[Type]: if analyzed is not None: result.append(analyzed) else: - # TODO: Is this the right thing to do? + # TODO: Is this the right thing to do? Or maybe return Optional[List[Type]]? result.append(AnyType(TypeOfAny.from_error)) except TypeTranslationError: self.fail('Type expected', node) diff --git a/mypy/newsemanal/semanal_main.py b/mypy/newsemanal/semanal_main.py index 00fed2fef97b..a113da67927f 100644 --- a/mypy/newsemanal/semanal_main.py +++ b/mypy/newsemanal/semanal_main.py @@ -16,7 +16,13 @@ def semantic_analysis_for_scc(graph: 'Graph', scc: List[str]) -> None: - # Assume reachability analysis has already been performed. + """Perform semantic analysis for all modules in a SCC (import cycle). + + Assume that reachability analysis has already been performed. + """ + # Note that functions can't define new module-level attributes + # using 'global x', since module top levels are fully processed + # before functions. This limitation is unlikely to go away soon. process_top_levels(graph, scc) process_functions(graph, scc) diff --git a/mypy/plugin.py b/mypy/plugin.py index fba43a29d2aa..23fe3c68b51a 100644 --- a/mypy/plugin.py +++ b/mypy/plugin.py @@ -182,7 +182,12 @@ def anal_type(self, t: Type, *, allow_unbound_tvars: bool = False, report_invalid_types: bool = True, third_pass: bool = False) -> Optional[Type]: - """Analyze an unbound type.""" + """Analyze an unbound type. + + Return None if the some part of the type is not ready yet (only + happens with the new semantic analyzer). In this case the current + target being analyzed will be deferred and analyzed again. + """ raise NotImplementedError @abstractmethod diff --git a/test-data/unit/check-newsemanal.test b/test-data/unit/check-newsemanal.test index 25d3b667cf87..cb11e3e6ffab 100644 --- a/test-data/unit/check-newsemanal.test +++ b/test-data/unit/check-newsemanal.test @@ -80,6 +80,15 @@ from b import bad # E: Module 'b' has no attribute 'bad' [file b.py] from a import bad2 # E: Module 'a' has no attribute 'bad2' +[case testNewAnalyzerTypeAnnotationCycle4] +# flags: --new-semantic-analyzer +import b +[file a.py] +from b import bad # E: Module 'b' has no attribute 'bad' +[file b.py] +# TODO: Could we generate an error here as well? +from a import bad + [case testNewAnalyzerSimpleFunction] # flags: --new-semantic-analyzer def f(x: int) -> str: