-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
PEP 604 Union syntax does not support forward references #90015
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
Comments
The class methods have a problem compiling when the type refers to the union of itself and others. # tmp.py
class Foo:
def __init__(self, tmp: "Foo"|int):
pass # Error
Traceback (most recent call last):
File "/Project/Mslc/Grammar/tmp.py", line 1, in <module>
class Foo:
File "/Project/Mslc/Grammar/tmp.py", line 2, in Foo
def __init__(self, tmp: "Foo"|int):
TypeError: unsupported operand type(s) for |: 'str' and 'type' |
Reproduced on 3.11. The error occurs if a type is on the left-hand-side of the operand, as well as if a type is on the right-hand-side:
|
Presumably the correct way to do this is: def __init__(self, tmp: "Foo|int"): That is, the entire type hint is a string. |
Arguably, either the implementation should be altered to support forward references, or the documentation at https://docs.python.org/3/library/stdtypes.html#union-type should be altered to make clear that, when type-hinting a union that includes a forward reference, the entire expression should be given as a string, as Eric suggests. |
I think I saw a similar bug report elsewhere (or maybe I'm misremembering). Anyways, Eric is right, the correct way is to wrap the entire thing, so "Foo|int" instead of "Foo"|int. @alex you brought up some good suggestions, I'll try to address them:
Unfortunately that's more complex than it seems. The original draft PEP-604 proposed implementation actually imported Union from typing.py, and I recall Guido disliking the idea that a builtin type should depend on typing.py. I have to agree with that philosophy here. I also don't think the alternative -- implementing a builtin ForwardRef type isn't worth the complexity unless our situation changes.
The first line says: "A union object holds the value of the | (bitwise or) operation on multiple type objects." It says *type objects*, which strings don't belong to. @tnthung does Eric's suggestion work for you? Or do you need something else? |
Thanks, Ken! To clarify: I agree that changing the implementation here would probably be a bad way to go: it would be foolish to try to replicate all the functionality of the typing module as builtins. I also think the existing documentation at https://docs.python.org/3/library/stdtypes.html#union-type is actually very good, so I don't think it needs a fundamental rewrite by any means. I do still think a sentence or two could be added to the documentation, however, clarifying how to deal with forward references, since the behaviour here is different to the older, more established syntax using typing.Union. Something like this? """ |
I have a related question about how type aliases should work. Starting with
With the new
The following is also invalid:
Putting everything in a string seems wrong to me, because it's not evaluated as a type:
I would suggest enhancing
Thoughts? |
You should never use Instead, use from typing import TypeAlias
Alias: TypeAlias = 'str | Foo' |
Ah, thanks. |
Is there some way to evaluate |
Alas not. I think earlier in the thread it was suggested that it would be a bad idea to change the runtime implementation, so we're probably stuck with this, unless you have a compelling (i.e., real-world) use case that needs to handle this. |
The easy workaround is to continue to use |
…eferences (pythonGH-105366) (cherry picked from commit fbdee00) Co-authored-by: Alex Waygood <[email protected]>
…eferences (pythonGH-105366) (cherry picked from commit fbdee00) Co-authored-by: Alex Waygood <[email protected]>
We've now documented that PEP-604 aliases do not support forward references at runtime. @pbryan, you may be interested in the new https://docs.python.org/3.13/library/typing.html#type-aliases |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
Linked PRs
The text was updated successfully, but these errors were encountered: