annotate flagReader.py @ 0:febfdc79550b

moved repository to Assembla
author catherine@DellZilla.myhome.westell.com
date Wed, 05 Mar 2008 12:16:19 -0500
parents
children f807c5cfa0de
rev   line source
0
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
1 """Defines and parses UNIX-style flags to modify command arguments.
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
2
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
3 print flagReader.FlagSet.parse.__doc__ for usage examples.
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
4 """
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
5
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
6 import re
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
7
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
8 class Flag(object):
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
9 def __init__(self, name, abbrev=None, nargs=0):
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
10 """Flag(name, abbrev=None, nargs=0) : Defines a flag.
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
11
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
12 name: the full name of the flag (double-dash form)
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
13 abbrev: the single-letter abbreviated form of the flag; defaults to
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
14 nargs: number of arguments expected after the flag"""
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
15
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
16 self.name = name
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
17 self.abbrev = abbrev or name[0]
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
18 self.fullabbrev = '-%s' % (self.abbrev)
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
19 self.fullname = '--%s' % (name)
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
20 self.nargs = nargs
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
21
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
22 class FlagSet(object):
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
23 def __init__(self, flags):
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
24 if not issubclass(type(flags), list):
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
25 raise TypeError, 'Argument must be a list'
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
26 self.flags = flags
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
27 self.lookup = {}
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
28 for flag in self.flags:
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
29 self.lookup[flag.abbrev] = flag
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
30 self.lookup[flag.fullabbrev] = flag
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
31 self.lookup[flag.fullname] = flag
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
32 self.abbrevPattern = re.compile('^-([%s]+)$' % (''.join(f.abbrev for f in flags)))
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
33 def parse(self, arg):
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
34 """
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
35 Finds flags; returns {flag: (values, if any)} and the remaining argument.
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
36
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
37 >>> f = FlagSet([Flag('foo'), Flag('bar'), Flag('gimmea', nargs=1)])
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
38 >>> f.parse('-fb')
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
39 ({'foo': [], 'bar': []}, '')
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
40 >>> f.parse('no flags')
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
41 ({}, 'no flags')
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
42 >>> f.parse('-f blah')
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
43 ({'foo': []}, 'blah')
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
44 >>> f.parse('--bar')
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
45 ({'bar': []}, '')
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
46 >>> f.parse('--bar -f')
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
47 ({'foo': [], 'bar': []}, '')
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
48 >>> f.parse('--notaflag')
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
49 ({}, '--notaflag')
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
50 >>> f.parse('')
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
51 ({}, '')
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
52 >>> f.parse('--gimmea bee -f and then some other stuff')
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
53 ({'gimmea': ['bee'], 'foo': []}, 'and then some other stuff')
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
54 >>> f.parse('hidden -bar')
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
55 ({}, 'hidden -bar')
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
56 >>> f.parse('-g myarg -b')
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
57 ({'gimmea': ['myarg'], 'bar': []}, '')
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
58 """
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
59 result = {}
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
60 words = arg.split()
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
61 while words:
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
62 word = words[0]
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
63 flag = self.lookup.get(word)
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
64 if flag:
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
65 result[flag.name] = []
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
66 words.pop(0)
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
67 for arg in range(flag.nargs):
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
68 try:
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
69 result[flag.name].append(words.pop(0))
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
70 except IndexError: # there aren't as many args as we expect
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
71 raise IndexError, '%s expects %d arguments' % (word, flag.nargs)
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
72 continue # on to next word
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
73 smashedAbbrevs = self.abbrevPattern.search(word)
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
74 if smashedAbbrevs:
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
75 for abbrev in smashedAbbrevs.group(1):
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
76 result[self.lookup[abbrev].name] = []
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
77 words.pop(0)
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
78 continue # on to next word
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
79 #if you get to here, word[0] does not denote options
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
80 break
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
81 return result, ' '.join(words)
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
82
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
83 def _test():
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
84 import doctest
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
85 doctest.testmod()
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
86
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
87 if __name__ == '__main__':
febfdc79550b moved repository to Assembla
catherine@DellZilla.myhome.westell.com
parents:
diff changeset
88 _test()