Search code examples
pythondocopt

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


I've been trying to use docopt to make a simple CLI, but for some reason my default parameters are not appearing. Below is my test code. I am using the latest version of docopt.py from the github repository.

"""
Usage:  scrappy <path> ... [options]

-a --auto           Automatically scrape and rename without user interaction.
-l --lang           Specify language code [default: en].
--scan-individual   Evaluate series information individually for each file.
-c --cfg            User alternate config file [default: ../scrappy.conf]
-t --test           Test run.  Do not modify files.
-v --verbose        Print verbose output
"""

from docopt import docopt
arguments = docopt(__doc__, version='0.1.0 alpha')
print arguments  # DEBUG

Here's my output when I run $ scrappy/scrappy.py first_path_parameter second/path/parameter

{'--auto': None,
 '--cfg': None,
 '--lang': None,
 '--scan-individual': None,
 '--test': None,
 '--verbose': None,
 '<path>': ['first_path_parameter', 'second/path/parameter']}

Anybody know what's going on?

EDIT:

I updated my code, but I'm still getting similar output. What's more, when I try to pass --scan-individual, I get an error according to which it requires an argument. Again, in case it matters, I'm running docopt having simply copied docopt.py into the working directory of my project. What's going on, here?

#!/usr/bin/env python

"""Scrappy:  Rename media files based on scraped information.

Usage:  scrappy <path> ... [options]

-a --auto               Automatically scrape and rename without user interaction.
-l LANG --lang LANG     Specify language code [default: en].
--scan-individual       Evaluate series information individually for each file.
-c CONF --cfg CONF      User alternate config file [default: ../scrappy.conf]
-t --test               Test run.  Do not modify files.
-v --verbose            Print verbose output
"""

from docopt import docopt
arguments = docopt(__doc__, version='0.1.0 alpha')
print arguments  # DEBUG

Output:

$ scrappy/scrappy.py first_path_parameter second/path/parameter --scan-individual
--scan-individual requires argument
Usage:  scrappy <path> ... [options]

Solution

  • 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.