Why are defaults not appearing in my command-line argument dictionary from docopt?

◇◆丶佛笑我妖孽 提交于 2019-12-05 10:08:23

By looking at the examples, it seems that if you want to pass a default value you may have to specify a target variable, e.g.

naval_fate.py:  --speed=<kn>  Speed in knots [default: 10].
options_example.py-  --exclude=PATTERNS   exclude files or directories which match these comma
options_example.py:                       separated patterns [default: .svn,CVS,.bzr,.hg,.git]
options_example.py-  -f NAME --file=NAME  when parsing directories, only check filenames matching
options_example.py:                       these comma separated patterns [default: *.py]

So in your case,

-l LANG --lang LANG  Specify language code [default: en].
-c CONFIG            User alternate config file [default: ../scrappy.conf]

produces

localhost-2:coding $ python doc.py --auto a b c
{'--auto': True,
 '--lang': 'en',
 '--scan-individual': False,
 '--test': False,
 '--verbose': False,
 '-c': '../scrappy.conf',
 '<path>': ['a', 'b', 'c']}

Edit: the updated code the OP posted works just fine for me, with the github version I downloaded about half an hour ago:

localhost-2:coding $ ./scrappy.py first_path_parameter second/path/parameter --scan-individual
{'--auto': False,
 '--cfg': '../scrappy.conf',
 '--lang': 'en',
 '--scan-individual': True,
 '--test': False,
 '--verbose': False,
 '<path>': ['first_path_parameter', 'second/path/parameter']}

So I'm at a loss.

I just ran across this issue in my own code and tested (using the other answers here from hargriffle and DSM) until I figured the following out.

Note this is as of docopt 0.6.1

When running this file:

#! /usr/bin/env python
"""scans.py

Usage:
  scans.py [<args>...]

Options:
  -h --help           Show this screen.
  --version           Show version.
  -L INT --limit=INT  Query response row limit [default: 10]

"""

from docopt import docopt

if __name__ == '__main__':
    print docopt(__doc__)

I receive the following output

{'<args>': []}

BUT if I specifically write in that the argument is optional in the usage line, like so:

Usage:
  scans.py [-L INT | --limit=INT] [<args>...]

I received what I was hoping for:

{'--limit': '10',
 '<args>': []}

I just ran into the same issue -- and I only resolved it after reading the last two comments by @DSM and @blz.

To reiterate, as it may help others, to get the defaults variables parsed you have to make sure there are at least two spaces between end of the variables for the options and the text description of the option.

From the docs:

Use two spaces to separate options with their informal description:

--verbose More text.   # BAD, will be treated as if verbose option had
                   # an argument "More", so use 2 spaces instead
-q        Quit.        # GOOD
-o FILE   Output file. # GOOD
--stdout  Use stdout.  # GOOD, 2 spaces

So without two spaces the option parser interprets the description text as variables and does not process the [default: ...] part.

Gordon McGregor

Same problem with me.

In my particular case I noticed that doc-opt is sensitive to lines starting with tabs vs starting with spaces

#!/usr/bin/env python
"""Sample Application.

Usage:
    sample [options] me
    sample --version

Options:
  --host HOST     words here  [default: 5]
  --version  Version identifier

"""

vs

#!/usr/bin/env python
"""Sample Application.

Usage:
    sample [options] me
    sample --version

Options:
    --host HOST     words here  [default: 5]
    --version  Version identifier

"""

where there is a single tab before --host and --version in the Options: list. The second case doesn't parse the defaults correctly, the first with spaces for the initial indent, does.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!