Skip to content
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

Using some_type | None syntax for type annotations causes error in python 3.11 #533

Open
7 tasks done
PhilReinhold opened this issue Jan 12, 2023 · 12 comments · May be fixed by #548 or #676
Open
7 tasks done

Using some_type | None syntax for type annotations causes error in python 3.11 #533

PhilReinhold opened this issue Jan 12, 2023 · 12 comments · May be fixed by #548 or #676
Labels
bug Something isn't working

Comments

@PhilReinhold
Copy link

First Check

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn't find it.
  • I searched the Typer documentation, with the integrated search.
  • I already searched in Google "How to X in Typer" and didn't find any information.
  • I already read and followed all the tutorial in the docs and didn't find an answer.
  • I already checked if it is not related to Typer but to Click.

Commit to Help

  • 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.

@PhilReinhold PhilReinhold added the question Question or problem label Jan 12, 2023
@domef
Copy link

domef commented Jan 13, 2023

I'm having the same issue. Using Union[type1, type2] with from typing import Union leads to the same error.

@jonaslb jonaslb linked a pull request Feb 4, 2023 that will close this issue
@raminqaf
Copy link

raminqaf commented Apr 4, 2023

@tiangolo, Any updates on this feature?

@johnthagen
Copy link

Related to

@pdonorio
Copy link

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?

@renardeinside
Copy link

I have the same issue with Python 3.10. Any advisory on how to fix this?

@lucasgadams
Copy link

Switching from str | None = None to Optional[str] = None worked for me.

@toppk
Copy link

toppk commented Aug 6, 2023

Switching from str | None = None to Optional[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.

@roganartu
Copy link

Switching from str | None = None to Optional[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:
    ...

@johnthagen
Copy link

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.

fstagni added a commit to fstagni/diracx that referenced this issue Sep 4, 2023
fstagni added a commit to fstagni/diracx that referenced this issue Sep 5, 2023
fstagni added a commit to fstagni/diracx that referenced this issue Sep 6, 2023
fstagni added a commit to fstagni/diracx that referenced this issue Sep 6, 2023
fstagni added a commit to fstagni/diracx that referenced this issue Sep 8, 2023
@standag standag linked a pull request Oct 3, 2023 that will close this issue
@albertotb
Copy link

albertotb commented Dec 11, 2023

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.

Agree, for now I've just disabled linting in that specific line, in Ruff you can do it with #noqa: UP007

@exislow
Copy link

exislow commented Jan 12, 2024

It would be great to use str | None instead of Optional[]. @tiangolo: Any plans to implement this to support >= Python3.11?

@dolfandringa
Copy link

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 to Optional[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:
    ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet