typer
typer copied to clipboard
PEP 604 Support
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
from pathlib import Path
import typer
def main(output: Path | None):
typer.guess_name(f"Hello {name}")
if __name__ == "__main__":
typer.run(main)
Description
Using an argument with the type of pathlib.Path | None
(as per PEP 604) raise the error:
Type not yet supported: pathlib.Path | None
Wanted Solution
| None
types should work instead of having to need to use Optional[]
.
Wanted Code
from pathlib import Path
import typer
def main(output: Path | None):
typer.echo(output)
if __name__ == "__main__":
typer.run(main)
Alternatives
No response
Operating System
Linux
Operating System Details
No response
Typer Version
0.4.0
Python Version
3.10.1
Additional Context
No response
I'm thinking if you can do this output: Path = None
? When you have Path | None
, the function expects either Path
or None
to be passed. This is the case even if you use Optional[]
without setting a default value type.
Plus I believe Typer is tested for up to Python 3.9. This means most of the features from Python 3.10 might not work as expected. Let's just say certain recursive dependencies used by Typer also might have similar troubles.
+1
Even using Python 3.10 without the __future__
imports PEP 604 isn't supported.
@tiangolo Are there any plans to support this in the near future?
Could this be more of a Pydantic issue?
@navhits I'm not exactly sure what you mean. Pydantic supports PEP 604 type hints.
If that's the case, then try building from python3.10 branch. In my understanding 604 is a 3.10 focussed enhancement.
Ok. There's a 0.4.1 release already. Try this version @SRv6d
I've been on that version since march.
Seems this is still broken as of 0.7.0, even though that release is supposed to support Python 3.11 (and therefore I assumed these new type annotations included with Python3.10)
Yeps, running into this as well.
As we have pyupgrade
in place enforcing PEP 604, I am in an awkward situation 🤔
As we have pyupgrade in place
Make them standalone types and pyupgrade will not change it. Or exclude the file from pyupgrade (your CLI interface is separated from the rest of your app, right?).
PathOrNone = Path | None
def main(output: PathOrNone):
typer.guess_name(f"Hello {name}")
As we have pyupgrade in place
Make them standalone types and pyupgrade will not change it. Or exclude the file from pyupgrade (your CLI interface is separated from the rest of your app, right?).
PathOrNone = Path | None def main(output: PathOrNone): typer.guess_name(f"Hello {name}")
Last I tried, making them standalone types would still give errors in typer
, as it just doesn't support the new union notation at all. If you pass it a standalone type, it'll just go through an extra hop to get the types that are in an union in the standalone type, and then fail again because it doesn't understand |
Sorry, bad example, I just woke up. 😂
PathOrNone = Optional[Path]
def main(output: PathOrNone):
typer.guess_name(f"Hello {name}")
pyupgrade should not change Optional[]
type aliases.
PathOrNone = Optional[Path]
Nice one, thanks!
Since the PR doesn't link to this issue, I'll link it here. This PR appears to be trying to fix this issue:
- https://github.com/tiangolo/typer/pull/522
For visibility, the current open PR for this issue is
- #676
Confirmed that either #676 or #548 will fix this issue!