Open KotlinIsland opened 3 years ago
like, in a stub there is no way so specify if a module is actually imported at runtime, or if you are just trying to access a type for type time.
The TYPE_CHECKING
symbol allows you to "lie" to the type checker, effectively making it see something different from the interpreter at runtime. I warn users that they use TYPE_CHECKING
at their own peril because these differences can lead to inconsistencies. Your sample above is one such example but there are many other similar patterns. My recommendation is to avoid using TYPE_CHECKING
if at all possible. For example, using it to avoid circular imports is a really bad justification, IMO. The better approach is to refactor your code to avoid the circular dependency.
In a stub, there is a way to specify that the symbol is exported at runtime. PEP 484 documents a mechanism for this. You do so by using a redundant alias form of import, such as from package.things import Thing as Thing
.
@erictraut I understand those limitations and agree, it was more just to explain the issue. (although an import type
would be very appreciated)
You haven't got the issue with stubs quite right though.
The issue isn't that Thing
is exported or not, look at the example, It's not referencing the Thing
from mod
it's accessing it from package.things
.
The issue is that mypy thinks package.things
is imported(because the stub says from package.things import Thing
), when it isn't, leading to AttributeError: module 'package' has no attribute 'things'
There is no way to specify in a stub that your import is reflected or not at runtime.
given:
entry.py:
mod.py:
In typeshed/bundled stubs: mod.pyi
OR, if this is fake imported in the .py module: mod.py
```py from __future__ import annotations from typing import TYPE_CHECKING if TYPE_CHECKING # do a type import so doesn't cause circular imports or slow down loading from package.things import Thing def func(it: Thing) -> None: ... ```package.things.py
When
mypy --strict entry.py
is executed, no error is generated. Whenpython entry.py
is run:AttributeError: module 'package' has no attribute 'things'
Mypy treats the 'type import' as importing
package.things
, when in reality it isn't. I understand this is consistent with whatTYPE_CHECKING
should do, but seems really sus if you ask me.This more seriously affects typeshed, where all imports are fake and mypy will think all fakely imported modules are really imported.