This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author bethard
Recipients bethard, docs@python, eric.araujo, jaraco, terry.reedy
Date 2011-12-15.10:16:37
SpamBayes Score 5.311515e-10
Marked as misclassified No
Message-id <1323944198.95.0.291707373871.issue13540@psf.upfronthosting.co.za>
In-reply-to
Content
Sorry about being out of contact (I'm flying back and forth between the US and the EU every 4-5 weeks right now), and thanks Terry for bringing this to my attention.

Essentially, the API is:

* The argument to action= must be a callable that accepts at least a "dest" and "option_strings" keyword arguments, and returns some object. The keyword arguments passed to this callable will be dest, option_strings, and whatever other keyword arguments were passed to add_argument().

* The object returned by the action= callable should have attributes "dest", "option_strings", "default", "type", "required", "help", etc. defined in essentially the same way as the add_argument() documentation.

* The object returned by the action= callable should itself be callable, and should accept the arguments (self, parser, namespace, values, option_string=None). This method can do whatever it wants, but as you note, the typical approach is to invoke setattr(namespace, self.dest, ...)

Now, all that said, the easiest way of creating a callable that returns an callable where both have the right signatures and the right attributes is to subclass argparse.Action. In fact, doing it any other way is probably crazy. I'm against changing the name of __call__ to invoke because it removes the possibility of defining an action as a function returning another function (which is currently possible), but I'm all for making the documentation strongly recommend subclassing argparse.Action. I would just say something like:

"You may also specify an arbitrary action by passing a subclass of :class:`argparse.Action`, or another callable object that implements the same interface."

I wouldn't bother to go into more detail about "implements the same interface" - all sane people will just subclass Action. ;-)

As to argparse.Action.__init__, hopefully the above bullet points make it clear that you must accept "dest" and "option_strings", but what other keyword arguments you want to accept are up to you. Be sure to call the superclass __init__ to set any attributes that you didn't accept to appropriate default values. A simple example of accepting an additional keyword argument is the _VersionAction, which accepts a "version" keyword argument that the other actions don't accept. The current "example of a custom action" should probably define __init__ to show how this works.
History
Date User Action Args
2011-12-15 10:16:39bethardsetrecipients: + bethard, terry.reedy, jaraco, eric.araujo, docs@python
2011-12-15 10:16:38bethardsetmessageid: <1323944198.95.0.291707373871.issue13540@psf.upfronthosting.co.za>
2011-12-15 10:16:38bethardlinkissue13540 messages
2011-12-15 10:16:37bethardcreate