Sébastien
Sébastien

Reputation: 14841

Python optparse: how to make a repeatable group of options?

Here is a simplified view of the script I am programming in python:

So I would like to use it like this:

compare.py -L local.txt -L local2.txt -p /tmp/

or

compare.py -L local.txt -R remote.txt -p remoteDir/ --myFlag

So I need to define 2 groups of options (local/L and remote/R), each containing its own set of mandatory and optional options.

I have not found a way to achieve this with optparse (or even argparse, but I'd like to stick with optparse if possible as I'm writing the script for Python 2.6.7)

Is there any clean solution ?

Upvotes: 1

Views: 640

Answers (2)

Robert Lujo
Robert Lujo

Reputation: 16391

I would do it with option callbacks + helper object which traces context of the current option. Example:

from optparse import OptionParser

class FileBase(object):
    def __init__(self, fname):
        self.fname = fname
        self.path = None
class LocalFile(FileBase):
    pass
class RemoteFile(FileBase):
    pass

class FileOptionParser(object):
    def __init__(self):
        self.last_file = None
        self.files = []

    def set_path(self, option, opt, value, parser):
        self.last_file.path = value

    def set_file(self, option, opt, value, parser):
        if   option.dest=="local" : cls = LocalFile
        elif option.dest=="remote": cls = RemoteFile
        else:                       assert False
        self.last_file = cls(value)
        self.files.append(self.last_file)
        setattr(parser.values, option.dest, self.last_file)

fop = FileOptionParser()

parser = OptionParser()
parser.add_option('-L', '--local',  type='string', action='callback', callback=fop.set_file)
parser.add_option('-R', '--remote', type='string', action='callback', callback=fop.set_file)
parser.add_option('-p', '--path',   type='string', action='callback', callback=fop.set_path)

(options, args) = parser.parse_args()
print [(f.fname, f.path) for f in fop.files]

example is:

> python test.py -L local.txt -R remote.txt -p remoteDir/
[('local.txt', None), ('remote.txt', 'remoteDir/')]

Upvotes: 3

Alfe
Alfe

Reputation: 59576

I think the answer is that you are not talking about options anymore but about arguments to your program. Options are modifiers which (optionally) can be given to influence the behavior of your program; arguments on the other side are the input data the program shall work on (additional to stdin in some cases).

Having that said, I think you should make your optional boolean flag an option and all other information arguments to be parsed after optparse has done its work. Figure out a neat syntax to specify what argument specifies a local file and what specifies a remote file, e. g. /path/to/local/file and host:/path/to/remote/file (although this syntax is used by things like rsync, keep in mind that it has problems with colons : in path names).

Upvotes: 0

Related Questions