Search code examples
pythondocopt

docopt does not parse args, just prints usage


I cannot get docopt to work. I have this simple example, which as far as I can tell is correct:

#! /usr/bin/env python3
"""usage: do.py name

"""
from docopt import docopt


args = docopt(__doc__)
print(f"Hello, {args['name']}!")

and it only ever prints:

$ ./do.py susan
usage: do.py name

Solution

  • From the docopt documentation:

    • <arguments>, ARGUMENTS. Arguments are specified as either upper-case words, e.g. my_program.py CONTENT-PATH or words surrounded by angular brackets: my_program.py <content-path>.

    Since name is neither upper case nor surrounded by angle brackets, it's not an argument. And since it is not an argument, it must fall into the category of

    • commands are words that do not follow the described above conventions of --options or <arguments> or ARGUMENTS, plus two special commands: dash "-" and double dash "--"…

    And indeed, that is what it is:

    $ ./do.py name
    Hello, True!
    

    It shows True because that's the value stored for commands, which serves to demonstrate that the command was entered. So that's probably not what you wanted. You could start with this model:

    #! /usr/bin/env python3
    """usage: do.py hello <name>
    
    """
    from docopt import docopt
    
    args = docopt(__doc__)
    if args['hello']:
        print(f"Hello, {args['<name>']}!")
    

    which has more intuitive results:

     ./do.py hello susan
    Hello, susan!
    

    But it's possible that you don't really need commands at all:

    #! /usr/bin/env python3
    """usage: do.py <name>
    
    """
    from docopt import docopt
    
    args = docopt(__doc__)
    print(f"Hello, {args['<name>']}!")
    
    $ ./do.py susan
    Hello, susan!