Michele Petrazzo wrote:
I'm trying optparse and I see a strange (for me) behavior:
def store_value(option, opt_str, value, parser):
setattr(parser.values, option.dest, value)
parser = optparse.OptionParser()
parser.add_option(-f, --foo,
action=callback, callback=store_value,
type=int, dest=foo)
args = [-f, 1]
(options, args) = parser.parse_args(args)
print options, args
{'foo': 1} [] # with the type
{'foo': None} ['1'] #without it
If I not specify the type in add_options, the value aren't passed to the
store_value (into value variable), but it's understood as args!
If I specify it, it
Is this normal?
I believe so. The optparse module lists 'callback' as one of the
TYPED_ACTIONS but not one of the ALWAYS_TYPED_ACTIONS, so it should only
set nargs=1 if a type= argument was provided. That means that callbacks
will be assumed to take zero arguments until you pass an nargs= or a
type= argument.
You can try using argparse_, which doesn't make these weird inferences,
and generally assumes that your action will take a single argument
unless you specify otherwise::
import argparse
class StoreValue(argparse.Action):
... def __call__(self, parser, namespace, value, opt_str=None):
... setattr(namespace, self.dest, value)
...
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--foo', action=StoreValue)
parser.parse_args('-f 1'.split())
Namespace(foo='1')
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--foo', action=StoreValue, type=int)
parser.parse_args('-f 1'.split())
Namespace(foo=1)
Not sure exactly what your callback was trying to do though -- it seems
like you're just duplicating the 'store' action (which is the default
anyway).
FWIW, if you want to write a custom action in argparse, you don't have
to worry about the weird TYPED_ACTIONS kinds of things in optparse.
Just specify in the action's constructor whatever defaults you need, e.g.::
class MyStoreValue(argparse.Action):
... def __init__(self, nargs=2, type=int, **kwargs):
... superinit = super(MyStoreValue, self).__init__
... superinit(nargs=nargs, type=type, **kwargs)
... def __call__(self, parser, namespace, value, opt_str=None):
... setattr(namespace, self.dest, value)
...
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--foo', action=MyStoreValue)
parser.parse_args('-f 1 2'.split())
Namespace(foo=[1, 2])
Of course, you can always specify nargs= and type= in the
``add_argument()`` call too.
.. _argparse: http://argparse.python-hosting.com/
STeVe
--
http://mail.python.org/mailman/listinfo/python-list