pallets / click

Python composable command line interface toolkit

Home Page:https://click.palletsprojects.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unexposed option name is `None` when the parameter name is not a python identifier

azmeuk opened this issue · comments

I would like to have dots in option names. As click requires option names to be valid python identifiers, I would like to use unexposed options to make dots in option names possible, and a custom callback to store the option name somewhere:

import click


def option_callback(ctx, param, value):
    ctx.ensure_object(dict)
    ctx.obj.setdefault("params", {})[param.name] = value

    return value


@click.command()
@click.option("--foo.foo", expose_value=False, callback=option_callback)
@click.option("--bar-bar", expose_value=False, callback=option_callback)
@click.pass_obj
def cli(obj):
    click.echo(obj["params"])


if __name__ == "__main__":  # pragma: no cover
    cli()

In that situation, in the callback context, option.name is None if the original option name is not a valid identifier:

$ python example.py --foo.foo baz --bar-bar baz
{None: 'baz', 'bar_bar': 'baz'}

I suppose this is due to those lines:

click/src/click/core.py

Lines 2594 to 2595 in 99015e1

if not expose_value:
return None, opts, secondary_opts

Ideally I would love a simple way to use non identifier option names, like proposed in #2433.
In the meantime I would suggest to allow Option.name to have its original value instead of None for unexposed option. I would volunteer for a PR if this is accepted.

What do you think?

  • Python version: 3.12
  • Click version: 8.1.7