typer icon indicating copy to clipboard operation
typer copied to clipboard

Multiple arguments with multiple values raises an error from Click

Open erdnaxeli opened this issue 4 years ago • 6 comments

Describe the bug

Hi, I tried to define two arguments as List[str], and I got an exception from Click.

To Reproduce

  • Create a file main.py with:
from typing import List
import typer

app = typer.Typer()

@app.command()
def hello(name: List[str], other: List[str]):
    typer.echo(f"Hello {name}")


if __name__ == "__main__":
    app()
  • Call it with:
python main.py Camila
  • It outputs:
Traceback (most recent call last):
  File "/home/erdnaxeli/t.py", line 12, in <module>
    typer.run(create)
  File "/home/erdnaxeli/.pyenv/versions/3.6.7/lib/python3.6/site-packages/typer/main.py", line 859, in run
    app()
  File "/home/erdnaxeli/.pyenv/versions/3.6.7/lib/python3.6/site-packages/typer/main.py", line 214, in __call__
    return get_command(self)(*args, **kwargs)
  File "/home/erdnaxeli/.pyenv/versions/3.6.7/lib/python3.6/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/home/erdnaxeli/.pyenv/versions/3.6.7/lib/python3.6/site-packages/click/core.py", line 781, in main
    with self.make_context(prog_name, args, **extra) as ctx:
  File "/home/erdnaxeli/.pyenv/versions/3.6.7/lib/python3.6/site-packages/click/core.py", line 700, in make_context
    self.parse_args(ctx, args)
  File "/home/erdnaxeli/.pyenv/versions/3.6.7/lib/python3.6/site-packages/click/core.py", line 1045, in parse_args
    opts, args, param_order = parser.parse_args(args=args)
  File "/home/erdnaxeli/.pyenv/versions/3.6.7/lib/python3.6/site-packages/click/parser.py", line 270, in parse_args
    self._process_args_for_args(state)
  File "/home/erdnaxeli/.pyenv/versions/3.6.7/lib/python3.6/site-packages/click/parser.py", line 278, in _process_args_for_args
    state.largs + state.rargs, [x.nargs for x in self._args]
  File "/home/erdnaxeli/.pyenv/versions/3.6.7/lib/python3.6/site-packages/click/parser.py", line 67, in _unpack_args
    raise TypeError("Cannot have two nargs < 0")
TypeError: Cannot have two nargs < 0

Expected behavior

I know wat I am doing cannot work, but I expect either:

  • an undefined behavior (like always having an error about missing argument other because name swallow all parameters)
  • or an explicte error from typer

The error from Click is not very explicit.

  • OS: Linux
  • Typer Version: 0.3.2
  • Python version: 3.6.7

erdnaxeli avatar Apr 02 '21 20:04 erdnaxeli

I still get this behavior with

  • click==8.1.3
  • typer==0.6.1

dyollb avatar Oct 28 '22 13:10 dyollb

but a workaround is to provide default empty lists:

def generate_dataset(
    image_dir: List[Path] = [],
    labels_dir: List[Path] = [],
): 
  pass

dyollb avatar Oct 28 '22 13:10 dyollb

Hi, was there any resolution to this?

dthiagarajan avatar Dec 21 '22 22:12 dthiagarajan

For me the workaround above was ok. If you want to force a minimum of one item in the list, the options must be required. This can be achieved using following strategy:

def generate_dataset(
    image_dir: List[Path] = typer.Option(...), 
    labels_dir: List[Path] = typer.Option(...),
):
    pass

dyollb avatar Dec 22 '22 09:12 dyollb