I'm trying to get to know optparse
a bit better, but I'm struggling to understand why the following code behaves the way it does. Am I doing something stupid?
import optparse
def store_test(option, opt_str, value, parser, args=None, kwargs=None):
print 'opt_str:', opt_str
print 'value:', value
op = optparse.OptionParser()
op.add_option('-t', '--test', action='callback', callback=store_test, default='test',
dest='test', help='test!')
(opts, args) = op.parse_args(['test.py', '-t', 'foo'])
print
print 'opts:'
print opts
print 'args:'
print args
Output:
opt_str: -t value: None opts: {'test': 'test'} args: ['foo']
Why is 'foo'
not being passed to store_test()
and instead being interpreted as an extra argument? Is there something wrong with op.parse_args(['-t', 'foo'])
?
Edit:
Here's the example from the docs:
def store_value(option, opt_str, value, parser):
setattr(parser.values, option.dest, value)
[...]
parser.add_option("--foo",
action="callback", callback=store_value,
type="int", nargs=3, dest="foo")
You're missing a "type" or "nargs" option attribute:
op.add_option('-t', '--test', action='callback', callback=store_test, default='test',
dest='test', help='test!', type='str')
This option will cause it to consume the next argument.
Reference: http://docs.python.org/library/optparse.html#optparse-option-callbacks
type
has its usual meaning: as with the "store" or "append" actions, it instructs optparse to consume one argument and convert it to type. Rather than storing the converted value(s) anywhere, though, optparse passes it to your callback function.nargs
also has its usual meaning: if it is supplied and > 1, optparse will consume nargs arguments, each of which must be convertible to type. It then passes a tuple of converted values to your callback.
This seems to be the relevant code from optparse.py
:
def takes_value(self):
return self.type is not None
def _process_short_opts(self, rargs, values):
[...]
if option.takes_value():
# Any characters left in arg? Pretend they're the
# next arg, and stop consuming characters of arg.
if i < len(arg):
rargs.insert(0, arg[i:])
stop = True
nargs = option.nargs
if len(rargs) < nargs:
if nargs == 1:
self.error(_("%s option requires an argument") % opt)
else:
self.error(_("%s option requires %d arguments")
% (opt, nargs))
elif nargs == 1:
value = rargs.pop(0)
else:
value = tuple(rargs[0:nargs])
del rargs[0:nargs]
else: # option doesn't take a value
value = None
option.process(opt, value, values, self)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With