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