Mercurial > python-cmd2
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() |