Option parser question - reading options from file as well as command line

Tim N. van der Leeuw tim.leeuwvander at nl.unisys.com
Mon May 22 15:18:43 EDT 2006


Andrew Robert wrote:
> Hi Everyone.
>
>
> I tried the following to get input into optionparser from either a file
> or command line.
>
>

Hi Andrew,

I played around a bit more, not happy that the read_file method which I
discovered earlier on the Values - object takes a property-file like
input and doesn't call any callbacks (for instance).

So I wrote a little module to provide an option-parser callback for
reading arguments from file...

Since it seems that Google Groups doesn't allow me to attach the file,
I'll paste it into here, hoping that nobody objects very strongly:

===============================
"""Callback for optparse.OptionParser that interprets a command-line
argument as filename, reads the file, and adds the contents of the file
to the options to be parsed by the OptionParser.

Usage:

>>> from args_from_file import add_argsfile_option
>>> from optparse import OptionValueError
>>> import sys
>>> op = OptionParser()
>>> add_argsfile_option(op, '-f', '--file')
>>> op.parse_args(sys.argv)

(This sample assumes that on the command-line, there is an option '-f'
or '--file'followed by the filename with options you wish to add to
the command-line).

The implementation reads the entire contents of the file into memory.

(c) Copyright 2006 Tim N. van der Leeuw (tim.leeuwvander at nl.unisys.com)
"""
import re
from optparse import OptionValueError

#SPLIT_ARGS = r'("[^"]*"|\'[^\']*\'|[^\s]+)'
SPLIT_ARGS = r'((?:")([^"]*)(?:")|(?:\')([^\']*)(?:\')|[^\s]+)'
g_split_args_re = None

def extract_args_from_string(arg_str, append_to=None):
    global g_split_args_re
    if not g_split_args_re:
        g_split_args_re = re.compile(SPLIT_ARGS)
    argv = g_split_args_re.findall(arg_str)
    argv = ([v for v in x if v <> ''][-1] for x in argv)
    if not append_to is None:
        return append_to.extend(argv)
    else:
        return list(argv)

def load_file(filename, skip_comments=True):
    f = None
    try:
        f = open(filename, 'rb', 16384)
        if skip_comments:
            lines = "".join((line for line in f if line.strip()[0] <>
'#'))
        else:
            lines = "".join(f)
        return lines
    finally:
        if f <> None:
            f.close()

def optparse_cb_load_args_from_file(option, opt, value, parser):
    try:
        args = load_file(value)
        extract_args_from_string(args, parser.rargs)
    except Exception, e:
        raise OptionValueError(
            'Error parsing argument %s, with reading options from
option-file "%s". Originating error: %s' %
            (opt, value, e))
    return

def add_argsfile_option(parser, *option_names):
    return parser.add_option(*option_names,
                      **{'type':'string',
                         'action':'callback',
                         'callback':optparse_cb_load_args_from_file})
===============================

Feel free to use as you like. Might make a nice addition to the
standard action types of optparse in the standard library? If there's
interest in that, I might try to write a patch for optparse.

Cheers,

--Tim




More information about the Python-list mailing list