Skip to content
Open
26 changes: 26 additions & 0 deletions tests/test_others.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,32 @@ def main(name: str = typer.Option(..., callback=name_callback)):
assert "value is: Camila" in result.stdout


def test_callback_4_list_none():
app = typer.Typer()

def names_callback(ctx, param, values: typing.Optional[typing.List[str]]):
if values is None:
return values
return [value.upper() for value in values]

@app.command()
def main(
names: typing.Optional[typing.List[str]] = typer.Option(
None, "--name", callback=names_callback
),
):
if names is None:
print("Hello World")
else:
print(f"Hello {', '.join(names)}")

result = runner.invoke(app, ["--name", "Sideshow", "--name", "Bob"])
assert "Hello SIDESHOW, BOB" in result.stdout

result = runner.invoke(app, [])
assert "Hello World" in result.stdout


def test_completion_argument():
file_path = Path(__file__).parent / "assets/completion_argument.py"
result = subprocess.run(
Expand Down
8 changes: 4 additions & 4 deletions typer/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -640,10 +640,10 @@ def convertor(value: Any) -> Any:

def generate_list_convertor(
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
) -> Callable[[Optional[Sequence[Any]]], Optional[List[Any]]]:
def internal_convertor(value: Optional[Sequence[Any]]) -> Optional[List[Any]]:
if value is None or len(value) == 0:
return default_value
Comment on lines -644 to +647
Copy link
Member

@svlandeg svlandeg Dec 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed the check to be more extensive and return default_value any time that value is None or empty. This needed to be updated when fixing the type, or the linter would complain about value possible being None when running the list comprehension.

return [convertor(v) if convertor else v for v in value]

return internal_convertor
Expand Down
Loading