argparse missing optparse capabilities?

rurpy at rurpy at
Thu Jan 5 03:05:16 EST 2012

I have optparse code that parses a command line containing
intermixed positional and optional arguments, where the optional
arguments set the context for the following positional arguments.
For example, arg1 -c33 arg2 arg3 -c44 arg4

'arg1' is processed in a default context, 'args2' and 'arg3' in
context '33', and 'arg4' in context '44'.

I am trying to do the same using argparse but it appears to be
not doable in a documented way.

Here is the working optparse code (which took 30 minutes to write
using just the optparse docs):

  import optparse
  def append_with_pos (option, opt_str, value, parser):
        if getattr (parser.values, option.dest, None) is None:
            setattr (parser.values, option.dest, [])
        getattr (parser.values, option.dest).append ((value, len
  def opt_parse():
        p = optparse.OptionParser()
        p.add_option ("-c", type=int,
            action='callback', callback=append_with_pos)
        opts, args = p.parse_args()
        return args, opts
  if __name__ == '__main__':
        args, opts = opt_parse()
        print args, opts

Output from the command line above:
  ['arg1', 'arg2', 'arg3', 'arg4'] {'c': [(33, 1), (44, 3)]}
The -c values are stored as (value, arglist_position) tuples.

Here is an attempt to convert to argparse using the guidelines
in the argparse docs:

  import argparse
  class AppendWithPos (argparse.Action):
    def __call__ (self, parser, namespace, values,
        if getattr (namespace, self.dest, None) is None:
            setattr (namespace, self.dest, [])
        getattr (namespace, self.dest).extend ((values, len
  def arg_parse():
	p = argparse.ArgumentParser (description='description')
	p.add_argument ('src', nargs='*')
	p.add_argument ('-c', type=int, action=AppendWithPos)
	opts = p.parse_args()
	return opts
  if __name__ == '__main__':
        opts = arg_parse()
        print opts

This fails with,
  AttributeError: 'ArgumentParser' object has no attribute 'largs'
and of course, the argparse.parser is not documented beyond how
to instantiate it.  Even were that not a problem, argparse complains
about "unrecognised arguments" for any positional arguments that
occur after an optional one.  I've been farting with this code for
a day now.

Any suggestions on how I can convince argparse to do what optparse
does easily will be very welcome.  (I tried parse_known_args() but
that breaks help and requires me to detect truly unknown arguments.)

(Python 2.7.1 if it matters and apologies if Google mangles
the formatting of this post.)

More information about the Python-list mailing list