docopt2¶
Typed successor to docopt. The usage message is the parser spec.
from docopt2 import docopt
args = docopt("Usage: prog <host> <port>", "127.0.0.1 8080")
args
# {'<host>': '127.0.0.1', '<port>': '8080'} -> an Arguments, a dict subclass
No builder, no decorators. You write the help text you would have written anyway, and that text parses the argv.
Pass a schema= and the same usage returns a typed object, each value coerced to its field type:
import dataclasses
from docopt2 import docopt
@dataclasses.dataclass
class Args:
host: str
port: int # coerced from the parsed string
args = docopt("Usage: prog <host> <port>", "127.0.0.1 8080", schema=Args)
args
# Args(host='127.0.0.1', port=8080) -> port is an int, not a str
Drop-in for docopt¶
docopt2 parses the same usage grammar and returns the same mapping, so switching over is a one-line
import change.
It is a superset, not a bit-identical clone. It accepts some argvs the original rejects, and it fixes three of the original's parsing bugs. Every divergence is pinned by name.
Diagnostics come with it. Everything else is opt-in: typed results, linting, stubs, completion, dispatch.
Zero dependencies
The core runs on the standard library alone. Nothing to install, nothing to audit. pydantic and
Hypothesis are optional extras (docopt2[pydantic], docopt2[hypothesis]), used only when you pass a
pydantic model as a schema or reach for the Hypothesis strategy.
Why docopt2¶
-
Typed results
Pass a dataclass,
TypedDict,Clisubclass, or pydantic model asschema=. Values come back coerced to their field types, never adict[str, Any]. -
Diagnostics that point at the problem
A mismatch carets the offending token in your argv and cross-references the usage that rejected it.
suggest=Trueadds a spell-checked "did you mean". -
Subcommand dispatch
Dispatchroutes a matched command path to its handler, optionally typed per command. It is the dispatch layer docopt itself omits. -
Shell completion
Context-aware completion scripts for bash, zsh, fish, PowerShell, and nushell. Tab offers only what is valid at the cursor.
-
Schema codegen
docopt2 stub(orgenerate_stub) writes the typed schema from your usage, in three styles, so you never hand-write it. -
Layered value resolution
Declare
[env: VAR]and[config: key]in the usage. docopt2 resolves CLI over env over config over default, andargs.source()reports which layer won. -
Self-documenting
--help
help_style="rich"renders an aligned, colored help screen. It scopes to the subcommand the user typed and shows where each value resolves from. -
Example generation
docopt2 examples(orgenerate_examples) samples the argvs your usage accepts. Use it for drift detection, parser fuzzing, or a Hypothesis strategy. -
Static usage linter
docopt2 check(orcheck) lints the usage grammar itself: dead defaults, unusable options, ambiguous variadics. It catches them before they ship. -
Usage formatter
docopt2 fmt(orformat_usage) aligns theOptions:block into one column. It is the formatter tocheck's linter, and it never changes what the usage parses to. -
Round-trip codec
format_argvis the inverse ofdocopt. It rebuilds a canonical argv from a parsed result and verifies it by re-parsing, so one usage spec drives both directions. -
Compatibility checking
check_compat(ordocopt2 compat) reports the invocations an old usage accepts that a new one rejects. It surfaces only breaks it can prove, so it fits a release gate.
Install¶
See Getting started to dive in, or browse the Guides and the API Reference for the full surface.