Skip to content

Commit d256026

Browse files
committed
Fix #2164
1 parent 9fcd409 commit d256026

3 files changed

Lines changed: 20 additions & 28 deletions

File tree

src/click/core.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3165,10 +3165,6 @@ def __init__(
31653165

31663166
super().__init__(param_decls, required=required, **attrs)
31673167

3168-
if __debug__:
3169-
if self.default not in (None, UNSET) and self.nargs == -1:
3170-
raise TypeError("'default' is not supported for nargs=-1.")
3171-
31723168
@property
31733169
def human_readable_name(self) -> str:
31743170
if self.metavar is not None:

src/click/parser.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ def process(
204204
)
205205
)
206206

207-
# Unset empty tuple so that a value from the environment may be tried.
208-
if self.nargs == -1 and self.obj.envvar is not None and value == ():
207+
# We failed to collect any argument value so we consider the argument as unset.
208+
if value == ():
209209
value = UNSET
210210

211211
state.opts[self.dest] = value # type: ignore

tests/test_arguments.py

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,6 @@ def copy(src, dst):
2020
assert result.output.splitlines() == ["src=foo.txt|bar.txt", "dst=dir"]
2121

2222

23-
def test_argument_unbounded_nargs_cant_have_default(runner):
24-
with pytest.raises(TypeError, match="nargs=-1"):
25-
26-
@click.command()
27-
@click.argument("src", nargs=-1, default=["42"])
28-
def copy(src):
29-
pass
30-
31-
3223
def test_nargs_tup(runner):
3324
@click.command()
3425
@click.argument("name", nargs=1)
@@ -379,26 +370,31 @@ def cmd(a, b, c):
379370

380371

381372
@pytest.mark.parametrize(
382-
("args", "default", "expected"),
373+
("argument_params", "args", "expected"),
383374
[
384375
# Any iterable with the same number of arguments as nargs is valid.
385-
[[], (1, 2), (1, 2)],
386-
[[], (1.1, 2.2), (1, 2)],
387-
[[], ("1", "2"), (1, 2)],
388-
[[], (None, None), (None, None)],
389-
[[], [1, 2], (1, 2)],
390-
[[], {1, 2}, (1, 2)],
391-
[[], frozenset([1, 2]), (1, 2)],
392-
[[], {1: "a", 2: "b"}, (1, 2)],
376+
[{"nargs": 2, "default": (1, 2)}, [], (1, 2)],
377+
[{"nargs": 2, "default": (1.1, 2.2)}, [], (1, 2)],
378+
[{"nargs": 2, "default": ("1", "2")}, [], (1, 2)],
379+
[{"nargs": 2, "default": (None, None)}, [], (None, None)],
380+
[{"nargs": 2, "default": [1, 2]}, [], (1, 2)],
381+
[{"nargs": 2, "default": {1, 2}}, [], (1, 2)],
382+
[{"nargs": 2, "default": frozenset([1, 2])}, [], (1, 2)],
383+
[{"nargs": 2, "default": {1: "a", 2: "b"}}, [], (1, 2)],
393384
# Empty iterable is valid if default is None.
394-
[[], None, None],
385+
[{"nargs": 2, "default": None}, [], None],
395386
# Arguments overrides the default.
396-
[["3", "4"], (1, 2), (3, 4)],
387+
[{"nargs": 2, "default": (1, 2)}, ["3", "4"], (3, 4)],
388+
# Unbounded arguments are allowed to have a default.
389+
# See: https://github.com/pallets/click/issues/2164
390+
[{"nargs": -1, "default": [42]}, [], (42,)],
391+
[{"nargs": -1, "default": None}, [], ()],
392+
[{"nargs": -1, "default": {1, 2, 3, 4, 5}}, [], (1, 2, 3, 4, 5)],
397393
],
398394
)
399-
def test_good_defaults_for_nargs(runner, args, default, expected):
395+
def test_good_defaults_for_nargs(runner, argument_params, args, expected):
400396
@click.command()
401-
@click.argument("a", nargs=2, type=int, default=default)
397+
@click.argument("a", type=int, **argument_params)
402398
def cmd(a):
403399
click.echo(repr(a), nl=False)
404400

0 commit comments

Comments
 (0)