typer
typer copied to clipboard
Using `some_type | None` syntax for type annotations causes error in python 3.11
First Check
- [X] I added a very descriptive title to this issue.
- [X] I used the GitHub search to find a similar issue and didn't find it.
- [X] I searched the Typer documentation, with the integrated search.
- [X] I already searched in Google "How to X in Typer" and didn't find any information.
- [X] I already read and followed all the tutorial in the docs and didn't find an answer.
- [X] I already checked if it is not related to Typer but to Click.
Commit to Help
- [X] I commit to help with one of those options 👆
Example Code
import typer
from datetime import datetime
print(typer.__version__)
app = typer.Typer()
@app.command()
def f(x: datetime | None = None):
print(x)
if __name__ == "__main__":
app()
Description
In python 3.10 this script runs as expected, but on 3.11 I get the following error
Traceback (most recent call last):
File "/Users/pcrein/qdash/test.py", line 16, in <module>
app()
File "/Users/pcrein/.pyenv/versions/qdash-3.11.0/lib/python3.11/site-packages/typer/main.py", line 328, in __call__
raise e
File "/Users/pcrein/.pyenv/versions/qdash-3.11.0/lib/python3.11/site-packages/typer/main.py", line 311, in __call__
return get_command(self)(*args, **kwargs)
^^^^^^^^^^^^^^^^^
File "/Users/pcrein/.pyenv/versions/qdash-3.11.0/lib/python3.11/site-packages/typer/main.py", line 364, in get_command
click_command = get_command_from_info(
^^^^^^^^^^^^^^^^^^^^^^
File "/Users/pcrein/.pyenv/versions/qdash-3.11.0/lib/python3.11/site-packages/typer/main.py", line 577, in get_command_from_info
) = get_params_convertors_ctx_param_name_from_function(command_info.callback)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/pcrein/.pyenv/versions/qdash-3.11.0/lib/python3.11/site-packages/typer/main.py", line 553, in get_params_convertors_ctx_param_name_from_function
click_param, convertor = get_click_param(param)
^^^^^^^^^^^^^^^^^^^^^^
File "/Users/pcrein/.pyenv/versions/qdash-3.11.0/lib/python3.11/site-packages/typer/main.py", line 844, in get_click_param
parameter_type = get_click_type(
^^^^^^^^^^^^^^^
File "/Users/pcrein/.pyenv/versions/qdash-3.11.0/lib/python3.11/site-packages/typer/main.py", line 773, in get_click_type
raise RuntimeError(f"Type not yet supported: {annotation}") # pragma no cover
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: Type not yet supported: datetime.datetime | None
Operating System
macOS
Operating System Details
No response
Typer Version
0.7.0
Python Version
3.11.0
Additional Context
I believe the issue is that for some reason, typing.get_type_hints
is no longer converting the UnionType
into a Union
. I would suggest as a fix that get_click_param
use typing.get_origin/get_args
instead of __args__
and __origin__
attributes.
I'm having the same issue. Using Union[type1, type2]
with from typing import Union
leads to the same error.
@tiangolo, Any updates on this feature?
Related to
- #348
Hi and thanks a lot for this great library!
I've run into this issue as well. May someone provide some guidance on what should be fixed, in case someone would like to contribute to solve it?
I have the same issue with Python 3.10. Any advisory on how to fix this?
Switching from str | None = None
to Optional[str] = None
worked for me.
Switching from
str | None = None
toOptional[str] = None
worked for me.
That is a pretty good workaround, but for me it means that I have to configure my linters one way for modules that use typer and another way for the rest of the code.
Switching from
str | None = None
toOptional[str] = None
worked for me.That is a pretty good workaround, but for me it means that I have to configure my linters one way for modules that use typer and another way for the rest of the code.
pyupgrade will respect type aliases, as will typer. It's unwieldy, but this means you can do the following without having to configure pyupgrade to keep runtime types:
OptionalStr = Optional[str]
main(
foo: OptionalStr = typer.Argument(None),
) -> None:
...
For me, I'd rather use Optional[str]
than making an alias named OptionalStr
(that someone then has to look up to know exactly how it was defined).
I think the idea here is that we ideally want to use str | None
as is the new, preferred style, that pyupgrade/Ruff also lint for.
For me, I'd rather use
Optional[str]
than making an alias namedOptionalStr
(that someone then has to look up to know exactly how it was defined).I think the idea here is that we ideally want to use
str | None
as is the new, preferred style, that pyupgrade/Ruff also lint for.
Agree, for now I've just disabled linting in that specific line, in Ruff you can do it with #noqa: UP007
It would be great to use str | None
instead of Optional[]
. @tiangolo: Any plans to implement this to support >= Python3.11?
I am stuck between Typer not supporting the new python syntax with |None=None
and pyupgrade refusing to add an option to skip code for a specific line. I guess I'll try this solution.....
Switching from
str | None = None
toOptional[str] = None
worked for me.That is a pretty good workaround, but for me it means that I have to configure my linters one way for modules that use typer and another way for the rest of the code.
pyupgrade will respect type aliases, as will typer. It's unwieldy, but this means you can do the following without having to configure pyupgrade to keep runtime types:
OptionalStr = Optional[str] main( foo: OptionalStr = typer.Argument(None), ) -> None: ...
Any updates on this?
@funkindy Waiting for @tiangolo to have time to review the MRs listed here
- https://github.com/tiangolo/typer/issues/678#issuecomment-2090423535
@funkindy Waiting for @tiangolo to have time to review the MRs listed here
- https://github.com/tiangolo/typer/issues/678#issuecomment-2090423535
Obviously @tiangolo either has no time, or has no will.
Hello all! Thanks for the feedback. :coffee:
This should have been fixed by https://github.com/fastapi/typer/pull/548
It is now available in Typer 0.12.4
:rocket:
Hello all! Thanks for the feedback. ☕
This should have been fixed by #548
It is now available in Typer
0.12.4
🚀
Just upgraded to Typer 0.12.4 but still same error:
TypeError: unsupported operand type(s) for |: 'str' and 'NoneType'
@tonjo please create a new discussion filling all the form data, including a minimal reproducible example we can copy and run to see your error.
Doing it with the original issue seems solved, so there's probably something different in your use case.