callback function: options.dest is None and prevents updating parser.values

"Joe Friedrichsen" <[email protected]> Mon, 18 Jun 2007 00:02:54 -0600
Newsgroups gmane.comp.python.optik.user
Message-ID <[email protected]>
Hi everyone,

I'm trying to write a callback function for optparse and am having
some trouble. I need a few options to accept a variable number of
arguments, and so I based my variable_args callback function off of
the example in the docs (
http://www.python.org/doc/2.4.4/lib/optparse-callback-example-6.html
-- I'm using Debian Etch, so it's python 2.4.4 for me :-)

I made the function a little more exact in knowing when to quit adding
arguments to the current option, and that part part is working well so
far. However, the function cannot update parser.values because
option.dest is None.

I'm confused because I've defined the dest for this option:
dest="threads". What's even more strange is that option.action is
'help'. This makes me think that while the correct callback function
was triggered for its corresponding option, the option object is
either incorrect or not fully initialized.

I've added all of the details below, both code and console output. The
print statements show that things aren't quite right. If anyone has
any insight about why I would get this behavior and how I can get it
working correctly, please tell me.

Thanks,
Joe

#######
####### Code
#######

    def variable_args(option, opt_str, value, parser):
        """Parse options that have a variable number of arguments

        """
        me = 'variable_args'
        assert value is None
        value = []
        rargs = parser.rargs

        # Group all of the parser's options
        all_options = []
        for option in parser.option_list:
            all_options = all_options + option._short_opts + option._long_opts
        print "%s: parser options = %s" % (me, all_options)
        print "%s: rargs = %s" % (me, rargs)
        while rargs:
            arg = rargs[0]

            # Stop if we hit an arg in the parser
            if arg in all_options:
                print "%s: breaking... found '%s'" % (me, arg)
                break
            else:
                print "%s: adding argument '%s'" % (me, arg)
                value.append(arg)
                del rargs[0]

        print "%s: parser.values = %s" % (me, parser.values)
        print "%s: option.dest = %s" % (me, option.dest)
        print "%s: value = %s" % (me, value)
        print "%s: option.action = %s" % (me, option.action)
        setattr(parser.values, option.dest, value)

    # Define the command line arguments
    from optparse import OptionParser, make_option
    option_list = [
    make_option("-t", "--threads",
            help="Threads to translate (comma-separated list of IDs or URLs)",
            metavar="'THREAD, LIST[, ...]'", dest="threads",
            action="callback", callback=variable_args),
    make_option("-p", "--posts",
            help="Posts to translate (comma-separated list of IDs or URLs)",
            metavar="'POST, LIST[, ...]'", dest="posts"),
    make_option("-c", "--categories",
            help="Categories to add posts to (commma-separated list)",
            metavar="'CATEGORY, LIST[, ...]'", dest="categories"),
    make_option("-a", "--authors",
            help="Author mappings (comma-separated list)",
            metavar="BB_AUTH:WP_AUTH[, ...]", dest="authors", ),
    make_option("-v", "--verbosity",
            help="Set the amount of output messages given", metavar="NUM",
            dest="verbosity", type="int"),
    make_option("--verbose",
            help="Set verbosity to 5",
            dest="verbosity", action="store_const", const=5),
    make_option("-q", "--quiet",
            help="Set verbosity to 0 (only error messages)",
            dest="verbosity", action="store_const", const=0)
    ]

    # Setup the parser
    opt_parser = OptionParser(usage="%prog [options]", version="%prog 0.20",
            description="Move PHPbb threads/posts to a WordPress blog",
            option_list=option_list)
    opt_parser.set_defaults(verbosity=1)

    # Grab the command line options
    (opts, args) = opt_parser.parse_args()

#######
####### Console
#######

$ ./phpbb2wp.py -c "Travel" -t 24 68 76 -a "BB Author 1: WP Author, BB
Author 2: WP Author"
variable_args: parser options = ['-t', '--threads', '-p', '--posts',
'-c', '--categories', '-a', '--authors', '-v', '--verbosity',
'--verbose', '-q', '--quiet', '--version', '-h', '--help']
variable_args: rargs = ['24', '68', '76', '-a', 'BB Author 1: WP
Author, BB Author 2: WP Author']
variable_args: adding argument '24'
variable_args: adding argument '68'
variable_args: adding argument '76'
variable_args: breaking... found '-a'
variable_args: parser.values = {'threads': None, 'verbosity': 1,
'posts': None, 'categories': 'Travel', 'authors': None}
variable_args: option.dest = None
variable_args: value = ['24', '68', '76']
variable_args: option.action = help
Traceback (most recent call last):
  File "./phpbb2wp.py", line 825, in ?
    main()
  File "./phpbb2wp.py", line 766, in main
    (opts, args) = opt_parser.parse_args()
  File "/usr/lib/python2.4/optparse.py", line 1280, in parse_args
    stop = self._process_args(largs, rargs, values)
  File "/usr/lib/python2.4/optparse.py", line 1324, in _process_args
    self._process_short_opts(rargs, values)
  File "/usr/lib/python2.4/optparse.py", line 1431, in _process_short_opts
    option.process(opt, value, values, self)
  File "/usr/lib/python2.4/optparse.py", line 712, in process
    return self.take_action(
  File "/usr/lib/python2.4/optparse.py", line 731, in take_action
    self.callback(self, opt, value, parser, *args, **kwargs)
  File "./phpbb2wp.py", line 730, in variable_args
    setattr(parser.values, option.dest, value)
TypeError: attribute name must be string

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/