Skip to content

phoenixpackagecleanup.utils.argparse_utils

Argument parsing utils.

Classes:

Name Description
EnumAction

Argparse action for handling Enums.

EnumAction

Bases: Action


              flowchart TD
              phoenixpackagecleanup.utils.argparse_utils.EnumAction[EnumAction]

              

              click phoenixpackagecleanup.utils.argparse_utils.EnumAction href "" "phoenixpackagecleanup.utils.argparse_utils.EnumAction"
            

Argparse action for handling Enums.

Allows to show help with the enum values as choices, while returning an Enum value once the argument is parsed.

The implementation is copied from this answer on slackoverflow: https://stackoverflow.com/a/60750535

Examples:

>>> import argparse
>>> from enum import Enum
>>> from phoenixpackagecleanup.utils.argparse_utils import EnumAction
>>> MyEnum = Enum("MyEnum", [("Foo", "foo"), ("Bar", "bar")])
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument("--my_enum", type=MyEnum, action=EnumAction)
EnumAction(option_strings=['--my_enum'], dest='my_enum', nargs=None, const=None, default=None, type=None, choices=('foo', 'bar'), required=False, help=None, metavar=None, deprecated=False)
>>> parser.print_help()
usage: pytest [-h] [--my_enum {foo,bar}]

options:
  -h, --help           show this help message and exit
  --my_enum {foo,bar}

Methods:

Name Description
__call__

Convert value back into a self._enum instance.

Source code in src/phoenixpackagecleanup/utils/argparse_utils.py
class EnumAction(argparse.Action):
    """Argparse action for handling Enums.

    Allows to show help with the enum values as choices, while returning an Enum value
    once the argument is parsed.

    The implementation is copied from this answer on slackoverflow: https://stackoverflow.com/a/60750535

    Examples
    --------
    >>> import argparse
    >>> from enum import Enum
    >>> from phoenixpackagecleanup.utils.argparse_utils import EnumAction
    >>> MyEnum = Enum("MyEnum", [("Foo", "foo"), ("Bar", "bar")])
    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument("--my_enum", type=MyEnum, action=EnumAction)
    EnumAction(option_strings=['--my_enum'], dest='my_enum', nargs=None, const=None, default=None, type=None, choices=('foo', 'bar'), required=False, help=None, metavar=None, deprecated=False)
    >>> parser.print_help()
    usage: pytest [-h] [--my_enum {foo,bar}]
    <BLANKLINE>
    options:
      -h, --help           show this help message and exit
      --my_enum {foo,bar}
    """  # noqa: E501 allow long lines for doc tests.

    def __init__(self, **kwargs: Any) -> None:  # noqa: ANN401 allow any type in general purpose argument parsing function
        # Pop off the enum type from kwargs
        enum_type = kwargs.pop("type", None)

        # Ensure an Enum subclass is provided
        if enum_type is None:
            error_msg = "Argument `type` must be assigned to an Enum class when using EnumAction. It is not set."
            raise ValueError(error_msg)
        if not issubclass(enum_type, Enum):
            error_msg = (
                f"Argument `type` must be an Enum class when the action is `EnumAction`, got type {type(enum_type)}"
            )
            raise TypeError(error_msg)

        # Generate choices from the Enum values
        kwargs.setdefault("choices", tuple(e.value for e in enum_type))

        # init the action
        super().__init__(**kwargs)

        # keep the enum type to generate Enum instances from their values when called
        self.enum = enum_type

    def __call__(
        self,
        parser: argparse.ArgumentParser,  # noqa: ARG002 allow un-used argument here to help match parent prototype
        namespace: argparse.Namespace,
        values: Any,  # noqa: ANN401 allow any type in general purpose argument parsing function
        option_string: str | None = None,  # noqa: ARG002 allow un-used argument here to help match parent prototype
    ) -> None:
        """Convert value back into a `self._enum` instance.

        Parameters
        ----------
        parser : argparse.ArgumentParser
            The parser instance invoking this action
        namespace : argparse.Namespace
            The namespace object that will be returned by the parser.
        values : str
            The command line argument string
        option_string : str, optional
            The option string that was used to invoke this action, by default None
        """
        # Convert the value back to an enum instance and set it in the namespace
        value = self.enum(values)
        setattr(namespace, self.dest, value)

__call__

__call__(parser, namespace, values, option_string=None)

Convert value back into a self._enum instance.

Parameters:

Name Type Description Default
parser ArgumentParser

The parser instance invoking this action

required
namespace Namespace

The namespace object that will be returned by the parser.

required
values str

The command line argument string

required
option_string str

The option string that was used to invoke this action, by default None

None
Source code in src/phoenixpackagecleanup/utils/argparse_utils.py
def __call__(
    self,
    parser: argparse.ArgumentParser,  # noqa: ARG002 allow un-used argument here to help match parent prototype
    namespace: argparse.Namespace,
    values: Any,  # noqa: ANN401 allow any type in general purpose argument parsing function
    option_string: str | None = None,  # noqa: ARG002 allow un-used argument here to help match parent prototype
) -> None:
    """Convert value back into a `self._enum` instance.

    Parameters
    ----------
    parser : argparse.ArgumentParser
        The parser instance invoking this action
    namespace : argparse.Namespace
        The namespace object that will be returned by the parser.
    values : str
        The command line argument string
    option_string : str, optional
        The option string that was used to invoke this action, by default None
    """
    # Convert the value back to an enum instance and set it in the namespace
    value = self.enum(values)
    setattr(namespace, self.dest, value)