doit icon indicating copy to clipboard operation
doit copied to clipboard

Default values for param of type list not being overridden.

Open joshuajorel opened this issue 2 years ago • 1 comments

Hi,

When using a param of type list and adding default values in the definition of the param, when invoking the task with list values you specified in the command line, it does not create a new list, but appends to the default list.

doit.py

from doit import task_params

@task_params([{'name': 'some_list', 'type': list, 'default': ['item1', 'item2'], 'short': 'l'}])
def task_list_with_duplicates(some_list):
    for l in some_list:
        yield {
            'name': f'name_of_list_{l}',
            'actions': [f'echo "some action on list {l}"'],
            'verbosity': 2
        }

Execution

> doit list_with_duplicates -l item1
ERROR: Task generation 'list_with_duplicates' has duplicated definition of 'list_with_duplicates:name_of_list_item1'

Environment

  1. OS: MacOS 11.6.8
  2. python version: 3.9.12
  3. doit version: 0.36.0
Fund with Polar

joshuajorel avatar Aug 11 '22 15:08 joshuajorel

I think I just ran into something similar which is, I think, actually the root cause issue here: if an action generator uses yield to generate tasks the params are ignored.

For example, given the following

from doit import task_params

@task_params([
    {'name': 'version', 'long': 'version', 'default': 'v10'},
])
def task_testing(version):
    print('version:', version)
    return {
        'actions': [f'echo {version}'],
        'verbosity': 2,
    }

It works as expected:

$ doit testing --version=hello
version: hello
.  testing
hello

But change it to this:

from doit import task_params

@task_params([
    {'name': 'version', 'long': 'version', 'default': 'v10'},
])
def task_testing(version):
    print('version:', version)
    yield {
        'basename': 'test',
        'actions': [f'echo {version}'],
        'verbosity': 2,
    }

and it ignores the command line argument:

$ doit test --version=hello
version: v10
.  test
v10

You can get it to work again by putting the CLI args on the yielded task:

from doit import task_params

def task_testing():
    yield {
        'basename': 'test',
        'actions': ['echo %(version)s'],
        'verbosity': 2,
        'params': [
            {'name': 'version', 'long': 'version', 'default': 'v10'},
        ],
    }

which works:

$ doit test --version=hello
.  test
hello

But it has some drawbacks as the CLI argument isn't available as a regular Python variable so you can't use it except in the few places doit will expand it (e.g. you couldn't use it in an f-string to generate a title).

oliverdain avatar Aug 19 '22 00:08 oliverdain