[issue25061] Add native enum support for argparse

desbma report at bugs.python.org
Tue Nov 3 12:24:34 EST 2015


desbma added the comment:

I came up with something that satisfies my needs (no boilerplate code, and intuitive add_argument call).

I modified your factory, and defined a simple action class (this is a quick and dirty prototype for discussion, I am in no way asking that such thing should be merged as such):

class EnumType(object):
    """Factory for creating enum object types
    """
    def __init__(self, enumclass, action):
        self.enums = enumclass
        self.action = action

    def __call__(self, astring):
        name = self.enums.__name__
        try:
            v = self.enums[astring.upper()]
        except KeyError:
            msg = ', '.join([t.name.lower() for t in self.enums])
            msg = '%s: use one of {%s}'%(name, msg)
            raise argparse.ArgumentTypeError(msg)
        else:
            self.action.choices = None  # hugly hack to prevent post validation from choices
            return v

    def __repr__(self):
        astr = ', '.join([t.name.lower() for t in self.enums])
        return '%s(%s)' % (self.enums.__name__, astr)


class StoreEnumAction(argparse._StoreAction):

  def __init__(self,
               option_strings,
               dest,
               type,
               nargs=None,
               const=None,
               default=None,
               required=False,
               help=None,
               metavar=None):
      super().__init__(option_strings=option_strings,
                       dest=dest,
                       nargs=nargs,
                       const=const,
                       default=default,
                       type=EnumType(type, self),
                       choices=tuple(t.name.lower() for t in type),
                       required=required,
                       help=help,
                       metavar=metavar)

Then all I have to do is to pass 'action=StoreEnumAction, type=TheEnum' to the add_argument call.

The good:
I get a proper usage line (which takes into account the value of 'nargs'), relevant error messages, and what is stored in the namespace after validation is the proper enum type, not a string.

The bad:
* The reference to the action inside the factory is ugly. This should probably be refractored to be all contained inside StoreEnumAction.
* The meaning of the 'type' parameter for StoreEnumAction is somewhat different than for other actions (enum class vs callable that validates)

What do you think?

----------

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue25061>
_______________________________________


More information about the Python-bugs-list mailing list