diff --git a/docs/tutorial/multiple-values/multiple-options.md b/docs/tutorial/multiple-values/multiple-options.md index 00754e93b4..d61bee1588 100644 --- a/docs/tutorial/multiple-values/multiple-options.md +++ b/docs/tutorial/multiple-values/multiple-options.md @@ -26,9 +26,10 @@ Check it:
```console +// The default value is 'None' $ python main.py -No provided users +No provided users (raw input = None) Aborted! // Now pass a user diff --git a/docs_src/multiple_values/multiple_options/tutorial001.py b/docs_src/multiple_values/multiple_options/tutorial001.py index 141e9aa1ce..bce2322915 100644 --- a/docs_src/multiple_values/multiple_options/tutorial001.py +++ b/docs_src/multiple_values/multiple_options/tutorial001.py @@ -5,7 +5,7 @@ def main(user: Optional[List[str]] = typer.Option(None)): if not user: - print("No provided users") + print(f"No provided users (raw input = {user})") raise typer.Abort() for u in user: print(f"Processing user: {u}") diff --git a/docs_src/multiple_values/multiple_options/tutorial001_an.py b/docs_src/multiple_values/multiple_options/tutorial001_an.py index 68ad2519ea..3dd19d8f59 100644 --- a/docs_src/multiple_values/multiple_options/tutorial001_an.py +++ b/docs_src/multiple_values/multiple_options/tutorial001_an.py @@ -6,7 +6,7 @@ def main(user: Annotated[Optional[List[str]], typer.Option()] = None): if not user: - print("No provided users") + print(f"No provided users (raw input = {user})") raise typer.Abort() for u in user: print(f"Processing user: {u}") diff --git a/tests/test_tutorial/test_multiple_values/test_multiple_options/test_tutorial001.py b/tests/test_tutorial/test_multiple_values/test_multiple_options/test_tutorial001.py index 3c57bfd33e..4293ed8d3d 100644 --- a/tests/test_tutorial/test_multiple_values/test_multiple_options/test_tutorial001.py +++ b/tests/test_tutorial/test_multiple_values/test_multiple_options/test_tutorial001.py @@ -15,6 +15,7 @@ def test_main(): result = runner.invoke(app) assert result.exit_code != 0 assert "No provided users" in result.output + assert "raw input = None" in result.output assert "Aborted" in result.output diff --git a/tests/test_tutorial/test_multiple_values/test_multiple_options/test_tutorial001_an.py b/tests/test_tutorial/test_multiple_values/test_multiple_options/test_tutorial001_an.py index 0009fd2f05..20ea235307 100644 --- a/tests/test_tutorial/test_multiple_values/test_multiple_options/test_tutorial001_an.py +++ b/tests/test_tutorial/test_multiple_values/test_multiple_options/test_tutorial001_an.py @@ -15,6 +15,7 @@ def test_main(): result = runner.invoke(app) assert result.exit_code != 0 assert "No provided users" in result.output + assert "raw input = None" in result.output assert "Aborted" in result.output diff --git a/typer/main.py b/typer/main.py index 9de5f5960d..271500b5e9 100644 --- a/typer/main.py +++ b/typer/main.py @@ -631,9 +631,11 @@ def convertor(value: Any) -> Any: def generate_list_convertor( - convertor: Optional[Callable[[Any], Any]] -) -> Callable[[Sequence[Any]], List[Any]]: - def internal_convertor(value: Sequence[Any]) -> List[Any]: + convertor: Optional[Callable[[Any], Any]], default_value: Optional[Any] +) -> Callable[[Sequence[Any]], Optional[List[Any]]]: + def internal_convertor(value: Sequence[Any]) -> Optional[List[Any]]: + if default_value is None and len(value) == 0: + return None return [convertor(v) if convertor else v for v in value] return internal_convertor @@ -852,7 +854,9 @@ def get_click_param( ) convertor = determine_type_convertor(main_type) if is_list: - convertor = generate_list_convertor(convertor) + convertor = generate_list_convertor( + convertor=convertor, default_value=default_value + ) if is_tuple: convertor = generate_tuple_convertor(main_type.__args__) if isinstance(parameter_info, OptionInfo):