based on https://github.com/python/typing/issues/105#issuecomment-382969250
Here is the situation.
I have a a.py:
class A():
pass
And I have a b.py:
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from a import A
def foo(a:A):
pass
The directory tree is like :
.
├── __init__.py
├── a.py
└── b.py
When I try to run b.py,I got the error below:
$ python3 ./b.py
Traceback (most recent call last):
File "/Users/will/work/finance/untitled/b.py", line 7, in <module>
def foo(a:A):
NameError: name 'A' is not defined
I am not sure if I use it right.
OS: MacOS 10.13.3
Python version: 3.6.1
The idea of if TYPE_CHECKING is so you can import things only when type checking. At runtime it is False so that you can include code that you only need for type checking, which is done separately from running your code.
So when Python is running your code, it comes to the if TYPE_CHECKING and doesn't execute the import, meaning A in the annotation is not bound to a name. If you don't want to import A, you can prevent Python from evaluating the type annotation A by putting quotes around it:
def foo(a: 'A'):
pass
mypy will still consider the type to be A.
Thanks @ethanhs !!! That helps a lot ~!
If I implement ever annotations of every function, it would cause import chaoes.
Thanks for your help.
Starting with Python 3.7, you could use postponed evaluation of annotations:
# b.py
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from a import A
def foo(a: A):
pass
Most helpful comment
Starting with Python 3.7, you could use postponed evaluation of annotations: