Skip to content

"Invalid type" when using type alias in import cycle #4498

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
JukkaL opened this issue Jan 22, 2018 · 0 comments · Fixed by #5635
Closed

"Invalid type" when using type alias in import cycle #4498

JukkaL opened this issue Jan 22, 2018 · 0 comments · Fixed by #5635
Assignees
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-0-high topic-import-cycles

Comments

@JukkaL
Copy link
Collaborator

JukkaL commented Jan 22, 2018

Type checking the following files results in an unexpected "Invalid type" error:

t.py:

MYPY = False
if MYPY:
    from t2 import A

x: A  # Invalid type "t2.A"   <---- unexpected

t2.py:

import t
from typing import Callable

A = Callable[[], None]

The reason for the error is that t and t2 form an import cycle and t is processed before t2 in the cycle, and thus the type alias A hasn't been processed when we analyze t.

This is probably the same bug as #4442, but for users this may not be obvious, so it perhaps makes maintain a separate issue.

@JukkaL JukkaL added bug mypy got something wrong priority-0-high labels Feb 9, 2018
msullivan added a commit that referenced this issue May 9, 2018
The logic in build to determine what imported modules are depended on
used to elide dependencies to m in `from m import a, b, c` if all of
a, b, c were submodules. This was removed in #4910 because it seemed
like it ought not be necessary (and that semantically there *was*
a dependency), and early versions of #4910 depended removing it.

The addition of this dependency, though, can cause cycles that
wouldn't be there otherwise, which can cause #4498 (invalid type when
using aliases in import cycles) to trip when it otherwise wouldn't.

We've seen this once in a bug report and once internally, so restore
the `all_are_submodules` logic in avoid triggering #4498 in these
cases.
msullivan added a commit that referenced this issue May 9, 2018
The logic in build to determine what imported modules are depended on
used to elide dependencies to m in `from m import a, b, c` if all of
a, b, c were submodules. This was removed in #4910 because it seemed
like it ought not be necessary (and that semantically there *was*
a dependency), and early versions of #4910 depended removing it.

The addition of this dependency, though, can cause cycles that
wouldn't be there otherwise, which can cause #4498 (invalid type when
using aliases in import cycles) to trip when it otherwise wouldn't.

We've seen this once in a bug report and once internally, so restore
the `all_are_submodules` logic in avoid triggering #4498 in these
cases.

Fixes #5015
msullivan added a commit that referenced this issue May 14, 2018
)

The logic in build to determine what imported modules are depended on
used to elide dependencies to m in `from m import a, b, c` if all of
a, b, c were submodules. This was removed in #4910 because it seemed
like it ought not be necessary (and that semantically there *was*
a dependency), and early versions of #4910 depended on removing it.

The addition of this dependency, though, can cause cycles that
wouldn't be there otherwise, which can cause #4498 (invalid type when
using aliases in import cycles) to trip when it otherwise wouldn't.

Unfortunately the dependency on the module is actually required for
correctness in some corner cases, so instead of eliding the import, we
lower its priority. This causes the cycles in the regressions we are
looking at to get processed in the order that works.

This is obviously just a workaround.
@ilevkivskyi ilevkivskyi added the false-positive mypy gave an error on correct code label May 19, 2018
@ilevkivskyi ilevkivskyi self-assigned this Sep 18, 2018
ilevkivskyi added a commit that referenced this issue Sep 21, 2018
Fixes #5275 
Fixes #4498 
Fixes #4442 

This is a simple _band-aid_ fix for `Invalid type` in import cycles where type aliases, named tuples, or typed dicts appear. Note that this is a partial fix that only fixes the `Invalid type` error when a type alias etc. appears in type context. This doesn't fix errors (e.g. `Cannot determine type of X`) that may appear if the type alias etc. appear in runtime context.

The motivation for partial fix is two-fold:
* The error often appears in stub files (especially for large libraries/frameworks) where we have more import cycles, but no runtime context at all.
* Ideally we should refactor semantic analysis to have deferred nodes, and process them in smaller passes when there is more info (like we do in type checking phase). But this is _much_ harder since this requires a large refactoring.  Also an alternative fix of updating node of every `NameExpr` and `MemberExpr` in third pass is costly from performance point of view, and still nontrivial.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-0-high topic-import-cycles
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants