[docs] [issue13540] Document the Action API in argparse

Jason R. Coombs report at bugs.python.org
Wed Dec 14 14:54:31 CET 2011

Jason R. Coombs <jaraco at jaraco.com> added the comment:

Most of the Action subclasses in argparse override __init__ and they raise ValueErrors when the parameters aren't as expected for that argument. This was my reason for adding that comment. If the basic Actions require this level of validation, wouldn't a custom action also want to supply this type of behavior? I'm sure I've overridden Action.__init__ in some of the subclasses I've created, but I don't remember specifically why.

I agree freezing the __init__ signature is undesirable. It would be preferable if the API called a hook for validating the argument parameters against the action. My intention, however, was to document the existing behavior, not influence changes in the behavior.

Perhaps the recommended API really isn't to subclass Action, but to supply a callable that takes the __init__ args which validates the parameters and returns a callable which takes the __call__ args which should set attributes on the namespace. Perhaps the Action class is only one such implementation of the API. Indeed, that was my understanding of the API as it is currently documented before Terry suggested otherwise.

What do you think about instead of documenting the Action class, we formalize the API, similar to how I described it in the previous paragraph, and then suggest that an Action subclass with an overridden __call__ is the most direct way to implement the Action API?

In reviewing the code again, I note that not just most, but all of the Action subclasses override __init__. I also note that not all of them accept the same parameters. For example, the _StoreConstAction does not accept an nargs parameter.

>>> p = argparse.ArgumentParser()
>>> p.add_argument('--awesome-sauce', action="store_const", const=True, nargs=None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\python\lib\argparse.py", line 1281, in add_argument
    action = action_class(**kwargs)
TypeError: __init__() got an unexpected keyword argument 'nargs'

So it seems that the Action API is slightly different than I described. The first callable should accept all of the parameters passed to add_argument _except_ for the action parameter itself. I think by indicating this in the API description, we avoid the problem of freezing any additional signature.

I'll take another stab at updating the documentation with these findings.


Python tracker <report at bugs.python.org>

More information about the docs mailing list