diff --git a/src/byteb4rb1e/utils/argparse/actions.py b/src/byteb4rb1e/utils/argparse/actions.py new file mode 100644 index 0000000..79a5e8f --- /dev/null +++ b/src/byteb4rb1e/utils/argparse/actions.py @@ -0,0 +1,33 @@ +"""Custom argparse actions.""" + +from __future__ import annotations + +import argparse +from typing import Any + + +class KeyValueAction(argparse.Action): + """Argparse action that accumulates ``KEY=VALUE`` pairs into a dict. + + Usage:: + + parser.add_argument("--config", action=KeyValueAction, + default={}, metavar="KEY=VALUE", + help="Set a config option (can be repeated)") + + Then ``args.config`` is a ``dict[str, str]``. + """ + + def __call__( + self, + parser: argparse.ArgumentParser, + namespace: argparse.Namespace, + values: Any, + option_string: str | None = None, + ) -> None: + d = getattr(namespace, self.dest, None) or {} + if "=" not in values: + parser.error(f"Invalid format: {values!r} (expected KEY=VALUE)") + key, _, value = values.partition("=") + d[key.strip()] = value.strip() + setattr(namespace, self.dest, d)