TCH rules require from __future__ import annotations
The following does not work with 3.11.1 at runtime:
test.py
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from test_b import B
def test(x: B) -> B:
return x
test_b.py
class B:
...
$ python test.py
Traceback (most recent call last):
File "test.py", line 9, in <module>
def test(x: B) -> B:
^
NameError: name 'B' is not defined
but it works when test.py contains from __future__ import annotations.
It might be good to either skip the TCH rules when from __future__ import annotations is not there or mention that this import needs to be added.
Hmm yeah. flake8-type-checking has some things to say about that and additional rules. @sondrelg - I promise I'll stop pinging you, but anything else you'd say about the "right" way to handle this, based on your experience?
Yeah this is correct for all Python version above 3.7 I believe. Ideally ruff should implement TC100, TC101, TC200, and TC201 as these are meant to complement the TC00[1,2,3] rule by telling you how to handle forward references.
What happens we when put an import inside a TYPE_CHECKING block (or any condition that is evaluated as False at runtime) is that the code path is not evaluated, so the import effectively doesn't happen at runtime. Since code outside the condition cannot reference something that isn't defined, we either wrap the undefined values in quotes or add a from __futures__ import annotations since this enables PEP563 behavior.
tl;dr: The TC00[1,2,3] need either the TC1* or TC2* range errors enabled (not both) to guide users into setting up their code in a valid way.
Sorry for not noticing this earlier. I should have warned you about this. And no worries about the pings - happy to help :+1:
This section explains the concepts adequately, I hope: https://github.com/snok/flake8-type-checking#choosing-how-to-handle-forward-references
So for now there is no way to turn TC1/TC2 in ruff?
The code just has to be written I think @RayJameson. There shouldn't be any real blockers in place.
Yup that's right -- we don't support those rules yet, only TC001 - TC005.
I think this specific issue was actually a bug that we fixed around runtime requirements for annotations in function scopes.
(That snippet no longer raises an error.)
Sorry for necroposting, but I've been studying this for the last couple of hours and don't get it. Is from __future__ import annotation needed with these rules or not? If it is, why doesn't ruff add it?