argparsing.py
Overview
The [argparsing.py](/projects/286/67331) file provides a custom command-line argument and ini-file option parsing framework built on top of Python’s standard `argparse` module. It is designed primarily for the pytest testing framework but can be adapted for other applications requiring complex command line and ini-file configuration management.
Key features include:
Parsing of command line options organized into named groups for better help output structure.
Registration and parsing of ini-file options with typed values and sensible defaults.
Integration with pytest-specific features and enhancements, such as improved help formatting and error reporting.
Support for argument completion and handling unknown arguments gracefully.
A minimal replacement for
optparse.Optionvia theArgumentclass for compatibility and extended behavior.
The module encapsulates the parsing logic in the `Parser` class, which is the main entry point to define options, groups, and parse command line inputs.
Classes and Functions
Class NotSet
A sentinel singleton class used to represent an unspecified default value distinct from `None`.
Usage: Used internally to detect when no default value is provided for ini options.
NOT_SET = NotSet()
Class Parser
Main class for defining and parsing command line and ini-file options.
Attributes
prog: str | None- Program name to display in help messages.extra_info: dict[str, Any]- Additional context info displayed on argument parsing errors.Internal:
_anonymous: OptionGroup- Holds options not assigned to a named group._groups: list[OptionGroup]- List of named option groups._processopt: Callable[[Argument], None] | None- Optional callback to process each option._usage: str | None- Usage string for help message._inidict: dict[str, tuple[str, str | None, Any]]- Ini option metadata: help, type, default._ininames: list[str]- Ordered list of ini option names.
Methods
__init__(usage=None, processopt=None, *, _ispytest=False)Initializes the parser. The
_ispytestflag is for internal validation.processoption(option: Argument) -> NoneCalls the
_processoptcallback if set, passing anArgumentinstance.getgroup(name: str, description: str = "", after: str | None = None) -> OptionGroupReturns a named option group. Creates it if it doesn't exist. The
afterparameter controls ordering for--help.addoption(*opts: str, **attrs: Any) -> NoneAdds a command line option to the anonymous (default) option group.
parse(args: Sequence[str | os.PathLike[str]], namespace: argparse.Namespace | None = None) -> argparse.NamespaceParses the given command line arguments and returns a populated namespace.
parse_setoption(args: Sequence[str | os.PathLike[str]], option: argparse.Namespace, namespace: argparse.Namespace | None = None) -> list[str]Parses args and updates fields in an existing
optionnamespace. Returns the list of unparsed file or directory arguments.parse_known_args(args: Sequence[str | os.PathLike[str]], namespace: argparse.Namespace | None = None) -> argparse.NamespaceParses the known arguments, ignoring unknown ones. Returns a namespace.
parse_known_and_unknown_args(args: Sequence[str | os.PathLike[str]], namespace: argparse.Namespace | None = None) -> tuple[argparse.Namespace, list[str]]Parses known arguments and returns both known and unknown argument lists.
addini(name: str, help: str, type: Literal[...] | None = None, default: Any = NOT_SET) -> NoneRegisters an ini-file option with a name, help text, type, and optional default. Supports types like "string", "bool", "int", "float", "paths", etc.
Usage Example
parser = Parser()
parser.addoption("--verbose", action="store_true", help="Increase verbosity")
group = parser.getgroup("Database Options", "Options related to database configuration")
group.addoption("--db-host", default="localhost", help="Database hostname")
args = parser.parse(["--verbose", "--db-host", "db.example.com"])
print(args.verbose) # True
print(args.db_host) # "db.example.com"
Function get_ini_default_for_type(type: Literal[...] | None) -> Any
Returns a sensible default value for the given ini-file option type when no explicit default is provided.
For
Noneor"string": returns empty string"".For list types (
"paths","pathlist","args","linelist"): returns empty list[].For
"bool": returnsFalse.For
"int": returns0.For
"float": returns0.0.
Class Argument
Represents a single command line option, mimicking `optparse.Option` behavior but compatible with `argparse`.
Attributes
_short_opts: list[str]- Short options (e.g.-h)._long_opts: list[str]- Long options (e.g.--help).dest: str- Destination attribute name in the parsed namespace.type,default- Option type and default value if provided.
Methods
__init__(*names: str, **attrs: Any)Initializes option names and attributes. Raises
ArgumentErrorif invalid option strings.names() -> list[str]Returns all option strings (short + long).
attrs() -> Mapping[str, Any]Returns all attributes to pass to
argparse.add_argument.
Usage Example
arg = Argument("-v", "--verbose", action="store_true", help="Enable verbose output")
print(arg.names()) # ['-v', '--verbose']
print(arg.attrs()) # {'action': 'store_true', 'dest': 'verbose', 'help': 'Enable verbose output'}
Class ArgumentError(Exception)
Custom error raised when an `Argument` instance is created with invalid or inconsistent arguments.
Class OptionGroup
Represents a named group of related command line options for better help output organization.
Attributes
name: str- Group name.description: str- Description shown in help.options: list[Argument]- List of options added to this group.parser: Parser | None- Reference to the owning parser.
Methods
__init__(name: str, description: str = "", parser: Parser | None = None, *, _ispytest: bool = False)addoption(*opts: str, **attrs: Any) -> NoneAdds a new option to the group. Raises
ValueErroron conflicting option names.Internal methods
_addoptionand_addoption_instanceare used for addingArgumentinstances with additional constraints (e.g., no lowercase short options).
Usage Example
group = parser.getgroup("Output Options", "Options affecting output formatting")
group.addoption("--color", choices=["yes", "no"], default="yes", help="Colorize output")
Class MyOptionParser(argparse.ArgumentParser)
Subclass of `argparse.ArgumentParser` with customized behavior:
Uses
DropShorterLongHelpFormatterfor improved help formatting.Disables abbreviation of options (
allow_abbrev=False).Overrides
error()to raise pytest'sUsageErrorwith extra context info.Overrides
parse_args()to allow positional arguments to be split and unrecognized options to be appended to a special attribute (file_or_dir).
Class DropShorterLongHelpFormatter(argparse.HelpFormatter)
Custom help formatter that:
Collapses long options that differ only by extra hyphens into a single, canonical form in help output.
Caches formatted actions for efficiency.
Wraps help text with explicit line break support.
Dynamically adjusts terminal width using pytest’s
_io.get_terminal_width().
Important Implementation Details
The
Parserclass uses an internal_anonymousOptionGroupto hold options not assigned to any named group.The
Argumentclass mimicsoptparse.Optionbut internally translates options intoargparse-compatible formats.Option groups are maintained in an ordered list, and
getgroupinserts new groups after a specified existing group if requested.The parser supports advanced features like argument completion (via
_pytest._argcomplete) and file/directory autocompletion.The
MyOptionParser.errormethod enhances error messages by including contextualextra_infoand raisesUsageErrorinstead of callingsys.exit.The ini-file options registered via
addinisupport multiple specialized types with automatic default values determined byget_ini_default_for_type.The
DropShorterLongHelpFormatterensures help output is concise by merging similar long options (e.g.,--two-wordsand--twowords).
Interaction with Other System Parts
Imports and interacts with pytest internals such as
_pytest._iofor terminal width and_pytest.config.exceptions.UsageErrorfor error handling.Uses
_pytest.deprecated.check_ispytestto validate internal pytest usage.Integrates with
_pytest._argcompleteto support shell argument completion.The
Parserclass is likely used by pytest's core configuration system (pytest.Config) to register and parse command line options and ini-file settings.The parsed options and ini values are exposed through pytest’s configuration API for consumption by plugins and core pytest logic.
Visual Diagram
classDiagram
class Parser {
+prog: str | None
+extra_info: dict[str, Any]
+__init__(usage: str | None, processopt: Callable[[Argument], None] | None, _ispytest: bool)
+processoption(option: Argument) void
+getgroup(name: str, description: str, after: str | None) OptionGroup
+addoption(*opts: str, **attrs: Any) void
+parse(args: Sequence[str | os.PathLike[str]], namespace: argparse.Namespace | None) argparse.Namespace
+parse_setoption(args: Sequence[str | os.PathLike[str]], option: argparse.Namespace, namespace: argparse.Namespace | None) list[str]
+parse_known_args(args: Sequence[str | os.PathLike[str]], namespace: argparse.Namespace | None) argparse.Namespace
+parse_known_and_unknown_args(args: Sequence[str | os.PathLike[str]], namespace: argparse.Namespace | None) tuple[argparse.Namespace, list[str]]
+addini(name: str, help: str, type: Literal | None, default: Any) void
}
class OptionGroup {
+name: str
+description: str
+options: list[Argument]
+addoption(*opts: str, **attrs: Any) void
}
class Argument {
+_short_opts: list[str]
+_long_opts: list[str]
+dest: str
+names() list[str]
+attrs() Mapping[str, Any]
}
class MyOptionParser {
+error(message: str) NoReturn
+parse_args(args: Sequence[str] | None, namespace: argparse.Namespace | None) argparse.Namespace
}
class DropShorterLongHelpFormatter {
+_format_action_invocation(action: argparse.Action) str
+_split_lines(text: str, width: int) list[str]
}
Parser "1" o-- "*" OptionGroup : groups
OptionGroup "1" o-- "*" Argument : options
Parser "1" --> "1" MyOptionParser : creates
MyOptionParser "1" --> "1" DropShorterLongHelpFormatter : uses formatter
Summary
The [argparsing.py](/projects/286/67331) file provides a pytest-tailored command line and ini-file parsing system that extends and customizes the Python standard `argparse` module. It supports grouping of options, advanced help formatting, ini-file option typing, and integration with pytest’s error handling and shell completion features. The core `Parser` class manages option groups and parsing, while utility classes like `Argument` and `OptionGroup` encapsulate option definitions. `MyOptionParser` and `DropShorterLongHelpFormatter` provide enhanced behavior and help output. Overall, this module is a critical part of pytest’s configuration subsystem enabling rich command line interfaces and configuration management.