Currently the TCH (flake8-type-checking) rules require annotations to be stored as strings (i.e. not evaluated). Annotations are stored a strings if:
- The annotations are string literals (i.e. are quoted)
- The annotations are in a module with
from __future__ import annotations (which causes evaluation of all annotations in the module to be skipped)
- The annotations are of local variables (the Python interpreter does not evaluate local variable annotations)
One approach to getting TCH autofix working is to inject from __future__ import annotations into all your source modules (using I002). This is not ideal because string annotations unavoidably break code that meets these conditions:
- annotations are being created in a local scope
- an annotation references a symbol only available in that local scope
- the annotation must be operated on at runtime
Here is an example of code meeting these conditions:
def make_bar():
class Bar:
...
def bar(x: "Bar"):
...
return bar
bar = make_bar()
# `bar` has a string annotation-- if we want to operate on it, we need to evaluate it. This requires
# calling `get_type_hints`, but this fails because "Bar" can't be dereferenced since referent `Bar`
# vanished with local scope
get_type_hints(bar) # => NameError: name 'Bar' is not defined.
We have plenty of code meeting these conditions in Dagster (mostly in tests), so my experiment in injecting from __future__ import annotations to enable TCH autofix has failed. Other projects that use runtime type annotation introspection are likely to encounter the same issues.
Therefore, a significant enhancement to TCH autofix would be to detect where annotations could be stored as strings, and perform a targeted conversion for you using quoting. Example:
from threading import Lock
def foo(lock: Lock):
...
After applying TCH autofix:
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from threading import Lock
def foo(lock: "Lock"):
...
This would make TCH autofix a lot more useful for us and probably many other projects.
Currently the
TCH(flake8-type-checking) rules require annotations to be stored as strings (i.e. not evaluated). Annotations are stored a strings if:from __future__ import annotations(which causes evaluation of all annotations in the module to be skipped)One approach to getting
TCHautofix working is to injectfrom __future__ import annotationsinto all your source modules (usingI002). This is not ideal because string annotations unavoidably break code that meets these conditions:Here is an example of code meeting these conditions:
We have plenty of code meeting these conditions in Dagster (mostly in tests), so my experiment in injecting
from __future__ import annotationsto enableTCHautofix has failed. Other projects that use runtime type annotation introspection are likely to encounter the same issues.Therefore, a significant enhancement to
TCHautofix would be to detect where annotations could be stored as strings, and perform a targeted conversion for you using quoting. Example:After applying
TCHautofix:This would make
TCHautofix a lot more useful for us and probably many other projects.