Skip to content

Modifying default_map in callback behaves differently between click 7.1.2 and 8.0.0 #2745

@dezsiszabi

Description

@dezsiszabi

Hi,

I'm trying to upgrade an application from click 7 to click 8 but I'm running into issues.
I was able to reduce the issue to a minimal reproducible example.

The following program behaves differently in 7.1.2 and 8.0.0

import click

def load_settings(ctx, param, value):
    # breakpoint()
    if (value is not None):
        ctx.default_map['general_foo'] = value + 'foo'
        ctx.default_map['general_bar'] = value + 'bar'

def sanitize_foo(ctx, param, val):
    click.echo('sanitizing foo')
    return val

def sanitize_bar(ctx, param, val):
    click.echo('sanitizing bar')
    return val

def print_help(ctx, param, value):
    if value:
        ctx.exit()

@click.command()
@click.option('--general-foo', '--foo', default=None, nargs=2, callback=sanitize_foo)
@click.option('--general-bar', '--bar', default=None, callback=sanitize_bar)
@click.option('--settings', callback=load_settings, default=None, is_eager=True)
@click.pass_context
def hello(ctx, settings, general_bar, general_foo):
    click.echo(general_foo)
    click.echo(general_bar)

@click.group()
@click.option('--settings', hidden=True)
@click.pass_context
def cli(ctx, settings):
    ctx.default_map['hello'] = { 'settings': settings }

cli.add_command(hello)

if __name__ == '__main__':
    cli(default_map={})

In click 7.1.2:

(.venv) dezsiszabi@SZABI-PC:~/projects/click-test$ python3 main.py hello --settings hello
sanitizing foo
sanitizing bar
('h', 'e', 'l', 'l', 'o', 'f', 'o', 'o')
hellobar

In click 8.0.0 (and later):

(.venv) dezsiszabi@SZABI-PC:~/projects/click-test$ python3 main.py hello --settings hello
Usage: main.py hello [OPTIONS]
Try 'main.py hello --help' for help.

Error: Invalid value for '--general-foo' / '--foo': Value must be an iterable.

I assume this difference was introduced intentionally, but I'm having a hard time adapting my code and even after reading the changelog multiple times I'm not sure which change in 8.0.0 is causing it exactly.

Note: the application is basically trying to do this https://jwodder.github.io/kbits/posts/click-config/
I assume the original developer of the application used this guide as well, but unfortunately this is now breaking with 8.0.0 :)

Any help is appreciated.

Environment:

  • Python version: 3.12.3
  • Click version: 8.0.0 to latest

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions