Experimental Union Support (Request for a Pull Request) #1855
hsaeed3
started this conversation in
Show and tell
Replies: 1 comment 2 replies
-
|
Hi @hsaeed3! Thanks for opening the discussion and for the detailed proposal. At this point in time, it wouldn't be a good idea to open a PR for this, as we're actively working on refactoring type resolvement in Typer. You'd inevitably end up with (a lot of) conflicts with that ongoing work. At this point we're trying to move this forward with the core maintainer's team, and once it's stable we'll definitely welcome further feedback/improvements on it. Your point about union support is definitely valid though, and we'll keep this in mind as we continue our refactor as well 🙏 . Will update here if there's more concrete news! |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
FORK / BRANCH LOCATION: HERE
Upon the tears of many who had fallen before (such as the valiant efforts of PR #1719), I too yearned as a child for union annotation support within typer.
I've created a fork and implementation for union support, which currently passes all requirements for a valid pull request, but as the template mentions, I wanted to ensure everything was put together properly before opening a PR.
Problem
The goal was to provide union support in the least invasive manner possible while providing a centralized location to access and modify all associated logic.
Today, something like value: int | str fails unless it collapses to a single non-None member (e.g.
int | None). That's a sensible default, but it blocks a common CLI pattern: accept a numeric id or a slug, a Literal choice or a freeform string, and so on.Approaches Considered
experimental_union_typesontyper.Typer()— way too broad; one switch for the whole app.union_type: boolonOption()/Argument()— union-ness belongs to the annotation, not each parameter declaration. (Felt finicky to me from a developer's perspective, but I do have a relatively complete implementation in this pattern that can replace the current content of the branch.union_types=Trueon@app.command()/@app.callback()— what I landed on: opt-in per command, logic centralized in a single internal module.int | Noneand similar single-member optionals keep working as they do today—no flag needed.Branch Content
The feature functionality itself is centralized within
typer/_union_types.pyand requires at the moment minimal intersection with only thetyper/main.pymodule.• Union parsing, help/metavars, and error messages via a dedicated helper module
• Shell autocomplete across union members
• Shell error & missing messages show choices in readable structure similar to
Literal• Tests with 100% coverage on the helper
typer/_union_types.py(still room to compact the implementation itself)• Docs with
"termy"runtime examples for help, completion, and errorsNested unions and list/tuple members are out of scope for now.
Further Questions
Beta Was this translation helpful? Give feedback.
All reactions