-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
PEP 695 type annotations with lambdas produce false F401 #9159
Comments
Thanks! Agree that we should probably fix this, although I admittedly don't understand how from typing import Annotated
type X = Annotated[int, lambda: re.compile("x")]
print(X.__metadata__) Yields:
|
On the other hand, Ruff correctly does not flag F401 here: from typing import Annotated
X = Annotated[int, lambda: re.compile("x")]
print(X.__metadata__) So I suspect our treatment right be correct. |
Here: >>> from typing import Annotated
>>> import re
>>> type X = Annotated[int, lambda: re.compile("x")]
>>> print(X.__value__.__metadata__)
(<function X.<locals>.<lambda> at 0x7f4df0747f60>,) |
Huh, ok. I will admit that I find |
This example also produces an F401 and has no import re
type X = lambda: re.compile("x")
>>> import re
>>> type X = lambda: re.compile("x")
>>> X.__value__
<function X.<locals>.<lambda> at 0x7f6d4cb30040>
>>> X.__value__()
re.compile('x') |
## Summary This PR is a more holistic fix for #9534 and #9159. When we visit the AST, we track nodes that we need to visit _later_ (deferred nodes). For example, when visiting a function, we defer the function body, since we don't want to visit the body until we've visited the rest of the statements in the containing scope. However, deferred nodes can themselves contain deferred nodes... For example, a function body can contain a lambda (which contains a deferred body). And then there are rarer cases, like a lambda inside of a type annotation. The aforementioned issues were fixed by reordering the deferral visits to catch common cases. But even with those fixes, we still fail on cases like: ```python from __future__ import annotations import re from typing import cast cast(lambda: re.match, 1) ``` Since we don't expect lambdas to appear inside of type definitions. This PR modifies the `Checker` to keep visiting until all the deferred stacks are empty. We _already_ do this for any one kind of deferred node; now, we do it for _all_ of them at a level above.
Minimal reproduction:
Result:
Settings:
Version 0.1.8
The text was updated successfully, but these errors were encountered: