-
Notifications
You must be signed in to change notification settings - Fork 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
UP007 false negative with quoted type #5706
Comments
I think this follows pyupgrade’s behavior, but I need to look into if that’s true, and why. |
I think this is the correct behavior (in some cases). E.g., this fails for me on 3.11: from typing import Optional
def foo(_: "myclass" | None):
pass With: Traceback (most recent call last):
File "/Users/crmarsh/workspace/ruff/foo.py", line 4, in <module>
def foo(_: "myclass" | None):
~~~~~~~~~~^~~~~~
TypeError: unsupported operand type(s) for |: 'str' and 'NoneType' However, it's sometimes okay, e.g. this is fine: from typing import Optional
class MyClass:
pass
def foo():
x: "MyClass" | None = MyClass()
foo() But this is not: from typing import Optional
class MyClass:
pass
def foo():
x: "MyClass" | None = MyClass()
def bar(x: "MyClass" | None):
pass
foo() It has to do with when Python evaluates annotations at runtime (e.g., any parameters to functions need to be evaluated at runtime because they get added to |
## Summary Python doesn't allow `"Foo" | None` if the annotation will be evaluated at runtime (see the comments in the PR, or the semantic model documentation for more on what this means and when it is true), but it _does_ allow it if the annotation is typing-only. This, for example, is invalid, as Python will evaluate `"Foo" | None` at runtime in order to populate the function's `__annotations__`: ```python def f(x: "Foo" | None): ... ``` This, however, is valid: ```python def f(): x: "Foo" | None ``` As is this: ```python from __future__ import annotations def f(x: "Foo" | None): ... ``` Closes #5706.
## Summary Python doesn't allow `"Foo" | None` if the annotation will be evaluated at runtime (see the comments in the PR, or the semantic model documentation for more on what this means and when it is true), but it _does_ allow it if the annotation is typing-only. This, for example, is invalid, as Python will evaluate `"Foo" | None` at runtime in order to populate the function's `__annotations__`: ```python def f(x: "Foo" | None): ... ``` This, however, is valid: ```python def f(): x: "Foo" | None ``` As is this: ```python from __future__ import annotations def f(x: "Foo" | None): ... ``` Closes #5706.
UP007 won't recognize cases like
While it recognizes
reproduces with 0.0.277 and on the playground
The text was updated successfully, but these errors were encountered: