argparse_dataclass
Declarative CLIs with argparse and dataclasses.
Features
Features marked with a ✓ are currently implemented; features marked with a ⊘ are not yet implemented.
- [✓] Positional arguments
- [✓] Boolean flags
- [✓] Integer, string, float, and other simple types as arguments
- [✓] Default values
- [✓] Arguments with a finite set of choices
- [⊘] Subcommands
- [⊘] Mutually exclusive groups
Examples
Using dataclass decorator
>>> from argparse_dataclass import dataclass
>>> @dataclass
... class Options:
... x: int = 42
... y: bool = False
...
>>> print(Options.parse_args(['--y']))
Options(x=42, y=True)
A simple parser with flags:
>>> from dataclasses import dataclass
>>> from argparse_dataclass import ArgumentParser
>>> @dataclass
... class Options:
... verbose: bool
... other_flag: bool
...
>>> parser = ArgumentParser(Options)
>>> print(parser.parse_args([]))
Options(verbose=False, other_flag=False)
>>> print(parser.parse_args(["--verbose", "--other-flag"]))
Options(verbose=True, other_flag=True)
Using defaults:
>>> from dataclasses import dataclass, field
>>> from argparse_dataclass import ArgumentParser
>>> @dataclass
... class Options:
... x: int = 1
... y: int = field(default=2)
... z: float = field(default_factory=lambda: 3.14)
...
>>> parser = ArgumentParser(Options)
>>> print(parser.parse_args([]))
Options(x=1, y=2, z=3.14)
Enabling choices for an option:
>>> from dataclasses import dataclass, field
>>> from argparse_dataclass import ArgumentParser
>>> @dataclass
... class Options:
... small_integer: int = field(metadata=dict(choices=[1, 2, 3]))
...
>>> parser = ArgumentParser(Options)
>>> print(parser.parse_args(["--small-integer", "3"]))
Options(small_integer=3)
Using different flag names and positional arguments:
>>> from dataclasses import dataclass, field
>>> from argparse_dataclass import ArgumentParser
>>> @dataclass
... class Options:
... x: int = field(metadata=dict(args=["-x", "--long-name"]))
... positional: str = field(metadata=dict(args=["positional"]))
...
>>> parser = ArgumentParser(Options)
>>> print(parser.parse_args(["-x", "0", "positional"]))
Options(x=0, positional='positional')
>>> print(parser.parse_args(["--long-name", 0, "positional"]))
Options(x=0, positional='positional')
Using a custom type converter:
>>> from dataclasses import dataclass, field
>>> from argparse_dataclass import ArgumentParser
>>> @dataclass
... class Options:
... name: str = field(metadata=dict(type=str.title))
...
>>> parser = ArgumentParser(Options)
>>> print(parser.parse_args(["--name", "john doe"]))
Options(name='John Doe')