1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 from __future__ import nested_scopes
21 import os
22 import re
23 import string
24 import types
25
26
27
28
29
31 """A 'Label' identifies an entity.
32
33 A 'Label' is a generalization of a filename. Like filenames, labels
34 consist of one or more directories followed by a basename. However,
35 the format used for a label need not be the same as that used by
36 filenames.
37
38 Each label class defines a separator character to take the place of
39 the '/' character used by many file systems.
40
41 All labels are relative labels; no label may begin with a separator
42 character."""
43
45 """Construct a new 'Label'.
46
47 'label' -- A string giving the value of the label."""
48
49 assert type(label) in (types.StringType, types.UnicodeType)
50 self._label = label
51
52
53 - def Join(self, *labels):
54 """Combine this label and the 'labels' into a single label.
55
56 'labels' -- A sequence of strings giving the components of the
57 new label. All but the last are taken as directory names; the
58 last is treated as a basename."""
59
60 result = self._label
61 for l in labels:
62 if not result:
63
64 result = l
65 elif result and result[-1] == self._sep:
66
67
68 result += l
69 else:
70 result = result + self._sep + l
71
72 return self.__class__(result)
73
74
76 """Split the label into a pair '(directory, basename)'.
77
78 returns -- A pair '(directory, basename)', each of which is
79 a label.
80
81 It is always true that 'directory.join(basename)' will return a
82 label equivalent to the original label."""
83
84 last_sep = self._label.rfind(self._sep)
85 if last_sep != -1:
86 return (self.__class__(self._label[:last_sep]),
87 self.__class__(self._label[last_sep + 1:]))
88 else:
89 return (self.__class__(""),
90 self.__class__(self._label))
91
92
94 """Split the label into a pair '(parent, subpath)'. This is
95 the same operation as Split, except the split occurs at the
96 leftmost separator, not the rightmost.
97
98 returns -- A pair '(directory, basename)', each of which is
99 a label.
100
101 It is always true that 'directory.join(basename)' will return a
102 label equivalent to the original label."""
103
104 first_sep = self._label.find(self._sep)
105 if first_sep != -1:
106 return (self.__class__(self._label[:first_sep]),
107 self.__class__(self._label[first_sep + 1:]))
108 else:
109 return (self.__class__(self._label),
110 self.__class__(""))
111
112
114 """Return the basename for the label.
115
116 returns -- A string giving the basename for the label. The
117 value returned for 'l.basename()' is always the same as
118 'l.split()[1]'."""
119
120 return self.Split()[1]
121
122
124 """Return the directory name for the 'label'.
125
126 returns -- A string giving the directory name for the 'label'.
127 The value returned for 'l.dirname()' is always the same as
128 'l.split()[0]'."""
129
130 return self.Split()[0]
131
132
133 - def IsValid(self, label, is_component):
134 """Returns true if 'label' is valid.
135
136 'label' -- The string being tested for validity.
137
138 'is_component' -- True if the string being tested is just a
139 single component of a label path.
140
141 returns -- True if 'label' is not valid."""
142
143 if label and label[0] == self._sep:
144
145
146 return 0
147 elif is_component and self._sep in label:
148
149 return 0
150 elif label.find(self._sep + self._sep) != -1:
151
152 return 0
153
154 return 1
155
156
158 """Return the string form of this label."""
159
160 return self._label
161
162
163
164
165
166 __thunk_regex = re.compile("[^a-z0-9_]")
167
190
191
192
193
194
195
196
197