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

Open
cyounkins opened this Issue May 30, 2017 · 6 comments

Comments

Projects
None yet
6 participants
@cyounkins

cyounkins commented May 30, 2017

$ cat tasks.py
from invoke import task

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


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

Docstring:
  none

Options:
  -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.

@bitprophet

This comment has been minimized.

Member

bitprophet commented May 31, 2017

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

@dmulter

This comment has been minimized.

dmulter commented Jul 10, 2017

+1

@bitprophet

This comment has been minimized.

Member

bitprophet commented Jul 10, 2017

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

@riverfr0zen

This comment has been minimized.

riverfr0zen commented Feb 7, 2018

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

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

@gmmeyer

This comment has been minimized.

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:

@task(help={
    '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 ...]

Docstring:
  Do Something

Options:
  -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
@dongfengdejia

This comment has been minimized.

dongfengdejia commented Apr 11, 2018

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\tasks.py 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
try:
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

output:
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\inv-script.py", 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\program.py"
, line 282, in run
self.parse_collection()
File "C:\Python27\lib\site-packages\invoke-0.22.1-py2.7.egg\invoke\program.py"
, line 356, in parse_collection
self.load_collection()
File "C:\Python27\lib\site-packages\invoke-0.22.1-py2.7.egg\invoke\program.py"
, 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\loader.py",
line 69, in load
module = imp.load_module(name, fd, path, desc)
File "E:\github\RIDE\tasks.py", line 63, in
@task
File "C:\Python27\lib\site-packages\invoke-0.22.1-py2.7.egg\invoke\tasks.py",
line 292, in task
return Task(args[0], **kwargs)
File "C:\Python27\lib\site-packages\invoke-0.22.1-py2.7.egg\invoke\tasks.py",
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\tasks.py",
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\tasks.py",
line 149, in argspec
raise TypeError("Tasks must have an initial Context argument!")
TypeError: Tasks must have an initial Context argument!

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