You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
The leftover arguments are empty in Click 6.0 Context #473
@mitsuhiko don't understand what I should change. nargs option applies to arguments "type". However, the question was how to receive leftover arguments(including options, like valid portion of sys.args) from context using MultiCommand approach.
Just to leave some comments on this: I would like to somehow undo parts of Click 6 because it just does not work that way. Not entirely sure what the course of action is :(
The bug still persists. You don't have access to leftover arguments from any place/subcommands. See updated example to reproduce this issue:
test.py
importclick@click.group(context_settings=dict(ignore_unknown_options=True,allow_extra_args=True))@click.option("--force","-f",is_flag=True,help="Force to accept any confirmation prompts.")@click.option("--caller", "-c")@click.pass_contextdefcli(ctx, force, caller):
print(ctx.args)
# do some preprocessing with leftover args... Do we have `--json-output`? etc.@cli.command()defrun():
passif__name__=='__main__':
cli()
I find some workaround. We can actually overload command.invoke() and backups args:
class PlatformioCLI(click.MultiCommand):
def invoke(self, ctx):
ctx._args = ctx.args
if hasattr(ctx, "protected_args"):
ctx._args = ctx.protected_args + ctx.args
return super(PlatformioCLI, self).invoke(ctx)
In this case, args will be in ctx._args. I may work in our case. The problem can occur when you need to get leftover arguments in subcommand. In this case, they will be empty.
In the first example #473 (comment), allow_extra_args is missing, and the top-level is a command, not a group, so extra arguments would be treated as errors.
In the second example #473 (comment), a Group is used and allow_extra_args is set (unneeded in this case, group requires this and sets it automatically). However, "run" is not an extra argument, it's the subcommand name.
Use click.argument("extra", nargs=-1) to explicitly capture the arguments. While it's not clearly documented this way, allow_extra_args is to allow the parser to handle nested subcommand parsing, not for user code to capture extra args. For the same reason that a group automatically sets allow_extra_args, do not use a nargs=-1 argument on a group, as it would never be able to dispatch to a command then since the command name and args would be considered "extra" to the parent parser.
allow_extra_args is a parser flag for supporting subcommands on groups. It is already set correctly for these internal situations.
Similarly, ctx.args and ctx.protected_args are also for internal tracking for dispatching subcommands. Command callbacks shouldn't be looking at them.
To capture extra arguments for direct use, use argument(nargs=-1) on a command. The command callback will then receive an extra argument with the list of captured values.
I acknowledge that this isn't clear from the documentation. As part of rewriting the parser, I've been running across quite a bit of behavior that should be considered internal, or that needs much clearer documentation.
Activity
mitsuhiko commentedon Dec 1, 2015
In which situation?
ivankravets commentedon Dec 1, 2015
Here
ctx.argsis equal to[]for any commands. For example,platformio serialports monitor --baud 115200.mitsuhiko commentedon Dec 1, 2015
So that you got args for children there was a bug. Do you need that?
nargs > 1still captures that.ivankravets commentedon Dec 1, 2015
Exactly, I need
argsfor children.ivankravets commentedon Dec 1, 2015
For example,
I just need
run .... Do you have any ideas?ivankravets commentedon Dec 5, 2015
@mitsuhiko don't understand what I should change.
nargsoption applies to arguments "type". However, the question was how to receive leftover arguments(including options, like valid portion of sys.args) from context usingMultiCommandapproach.P.S: I have blocked issue for it platformio/platformio-core#349 and reduced temporary Click to
<6.Thanks in advance!
mitsuhiko commentedon Dec 7, 2015
Are you looking for this maybe? http://click.pocoo.org/5/advanced/#forwarding-unknown-options
ivankravets commentedon Dec 7, 2015
Test code
Click < 6
Click 6
What is wrong in this code? Thanks.
mitsuhiko commentedon Dec 8, 2015
I will have a look at that.
orome commentedon Jan 6, 2016
I'm getting downgrade to click 5.1 (by 2.7.1).
ivankravets commentedon Jan 12, 2016
@orome It's ok. @platformio requires some functionality which doesn't work in Click 6. See related issue platformio/platformio-core#349
mitsuhiko commentedon Jan 12, 2016
Just to leave some comments on this: I would like to somehow undo parts of Click 6 because it just does not work that way. Not entirely sure what the course of action is :(
ivankravets commentedon Feb 22, 2016
@mitsuhiko do you have any news?
mitsuhiko commentedon Apr 15, 2016
Not yet, for now please use Click 5 if you need this.
3 remaining items
ivankravets commentedon May 7, 2019
The bug still persists. You don't have access to leftover arguments from any place/subcommands. See updated example to reproduce this issue:
test.py
Click 5.0
Click 7.0
jcrotts commentedon May 7, 2019
Quite right the two use cases above are slightly different.
I think this issue targets your use case.
#347
ivankravets commentedon May 7, 2019
Can you reopen it?
jcrotts commentedon May 8, 2019
Sure, have you been able to find a work around for the behavior you want?
ivankravets commentedon May 8, 2019
@jcrotts Thanks for reopening! The only solution is to parse manually
sys.argvwhich loses sense in usingclickat all.Is it difficult to fix it? The issue arose with Click 6.0 release 4 years ago.
jcrotts commentedon May 8, 2019
This seems to be the commit that changed this behavior.
0a2919f
ivankravets commentedon May 8, 2019
You are right, thanks! I removed these lines https://github.com/pallets/click/blob/master/click/core.py#L1122:L1123 and everything works now with Click 7.0.
@mitsuhiko can we remove these L1122:L1123 lines which reset context args?
jcrotts commentedon May 8, 2019
So actually just removing the 2nd line seems to revert the behavior, and then changing the print to print(ctx.protected_args).
Tests pass after the change, but I think this could be overriding a design decision that I'm not fully aware of.
ivankravets commentedon May 8, 2019
I find some workaround. We can actually overload
command.invoke()and backups args:In this case,
argswill be inctx._args. I may work in our case. The problem can occur when you need to get leftover arguments in subcommand. In this case, they will be empty.So, what to do with this issue?
ivankravets commentedon May 8, 2019
http://click.palletsprojects.com/en/7.x/api/#click.Context.args
It looks like a critical bug.
Another workaround could be
ctx.leftover_argsand set it toctx.protected_args + ctx.argsbefore reseting.jcrotts commentedon Jun 24, 2019
Seems related to #1323
davidism commentedon Mar 2, 2022
In the first example #473 (comment),
allow_extra_argsis missing, and the top-level is a command, not a group, so extra arguments would be treated as errors.In the second example #473 (comment), a
Groupis used andallow_extra_argsis set (unneeded in this case, group requires this and sets it automatically). However, "run" is not an extra argument, it's the subcommand name.Use
click.argument("extra", nargs=-1)to explicitly capture the arguments. While it's not clearly documented this way,allow_extra_argsis to allow the parser to handle nested subcommand parsing, not for user code to capture extra args. For the same reason that a group automatically setsallow_extra_args, do not use anargs=-1argument on a group, as it would never be able to dispatch to a command then since the command name and args would be considered "extra" to the parent parser.allow_extra_argsis a parser flag for supporting subcommands on groups. It is already set correctly for these internal situations.ctx.argsandctx.protected_argsare also for internal tracking for dispatching subcommands. Command callbacks shouldn't be looking at them.argument(nargs=-1)on a command. The command callback will then receive anextraargument with the list of captured values.I acknowledge that this isn't clear from the documentation. As part of rewriting the parser, I've been running across quite a bit of behavior that should be considered internal, or that needs much clearer documentation.