typer
typer copied to clipboard
How to input an iterable as a required command-line option when prompted?
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
app = typer.Typer()
@app.command()
def set_roles(
single: str = typer.Option(..., prompt=True),
multiple: list[str] = typer.Option(None, prompt=True),
):
typer.echo(f"{single}")
typer.echo(f"{multiple}")
if __name__ == "__main__":
app()
Description
When I run the example without passing any arguments, I cannot pass multiple arguments to the prompt for multiple
that satisfies the script. How must I format these at the prompt?
Example:
> python example.py
Single: one
Multple: one, two
Error: Value must be an iterable.
Multple: one two
Error: Value must be an iterable.
Multple: "one" "tow"
Error: Value must be an iterable.
Multple: "one,two"
Error: Value must be an iterable.
Multple: one
Error: Value must be an iterable.
Multple: one
Error: Value must be an iterable.
Multple: "one"
Error: Value must be an iterable.
Multple: [one, two]
Error: Value must be an iterable.
Multple: ["one", "two"]
Error: Value must be an iterable.
Multple: "['one','two']
Error: Value must be an iterable.
Operating System
macOS
Operating System Details
No response
Typer Version
0.4.0
Python Version
Python 3.10.1
Additional Context
No response
Hey
Any update on that?
Any update?
No Updates so far. One solutions I could think of is to use the rich implementation instead of the default click one. - Maybe this would work as expected and can handle the lists Just a thought - did not really played around with that yet
Also having this issue. Was trying to track down where the prompt is being generated from, and it may be underlying behaviour from Click
https://click.palletsprojects.com/en/8.0.x/options/#prompting
It is advised that prompt not be used in conjunction with the multiple flag set to True. Instead, prompt in the function interactively.
From some debugging - seems the source of the error is here.... https://github.com/pallets/click/blob/5e75fe7f9c1b820d71f482599cd6996523332d06/src/click/core.py#L2271
def check_iter(value: t.Any) -> t.Iterator:
try:
return _check_iter(value)
except TypeError:
# This should only happen when passing in args manually,
# the parser should construct an iterable when parsing
# the command line.
raise BadParameter(
_("Value must be an iterable."), ctx=ctx, param=self
) from None
def _check_iter(value: t.Any) -> t.Iterator[t.Any]:
"""Check if the value is iterable but not a string. Raises a type
error, or return an iterator over the value.
"""
if isinstance(value, str):
raise TypeError
return iter(value)
Seems that in the case of 'option with prompt' - seems like the arg will always come through as str and fail here.
I managed to use typer.prompt() to set a default of [] and convert to a list (for storage in a configparser file) using eval(input). - e.g. input the following on the command line...
['param1','param21','param3']
Not happy about it, as the input experience is brittle, and becomes 'interactive' by using typer.prompt - but it's functional. Would be good if more of Click's underlying functionality around types / specific parsers could be surfaced in Typer.