]>
Commit | Line | Data |
---|---|---|
3257aa99 DM |
1 | """A collection of string operations (most are no longer used).\r |
2 | \r | |
3 | Warning: most of the code you see here isn't normally used nowadays.\r | |
4 | Beginning with Python 1.6, many of these functions are implemented as\r | |
5 | methods on the standard string object. They used to be implemented by\r | |
6 | a built-in module called strop, but strop is now obsolete itself.\r | |
7 | \r | |
8 | Public module variables:\r | |
9 | \r | |
10 | whitespace -- a string containing all characters considered whitespace\r | |
11 | lowercase -- a string containing all characters considered lowercase letters\r | |
12 | uppercase -- a string containing all characters considered uppercase letters\r | |
13 | letters -- a string containing all characters considered letters\r | |
14 | digits -- a string containing all characters considered decimal digits\r | |
15 | hexdigits -- a string containing all characters considered hexadecimal digits\r | |
16 | octdigits -- a string containing all characters considered octal digits\r | |
17 | punctuation -- a string containing all characters considered punctuation\r | |
18 | printable -- a string containing all characters considered printable\r | |
19 | \r | |
20 | """\r | |
21 | \r | |
22 | # Some strings for ctype-style character classification\r | |
23 | whitespace = ' \t\n\r\v\f'\r | |
24 | lowercase = 'abcdefghijklmnopqrstuvwxyz'\r | |
25 | uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'\r | |
26 | letters = lowercase + uppercase\r | |
27 | ascii_lowercase = lowercase\r | |
28 | ascii_uppercase = uppercase\r | |
29 | ascii_letters = ascii_lowercase + ascii_uppercase\r | |
30 | digits = '0123456789'\r | |
31 | hexdigits = digits + 'abcdef' + 'ABCDEF'\r | |
32 | octdigits = '01234567'\r | |
33 | punctuation = """!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"""\r | |
34 | printable = digits + letters + punctuation + whitespace\r | |
35 | \r | |
36 | # Case conversion helpers\r | |
37 | # Use str to convert Unicode literal in case of -U\r | |
38 | l = map(chr, xrange(256))\r | |
39 | _idmap = str('').join(l)\r | |
40 | del l\r | |
41 | \r | |
42 | # Functions which aren't available as string methods.\r | |
43 | \r | |
44 | # Capitalize the words in a string, e.g. " aBc dEf " -> "Abc Def".\r | |
45 | def capwords(s, sep=None):\r | |
46 | """capwords(s [,sep]) -> string\r | |
47 | \r | |
48 | Split the argument into words using split, capitalize each\r | |
49 | word using capitalize, and join the capitalized words using\r | |
50 | join. If the optional second argument sep is absent or None,\r | |
51 | runs of whitespace characters are replaced by a single space\r | |
52 | and leading and trailing whitespace are removed, otherwise\r | |
53 | sep is used to split and join the words.\r | |
54 | \r | |
55 | """\r | |
56 | return (sep or ' ').join(x.capitalize() for x in s.split(sep))\r | |
57 | \r | |
58 | \r | |
59 | # Construct a translation string\r | |
60 | _idmapL = None\r | |
61 | def maketrans(fromstr, tostr):\r | |
62 | """maketrans(frm, to) -> string\r | |
63 | \r | |
64 | Return a translation table (a string of 256 bytes long)\r | |
65 | suitable for use in string.translate. The strings frm and to\r | |
66 | must be of the same length.\r | |
67 | \r | |
68 | """\r | |
69 | if len(fromstr) != len(tostr):\r | |
70 | raise ValueError, "maketrans arguments must have same length"\r | |
71 | global _idmapL\r | |
72 | if not _idmapL:\r | |
73 | _idmapL = list(_idmap)\r | |
74 | L = _idmapL[:]\r | |
75 | fromstr = map(ord, fromstr)\r | |
76 | for i in range(len(fromstr)):\r | |
77 | L[fromstr[i]] = tostr[i]\r | |
78 | return ''.join(L)\r | |
79 | \r | |
80 | \r | |
81 | \r | |
82 | ####################################################################\r | |
83 | import re as _re\r | |
84 | \r | |
85 | class _multimap:\r | |
86 | """Helper class for combining multiple mappings.\r | |
87 | \r | |
88 | Used by .{safe_,}substitute() to combine the mapping and keyword\r | |
89 | arguments.\r | |
90 | """\r | |
91 | def __init__(self, primary, secondary):\r | |
92 | self._primary = primary\r | |
93 | self._secondary = secondary\r | |
94 | \r | |
95 | def __getitem__(self, key):\r | |
96 | try:\r | |
97 | return self._primary[key]\r | |
98 | except KeyError:\r | |
99 | return self._secondary[key]\r | |
100 | \r | |
101 | \r | |
102 | class _TemplateMetaclass(type):\r | |
103 | pattern = r"""\r | |
104 | %(delim)s(?:\r | |
105 | (?P<escaped>%(delim)s) | # Escape sequence of two delimiters\r | |
106 | (?P<named>%(id)s) | # delimiter and a Python identifier\r | |
107 | {(?P<braced>%(id)s)} | # delimiter and a braced identifier\r | |
108 | (?P<invalid>) # Other ill-formed delimiter exprs\r | |
109 | )\r | |
110 | """\r | |
111 | \r | |
112 | def __init__(cls, name, bases, dct):\r | |
113 | super(_TemplateMetaclass, cls).__init__(name, bases, dct)\r | |
114 | if 'pattern' in dct:\r | |
115 | pattern = cls.pattern\r | |
116 | else:\r | |
117 | pattern = _TemplateMetaclass.pattern % {\r | |
118 | 'delim' : _re.escape(cls.delimiter),\r | |
119 | 'id' : cls.idpattern,\r | |
120 | }\r | |
121 | cls.pattern = _re.compile(pattern, _re.IGNORECASE | _re.VERBOSE)\r | |
122 | \r | |
123 | \r | |
124 | class Template:\r | |
125 | """A string class for supporting $-substitutions."""\r | |
126 | __metaclass__ = _TemplateMetaclass\r | |
127 | \r | |
128 | delimiter = '$'\r | |
129 | idpattern = r'[_a-z][_a-z0-9]*'\r | |
130 | \r | |
131 | def __init__(self, template):\r | |
132 | self.template = template\r | |
133 | \r | |
134 | # Search for $$, $identifier, ${identifier}, and any bare $'s\r | |
135 | \r | |
136 | def _invalid(self, mo):\r | |
137 | i = mo.start('invalid')\r | |
138 | lines = self.template[:i].splitlines(True)\r | |
139 | if not lines:\r | |
140 | colno = 1\r | |
141 | lineno = 1\r | |
142 | else:\r | |
143 | colno = i - len(''.join(lines[:-1]))\r | |
144 | lineno = len(lines)\r | |
145 | raise ValueError('Invalid placeholder in string: line %d, col %d' %\r | |
146 | (lineno, colno))\r | |
147 | \r | |
148 | def substitute(*args, **kws):\r | |
149 | if not args:\r | |
150 | raise TypeError("descriptor 'substitute' of 'Template' object "\r | |
151 | "needs an argument")\r | |
152 | self, args = args[0], args[1:] # allow the "self" keyword be passed\r | |
153 | if len(args) > 1:\r | |
154 | raise TypeError('Too many positional arguments')\r | |
155 | if not args:\r | |
156 | mapping = kws\r | |
157 | elif kws:\r | |
158 | mapping = _multimap(kws, args[0])\r | |
159 | else:\r | |
160 | mapping = args[0]\r | |
161 | # Helper function for .sub()\r | |
162 | def convert(mo):\r | |
163 | # Check the most common path first.\r | |
164 | named = mo.group('named') or mo.group('braced')\r | |
165 | if named is not None:\r | |
166 | val = mapping[named]\r | |
167 | # We use this idiom instead of str() because the latter will\r | |
168 | # fail if val is a Unicode containing non-ASCII characters.\r | |
169 | return '%s' % (val,)\r | |
170 | if mo.group('escaped') is not None:\r | |
171 | return self.delimiter\r | |
172 | if mo.group('invalid') is not None:\r | |
173 | self._invalid(mo)\r | |
174 | raise ValueError('Unrecognized named group in pattern',\r | |
175 | self.pattern)\r | |
176 | return self.pattern.sub(convert, self.template)\r | |
177 | \r | |
178 | def safe_substitute(*args, **kws):\r | |
179 | if not args:\r | |
180 | raise TypeError("descriptor 'safe_substitute' of 'Template' object "\r | |
181 | "needs an argument")\r | |
182 | self, args = args[0], args[1:] # allow the "self" keyword be passed\r | |
183 | if len(args) > 1:\r | |
184 | raise TypeError('Too many positional arguments')\r | |
185 | if not args:\r | |
186 | mapping = kws\r | |
187 | elif kws:\r | |
188 | mapping = _multimap(kws, args[0])\r | |
189 | else:\r | |
190 | mapping = args[0]\r | |
191 | # Helper function for .sub()\r | |
192 | def convert(mo):\r | |
193 | named = mo.group('named') or mo.group('braced')\r | |
194 | if named is not None:\r | |
195 | try:\r | |
196 | # We use this idiom instead of str() because the latter\r | |
197 | # will fail if val is a Unicode containing non-ASCII\r | |
198 | return '%s' % (mapping[named],)\r | |
199 | except KeyError:\r | |
200 | return mo.group()\r | |
201 | if mo.group('escaped') is not None:\r | |
202 | return self.delimiter\r | |
203 | if mo.group('invalid') is not None:\r | |
204 | return mo.group()\r | |
205 | raise ValueError('Unrecognized named group in pattern',\r | |
206 | self.pattern)\r | |
207 | return self.pattern.sub(convert, self.template)\r | |
208 | \r | |
209 | \r | |
210 | \r | |
211 | ####################################################################\r | |
212 | # NOTE: Everything below here is deprecated. Use string methods instead.\r | |
213 | # This stuff will go away in Python 3.0.\r | |
214 | \r | |
215 | # Backward compatible names for exceptions\r | |
216 | index_error = ValueError\r | |
217 | atoi_error = ValueError\r | |
218 | atof_error = ValueError\r | |
219 | atol_error = ValueError\r | |
220 | \r | |
221 | # convert UPPER CASE letters to lower case\r | |
222 | def lower(s):\r | |
223 | """lower(s) -> string\r | |
224 | \r | |
225 | Return a copy of the string s converted to lowercase.\r | |
226 | \r | |
227 | """\r | |
228 | return s.lower()\r | |
229 | \r | |
230 | # Convert lower case letters to UPPER CASE\r | |
231 | def upper(s):\r | |
232 | """upper(s) -> string\r | |
233 | \r | |
234 | Return a copy of the string s converted to uppercase.\r | |
235 | \r | |
236 | """\r | |
237 | return s.upper()\r | |
238 | \r | |
239 | # Swap lower case letters and UPPER CASE\r | |
240 | def swapcase(s):\r | |
241 | """swapcase(s) -> string\r | |
242 | \r | |
243 | Return a copy of the string s with upper case characters\r | |
244 | converted to lowercase and vice versa.\r | |
245 | \r | |
246 | """\r | |
247 | return s.swapcase()\r | |
248 | \r | |
249 | # Strip leading and trailing tabs and spaces\r | |
250 | def strip(s, chars=None):\r | |
251 | """strip(s [,chars]) -> string\r | |
252 | \r | |
253 | Return a copy of the string s with leading and trailing\r | |
254 | whitespace removed.\r | |
255 | If chars is given and not None, remove characters in chars instead.\r | |
256 | If chars is unicode, S will be converted to unicode before stripping.\r | |
257 | \r | |
258 | """\r | |
259 | return s.strip(chars)\r | |
260 | \r | |
261 | # Strip leading tabs and spaces\r | |
262 | def lstrip(s, chars=None):\r | |
263 | """lstrip(s [,chars]) -> string\r | |
264 | \r | |
265 | Return a copy of the string s with leading whitespace removed.\r | |
266 | If chars is given and not None, remove characters in chars instead.\r | |
267 | \r | |
268 | """\r | |
269 | return s.lstrip(chars)\r | |
270 | \r | |
271 | # Strip trailing tabs and spaces\r | |
272 | def rstrip(s, chars=None):\r | |
273 | """rstrip(s [,chars]) -> string\r | |
274 | \r | |
275 | Return a copy of the string s with trailing whitespace removed.\r | |
276 | If chars is given and not None, remove characters in chars instead.\r | |
277 | \r | |
278 | """\r | |
279 | return s.rstrip(chars)\r | |
280 | \r | |
281 | \r | |
282 | # Split a string into a list of space/tab-separated words\r | |
283 | def split(s, sep=None, maxsplit=-1):\r | |
284 | """split(s [,sep [,maxsplit]]) -> list of strings\r | |
285 | \r | |
286 | Return a list of the words in the string s, using sep as the\r | |
287 | delimiter string. If maxsplit is given, splits at no more than\r | |
288 | maxsplit places (resulting in at most maxsplit+1 words). If sep\r | |
289 | is not specified or is None, any whitespace string is a separator.\r | |
290 | \r | |
291 | (split and splitfields are synonymous)\r | |
292 | \r | |
293 | """\r | |
294 | return s.split(sep, maxsplit)\r | |
295 | splitfields = split\r | |
296 | \r | |
297 | # Split a string into a list of space/tab-separated words\r | |
298 | def rsplit(s, sep=None, maxsplit=-1):\r | |
299 | """rsplit(s [,sep [,maxsplit]]) -> list of strings\r | |
300 | \r | |
301 | Return a list of the words in the string s, using sep as the\r | |
302 | delimiter string, starting at the end of the string and working\r | |
303 | to the front. If maxsplit is given, at most maxsplit splits are\r | |
304 | done. If sep is not specified or is None, any whitespace string\r | |
305 | is a separator.\r | |
306 | """\r | |
307 | return s.rsplit(sep, maxsplit)\r | |
308 | \r | |
309 | # Join fields with optional separator\r | |
310 | def join(words, sep = ' '):\r | |
311 | """join(list [,sep]) -> string\r | |
312 | \r | |
313 | Return a string composed of the words in list, with\r | |
314 | intervening occurrences of sep. The default separator is a\r | |
315 | single space.\r | |
316 | \r | |
317 | (joinfields and join are synonymous)\r | |
318 | \r | |
319 | """\r | |
320 | return sep.join(words)\r | |
321 | joinfields = join\r | |
322 | \r | |
323 | # Find substring, raise exception if not found\r | |
324 | def index(s, *args):\r | |
325 | """index(s, sub [,start [,end]]) -> int\r | |
326 | \r | |
327 | Like find but raises ValueError when the substring is not found.\r | |
328 | \r | |
329 | """\r | |
330 | return s.index(*args)\r | |
331 | \r | |
332 | # Find last substring, raise exception if not found\r | |
333 | def rindex(s, *args):\r | |
334 | """rindex(s, sub [,start [,end]]) -> int\r | |
335 | \r | |
336 | Like rfind but raises ValueError when the substring is not found.\r | |
337 | \r | |
338 | """\r | |
339 | return s.rindex(*args)\r | |
340 | \r | |
341 | # Count non-overlapping occurrences of substring\r | |
342 | def count(s, *args):\r | |
343 | """count(s, sub[, start[,end]]) -> int\r | |
344 | \r | |
345 | Return the number of occurrences of substring sub in string\r | |
346 | s[start:end]. Optional arguments start and end are\r | |
347 | interpreted as in slice notation.\r | |
348 | \r | |
349 | """\r | |
350 | return s.count(*args)\r | |
351 | \r | |
352 | # Find substring, return -1 if not found\r | |
353 | def find(s, *args):\r | |
354 | """find(s, sub [,start [,end]]) -> in\r | |
355 | \r | |
356 | Return the lowest index in s where substring sub is found,\r | |
357 | such that sub is contained within s[start,end]. Optional\r | |
358 | arguments start and end are interpreted as in slice notation.\r | |
359 | \r | |
360 | Return -1 on failure.\r | |
361 | \r | |
362 | """\r | |
363 | return s.find(*args)\r | |
364 | \r | |
365 | # Find last substring, return -1 if not found\r | |
366 | def rfind(s, *args):\r | |
367 | """rfind(s, sub [,start [,end]]) -> int\r | |
368 | \r | |
369 | Return the highest index in s where substring sub is found,\r | |
370 | such that sub is contained within s[start,end]. Optional\r | |
371 | arguments start and end are interpreted as in slice notation.\r | |
372 | \r | |
373 | Return -1 on failure.\r | |
374 | \r | |
375 | """\r | |
376 | return s.rfind(*args)\r | |
377 | \r | |
378 | # for a bit of speed\r | |
379 | _float = float\r | |
380 | _int = int\r | |
381 | _long = long\r | |
382 | \r | |
383 | # Convert string to float\r | |
384 | def atof(s):\r | |
385 | """atof(s) -> float\r | |
386 | \r | |
387 | Return the floating point number represented by the string s.\r | |
388 | \r | |
389 | """\r | |
390 | return _float(s)\r | |
391 | \r | |
392 | \r | |
393 | # Convert string to integer\r | |
394 | def atoi(s , base=10):\r | |
395 | """atoi(s [,base]) -> int\r | |
396 | \r | |
397 | Return the integer represented by the string s in the given\r | |
398 | base, which defaults to 10. The string s must consist of one\r | |
399 | or more digits, possibly preceded by a sign. If base is 0, it\r | |
400 | is chosen from the leading characters of s, 0 for octal, 0x or\r | |
401 | 0X for hexadecimal. If base is 16, a preceding 0x or 0X is\r | |
402 | accepted.\r | |
403 | \r | |
404 | """\r | |
405 | return _int(s, base)\r | |
406 | \r | |
407 | \r | |
408 | # Convert string to long integer\r | |
409 | def atol(s, base=10):\r | |
410 | """atol(s [,base]) -> long\r | |
411 | \r | |
412 | Return the long integer represented by the string s in the\r | |
413 | given base, which defaults to 10. The string s must consist\r | |
414 | of one or more digits, possibly preceded by a sign. If base\r | |
415 | is 0, it is chosen from the leading characters of s, 0 for\r | |
416 | octal, 0x or 0X for hexadecimal. If base is 16, a preceding\r | |
417 | 0x or 0X is accepted. A trailing L or l is not accepted,\r | |
418 | unless base is 0.\r | |
419 | \r | |
420 | """\r | |
421 | return _long(s, base)\r | |
422 | \r | |
423 | \r | |
424 | # Left-justify a string\r | |
425 | def ljust(s, width, *args):\r | |
426 | """ljust(s, width[, fillchar]) -> string\r | |
427 | \r | |
428 | Return a left-justified version of s, in a field of the\r | |
429 | specified width, padded with spaces as needed. The string is\r | |
430 | never truncated. If specified the fillchar is used instead of spaces.\r | |
431 | \r | |
432 | """\r | |
433 | return s.ljust(width, *args)\r | |
434 | \r | |
435 | # Right-justify a string\r | |
436 | def rjust(s, width, *args):\r | |
437 | """rjust(s, width[, fillchar]) -> string\r | |
438 | \r | |
439 | Return a right-justified version of s, in a field of the\r | |
440 | specified width, padded with spaces as needed. The string is\r | |
441 | never truncated. If specified the fillchar is used instead of spaces.\r | |
442 | \r | |
443 | """\r | |
444 | return s.rjust(width, *args)\r | |
445 | \r | |
446 | # Center a string\r | |
447 | def center(s, width, *args):\r | |
448 | """center(s, width[, fillchar]) -> string\r | |
449 | \r | |
450 | Return a center version of s, in a field of the specified\r | |
451 | width. padded with spaces as needed. The string is never\r | |
452 | truncated. If specified the fillchar is used instead of spaces.\r | |
453 | \r | |
454 | """\r | |
455 | return s.center(width, *args)\r | |
456 | \r | |
457 | # Zero-fill a number, e.g., (12, 3) --> '012' and (-3, 3) --> '-03'\r | |
458 | # Decadent feature: the argument may be a string or a number\r | |
459 | # (Use of this is deprecated; it should be a string as with ljust c.s.)\r | |
460 | def zfill(x, width):\r | |
461 | """zfill(x, width) -> string\r | |
462 | \r | |
463 | Pad a numeric string x with zeros on the left, to fill a field\r | |
464 | of the specified width. The string x is never truncated.\r | |
465 | \r | |
466 | """\r | |
467 | if not isinstance(x, basestring):\r | |
468 | x = repr(x)\r | |
469 | return x.zfill(width)\r | |
470 | \r | |
471 | # Expand tabs in a string.\r | |
472 | # Doesn't take non-printing chars into account, but does understand \n.\r | |
473 | def expandtabs(s, tabsize=8):\r | |
474 | """expandtabs(s [,tabsize]) -> string\r | |
475 | \r | |
476 | Return a copy of the string s with all tab characters replaced\r | |
477 | by the appropriate number of spaces, depending on the current\r | |
478 | column, and the tabsize (default 8).\r | |
479 | \r | |
480 | """\r | |
481 | return s.expandtabs(tabsize)\r | |
482 | \r | |
483 | # Character translation through look-up table.\r | |
484 | def translate(s, table, deletions=""):\r | |
485 | """translate(s,table [,deletions]) -> string\r | |
486 | \r | |
487 | Return a copy of the string s, where all characters occurring\r | |
488 | in the optional argument deletions are removed, and the\r | |
489 | remaining characters have been mapped through the given\r | |
490 | translation table, which must be a string of length 256. The\r | |
491 | deletions argument is not allowed for Unicode strings.\r | |
492 | \r | |
493 | """\r | |
494 | if deletions or table is None:\r | |
495 | return s.translate(table, deletions)\r | |
496 | else:\r | |
497 | # Add s[:0] so that if s is Unicode and table is an 8-bit string,\r | |
498 | # table is converted to Unicode. This means that table *cannot*\r | |
499 | # be a dictionary -- for that feature, use u.translate() directly.\r | |
500 | return s.translate(table + s[:0])\r | |
501 | \r | |
502 | # Capitalize a string, e.g. "aBc dEf" -> "Abc def".\r | |
503 | def capitalize(s):\r | |
504 | """capitalize(s) -> string\r | |
505 | \r | |
506 | Return a copy of the string s with only its first character\r | |
507 | capitalized.\r | |
508 | \r | |
509 | """\r | |
510 | return s.capitalize()\r | |
511 | \r | |
512 | # Substring replacement (global)\r | |
513 | def replace(s, old, new, maxreplace=-1):\r | |
514 | """replace (str, old, new[, maxreplace]) -> string\r | |
515 | \r | |
516 | Return a copy of string str with all occurrences of substring\r | |
517 | old replaced by new. If the optional argument maxreplace is\r | |
518 | given, only the first maxreplace occurrences are replaced.\r | |
519 | \r | |
520 | """\r | |
521 | return s.replace(old, new, maxreplace)\r | |
522 | \r | |
523 | \r | |
524 | # Try importing optional built-in module "strop" -- if it exists,\r | |
525 | # it redefines some string operations that are 100-1000 times faster.\r | |
526 | # It also defines values for whitespace, lowercase and uppercase\r | |
527 | # that match <ctype.h>'s definitions.\r | |
528 | \r | |
529 | try:\r | |
530 | from strop import maketrans, lowercase, uppercase, whitespace\r | |
531 | letters = lowercase + uppercase\r | |
532 | except ImportError:\r | |
533 | pass # Use the original versions\r | |
534 | \r | |
535 | ########################################################################\r | |
536 | # the Formatter class\r | |
537 | # see PEP 3101 for details and purpose of this class\r | |
538 | \r | |
539 | # The hard parts are reused from the C implementation. They're exposed as "_"\r | |
540 | # prefixed methods of str and unicode.\r | |
541 | \r | |
542 | # The overall parser is implemented in str._formatter_parser.\r | |
543 | # The field name parser is implemented in str._formatter_field_name_split\r | |
544 | \r | |
545 | class Formatter(object):\r | |
546 | def format(*args, **kwargs):\r | |
547 | if not args:\r | |
548 | raise TypeError("descriptor 'format' of 'Formatter' object "\r | |
549 | "needs an argument")\r | |
550 | self, args = args[0], args[1:] # allow the "self" keyword be passed\r | |
551 | try:\r | |
552 | format_string, args = args[0], args[1:] # allow the "format_string" keyword be passed\r | |
553 | except IndexError:\r | |
554 | if 'format_string' in kwargs:\r | |
555 | format_string = kwargs.pop('format_string')\r | |
556 | else:\r | |
557 | raise TypeError("format() missing 1 required positional "\r | |
558 | "argument: 'format_string'")\r | |
559 | return self.vformat(format_string, args, kwargs)\r | |
560 | \r | |
561 | def vformat(self, format_string, args, kwargs):\r | |
562 | used_args = set()\r | |
563 | result = self._vformat(format_string, args, kwargs, used_args, 2)\r | |
564 | self.check_unused_args(used_args, args, kwargs)\r | |
565 | return result\r | |
566 | \r | |
567 | def _vformat(self, format_string, args, kwargs, used_args, recursion_depth):\r | |
568 | if recursion_depth < 0:\r | |
569 | raise ValueError('Max string recursion exceeded')\r | |
570 | result = []\r | |
571 | for literal_text, field_name, format_spec, conversion in \\r | |
572 | self.parse(format_string):\r | |
573 | \r | |
574 | # output the literal text\r | |
575 | if literal_text:\r | |
576 | result.append(literal_text)\r | |
577 | \r | |
578 | # if there's a field, output it\r | |
579 | if field_name is not None:\r | |
580 | # this is some markup, find the object and do\r | |
581 | # the formatting\r | |
582 | \r | |
583 | # given the field_name, find the object it references\r | |
584 | # and the argument it came from\r | |
585 | obj, arg_used = self.get_field(field_name, args, kwargs)\r | |
586 | used_args.add(arg_used)\r | |
587 | \r | |
588 | # do any conversion on the resulting object\r | |
589 | obj = self.convert_field(obj, conversion)\r | |
590 | \r | |
591 | # expand the format spec, if needed\r | |
592 | format_spec = self._vformat(format_spec, args, kwargs,\r | |
593 | used_args, recursion_depth-1)\r | |
594 | \r | |
595 | # format the object and append to the result\r | |
596 | result.append(self.format_field(obj, format_spec))\r | |
597 | \r | |
598 | return ''.join(result)\r | |
599 | \r | |
600 | \r | |
601 | def get_value(self, key, args, kwargs):\r | |
602 | if isinstance(key, (int, long)):\r | |
603 | return args[key]\r | |
604 | else:\r | |
605 | return kwargs[key]\r | |
606 | \r | |
607 | \r | |
608 | def check_unused_args(self, used_args, args, kwargs):\r | |
609 | pass\r | |
610 | \r | |
611 | \r | |
612 | def format_field(self, value, format_spec):\r | |
613 | return format(value, format_spec)\r | |
614 | \r | |
615 | \r | |
616 | def convert_field(self, value, conversion):\r | |
617 | # do any conversion on the resulting object\r | |
618 | if conversion is None:\r | |
619 | return value\r | |
620 | elif conversion == 's':\r | |
621 | return str(value)\r | |
622 | elif conversion == 'r':\r | |
623 | return repr(value)\r | |
624 | raise ValueError("Unknown conversion specifier {0!s}".format(conversion))\r | |
625 | \r | |
626 | \r | |
627 | # returns an iterable that contains tuples of the form:\r | |
628 | # (literal_text, field_name, format_spec, conversion)\r | |
629 | # literal_text can be zero length\r | |
630 | # field_name can be None, in which case there's no\r | |
631 | # object to format and output\r | |
632 | # if field_name is not None, it is looked up, formatted\r | |
633 | # with format_spec and conversion and then used\r | |
634 | def parse(self, format_string):\r | |
635 | return format_string._formatter_parser()\r | |
636 | \r | |
637 | \r | |
638 | # given a field_name, find the object it references.\r | |
639 | # field_name: the field being looked up, e.g. "0.name"\r | |
640 | # or "lookup[3]"\r | |
641 | # used_args: a set of which args have been used\r | |
642 | # args, kwargs: as passed in to vformat\r | |
643 | def get_field(self, field_name, args, kwargs):\r | |
644 | first, rest = field_name._formatter_field_name_split()\r | |
645 | \r | |
646 | obj = self.get_value(first, args, kwargs)\r | |
647 | \r | |
648 | # loop through the rest of the field_name, doing\r | |
649 | # getattr or getitem as needed\r | |
650 | for is_attr, i in rest:\r | |
651 | if is_attr:\r | |
652 | obj = getattr(obj, i)\r | |
653 | else:\r | |
654 | obj = obj[i]\r | |
655 | \r | |
656 | return obj, first\r |