Skip to content

[FEATURE] Define choices via dictionary instead of enum #241

Description

@codethief

I have a (dynamic) dictionary mapping strings (names) to more complicated objects. I want to define a Typer argument (or option) that allows the user to choose one of those objects by providing the corresponding name.

The solution I would like

Pseudo-code:

networks: Dict[str, NeuralNetwork] = {}
# <Add entries to networks here>

def main(
    network: NeuralNetwork = typer.Argument(choices=networks)
):
    ...

Basically, I would like to tell Typer to use the dictionary's string keys as the possible values the user can choose from on the command line and then map them to the corresponding NeuralNetwork object when invoking main().

Alternatives I've considered

Since Typer currently doesn't support Union types (let alone dynamically created ones), the only alternative with proper type checking and auto-completion that I've found is the following:

networks: Dict[str, NeuralNetwork] = {}
# <Add entries to networks here>

# Use Enum's functional interface to dynamically create one
NetworkEnum = Enum(
    "NetworkEnum",
    names=[ (name, network) for name, network in networks.items() ],  // EDIT: This needs to read (name, name), see vincentqb's comment below
    module=__name__,
)

def main(
    network: NetworkEnum
):
    the_network = networks[network.value]
    ...

While this works, it requires boilerplate code and is much less readable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions