docopt
docopt is a Pythonic argument parser that creates command-line interfaces based on the user's beautiful help message, typically provided as a module docstring. It adheres to PEP 257 by using the docstring as the source of truth for argument parsing, reducing boilerplate code. The current version is 0.6.2, released in June 2014, and the original project sees limited active development, with a community-maintained fork (`docopt-ng`) offering continued updates.
Warnings
- breaking The meaning of the `[options]` shortcut changed from 'any known option' to 'any option not in usage-pattern'. Additionally, the `argv` parameter now defaults to `None` instead of `sys.argv[1:]`, allowing docopt to use the latest `sys.argv`.
- breaking The return type of `docopt` changed. It now returns a dictionary of arguments and options. Previously, for arguments, it returned a namespace or a list in older versions.
- gotcha The original `docopt` project (0.6.2, last updated June 2014) is no longer actively maintained. For ongoing development, bug fixes, and potentially newer Python version compatibility, consider using `docopt-ng`, a community-maintained fork.
- gotcha When an option or argument is allowed to be repeated (e.g., `my_program.py <file>...` or `my_program.py --path=<path>...`), docopt collects the matched arguments into a list. If an option is repeated without an argument, its occurrences are counted.
- gotcha The fundamental principle of docopt is to derive the parser directly from the user-written help message (docstring). This can feel 'magical' or 'abstract-breaking' to developers accustomed to explicitly defining arguments programmatically, potentially leading to confusion if the docstring syntax isn't perfectly understood.
Install
-
pip install docopt==0.6.2
Imports
- docopt
from docopt import docopt
Quickstart
import os
from docopt import docopt
DOC = """
Naval Fate.
Usage:
naval_fate.py ship new <name>...
naval_fate.py ship <name> move <x> <y> [--speed=<kn>]
naval_fate.py ship shoot <x> <y>
naval_fate.py mine (set|remove) <x> <y> [--moored | --drifting]
naval_fate.py (-h | --help)
naval_fate.py --version
Options:
-h --help Show this screen.
--version Show version.
--speed=<kn> Speed in knots [default: 10].
--moored Moored (anchored) mine.
--drifting Drifting mine.
"""
if __name__ == '__main__':
# Simulate command-line arguments for demonstration
# In a real script, this would be docopt(__doc__, version='Naval Fate 2.0')
# For testing, you might pass a list of strings:
# arguments = docopt(DOC, argv=['ship', 'new', 'Argos', 'Bounty'], version='Naval Fate 2.0')
# For a runnable quickstart, we'll parse the docstring without actual CLI input
# and assume a simple case. For full CLI testing, a dedicated test framework is better.
# To make this runnable without actual CLI, we simulate argv.
# In a real scenario, remove `argv` parameter to let it use sys.argv
simulated_argv = os.environ.get('DOCOPT_SIM_ARGS', '').split() or ['ship', 'new', 'ExampleShip']
# If --version is in simulated_argv, docopt will print version and exit.
# For quickstart, we'll avoid it unless specifically tested.
if '--version' in simulated_argv:
print('Naval Fate 2.0')
import sys
sys.exit(0)
arguments = docopt(DOC, argv=simulated_argv, version='Naval Fate 2.0')
print(arguments)
# Example of accessing parsed arguments
if arguments.get('ship') and arguments.get('new'):
print(f"Creating new ship(s): {arguments['<name>']}")