Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Positional arguments not described in help #449

cyounkins opened this issue May 30, 2017 · 8 comments

Positional arguments not described in help #449

cyounkins opened this issue May 30, 2017 · 8 comments


Copy link

$ cat
from invoke import task

def hi(ctx, name):
    print("Hi {0}!".format(name))

$ invoke --help hi
Usage: inv[oke] [--core-opts] hi [--options] [other tasks here ...]


  -n STRING, --name=STRING

$ invoke hi
'hi' did not receive all required positional arguments!

The auto-generated usage does not indicate that a positional argument is required. hi [--options] [other tasks here ...] seems to imply the opposite - that all arguments are optional.

In addition, we should be able to print the required positional arguments when we do not receive all of them.

Copy link

Good catch, this feels like a bug to me. Thanks!

Copy link

dmulter commented Jul 10, 2017


Copy link

To clarify, I think this change should both:

  • add more info to --help output re: positional arguments
  • display --help output in the situation causing us to complain about positional arguments, automatically (this comes up a lot actually.)

riverfr0zen added a commit to riverfr0zen/invoke that referenced this issue Feb 7, 2018
Copy link

I've posted a pull request for this issue at #504

bitprophet added a commit that referenced this issue Feb 20, 2018
Copy link

gmmeyer commented Mar 17, 2018

I don't think the above commit fully fixes this bug. If you don't supply sufficient positional arguments, the help flag won't work properly, either. Here's an example:

If you have a task, something like this that was written by one of my coworkers, @ofek:

    'package': 'The package to upgrade throughout the integrations',
    'version': 'The version of the package to pin',
    'verbose': 'Whether or not to produce output',
def upgrade(ctx, package, version, verbose=False):
    Do Something

And you do not supply the positional arguments, the task will just fail:

❯❯❯ invoke upgrade -h
'upgrade' did not receive all required positional arguments!

If you put help before the task, it will print out normally:

❯❯❯ invoke -h upgrade
Usage: inv[oke] [--core-opts] upgrade [--options] [other tasks here ...]

  Do Something

  -e, --verbose                 Whether or not to produce output
  -p STRING, --package=STRING   The package to upgrade throughout the integrations
  -v STRING, --version=STRING   The version of the package to pin

Copy link

May I ask is this one bug too? (i mean if there not have args, but there will raise error?)

code (invoke-0.22.1-py2.7.egg\invoke\ function: def argspec(self, body)):
print "+++arg_names", arg_names # add for debug
matched_args = [reversed(x) for x in [spec.args, spec.defaults or []]]
spec_dict = dict(zip_longest(*matched_args, fillvalue=NO_DEFAULT))
# Pop context argument
context_arg = arg_names.pop(0)
except IndexError:
# TODO: see TODO under call, this should be same type
raise TypeError("Tasks must have an initial Context argument!")
del spec_dict[context_arg]
return arg_names, spec_dict

E:\github\RIDE>inv --list
+++arg_names ['args']
+++context_arg args
+++arg_names ['test_filter']
+++context_arg test_filter
+++arg_names ['upgrade']
+++context_arg upgrade
+++arg_names []
Traceback (most recent call last):
File "C:\Python27\Scripts\", line 11, in
load_entry_point('invoke==0.22.1', 'console_scripts', 'inv')()
File "C:\Python27\lib\site-packages\invoke-0.22.1-py2.7.egg\invoke\"
, line 282, in run
File "C:\Python27\lib\site-packages\invoke-0.22.1-py2.7.egg\invoke\"
, line 356, in parse_collection
File "C:\Python27\lib\site-packages\invoke-0.22.1-py2.7.egg\invoke\"
, line 508, in load_collection
module, parent = loader.load(coll_name)
File "C:\Python27\lib\site-packages\invoke-0.22.1-py2.7.egg\invoke\",
line 69, in load
module = imp.load_module(name, fd, path, desc)
File "E:\github\RIDE\", line 63, in
File "C:\Python27\lib\site-packages\invoke-0.22.1-py2.7.egg\invoke\",
line 292, in task
return Task(args[0], **kwargs)
File "C:\Python27\lib\site-packages\invoke-0.22.1-py2.7.egg\invoke\",
line 63, in init
self.positional = self.fill_implicit_positionals(positional)
File "C:\Python27\lib\site-packages\invoke-0.22.1-py2.7.egg\invoke\",
line 155, in fill_implicit_positionals
args, spec_dict = self.argspec(self.body)
File "C:\Python27\lib\site-packages\invoke-0.22.1-py2.7.egg\invoke\",
line 149, in argspec
raise TypeError("Tasks must have an initial Context argument!")
TypeError: Tasks must have an initial Context argument!

Copy link

Sorry in advance, I know this is an old issue, but this behavior seems to persist even today. Any updates on this?

Copy link

jungerm2 commented Jul 3, 2023

This is, in my view, a key issue that likely limits wider invoke adoption: It doesn't make it clear to the user what arguments are required.

I have some time on my hands and could look at this closer, what would you recommend we start with @bitprophet? While I do use invoke a lot, I'm not too familiar with its internals. It seems some work has been done on this by @riverfr0zen, but it only raises an error when the user forgets an argument, it doesn't modify the help message.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet

No branches or pull requests

7 participants