Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: appengine/monorail/third_party/ezt.py

Issue 1868553004: Open Source Monorail (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Rebase Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 """ezt.py -- EaZy Templating 2 """ezt.py -- EaZy Templating
3 3
4 For documentation, please see: http://code.google.com/p/ezt/wiki/Syntax 4 For documentation, please see: http://code.google.com/p/ezt/wiki/Syntax
5 """ 5 """
6 # 6 #
7 # Copyright (C) 2001-2011 Greg Stein. All Rights Reserved. 7 # Copyright (C) 2001-2011 Greg Stein. All Rights Reserved.
8 # 8 #
9 # Redistribution and use in source and binary forms, with or without 9 # Redistribution and use in source and binary forms, with or without
10 # modification, are permitted provided that the following conditions are 10 # modification, are permitted provided that the following conditions are
(...skipping 21 matching lines...) Expand all
32 # 32 #
33 # This software is maintained by Greg and is available at: 33 # This software is maintained by Greg and is available at:
34 # http://code.google.com/p/ezt/ 34 # http://code.google.com/p/ezt/
35 # 35 #
36 36
37 __author__ = 'Greg Stein' 37 __author__ = 'Greg Stein'
38 __version__ = '1.0' 38 __version__ = '1.0'
39 __license__ = 'BSD' 39 __license__ = 'BSD'
40 40
41 import re 41 import re
42 from types import StringType, IntType, FloatType, LongType 42 from types import IntType, FloatType, LongType
43 import os 43 import os
44 import urllib 44 import urllib
45 try: 45 import StringIO
46 import cStringIO
47 except ImportError:
48 import StringIO
49 cStringIO = StringIO
50 46
51 # 47 #
52 # Formatting types 48 # Formatting types
53 # 49 #
54 FORMAT_RAW = 'raw' 50 FORMAT_RAW = 'raw'
55 FORMAT_HTML = 'html' 51 FORMAT_HTML = 'html'
56 FORMAT_XML = 'xml' 52 FORMAT_XML = 'xml'
57 FORMAT_JS = 'js' 53 FORMAT_JS = 'js'
58 FORMAT_URL = 'url' 54 FORMAT_URL = 'url'
59 55
60 # 56 #
61 # This regular expression matches three alternatives: 57 # This regular expression matches four alternatives:
62 # expr: NEWLINE | DIRECTIVE | BRACKET | COMMENT 58 # expr: NEWLINE | DIRECTIVE | BRACKET | COMMENT
63 # DIRECTIVE: '[' ITEM (whitespace ITEM)* '] 59 # DIRECTIVE: '[' ITEM (whitespace ARG)* ']
64 # ITEM: STRING | NAME 60 # ITEM: STRING | NAME
61 # ARG: STRING | NAME | NUMBER
65 # STRING: '"' (not-slash-or-dquote | '\' anychar)* '"' 62 # STRING: '"' (not-slash-or-dquote | '\' anychar)* '"'
66 # NAME: (alphanum | '_' | '-' | '.')+ 63 # NAME: (alpha | '_') (alphanum | '_' | '-' | '.')*
64 # NUMBER: digit+
67 # BRACKET: '[[]' 65 # BRACKET: '[[]'
68 # COMMENT: '[#' not-rbracket* ']' 66 # COMMENT: '[#' not-rbracket* ']'
69 # 67 #
68 # Note: the above BNR is a bit loose around ITEM/ARG/NAME/NUMBER. The
69 # important point is that the first value in a directive must
70 # start with '_' or an alpha character (no digits). This greatly
71 # helps to avoid simple errors like '[0]' in templates.
72 #
70 # When used with the split() method, the return value will be composed of 73 # When used with the split() method, the return value will be composed of
71 # non-matching text and the three paren groups (NEWLINE, DIRECTIVE and 74 # non-matching text and the three paren groups (NEWLINE, DIRECTIVE and
72 # BRACKET). Since the COMMENT matches are not placed into a group, they are 75 # BRACKET). Since the COMMENT matches are not placed into a group, they are
73 # considered a "splitting" value and simply dropped. 76 # considered a "splitting" value and simply dropped.
74 # 77 #
75 _item = r'(?:"(?:[^\\"]|\\.)*"|[-\w.]+)' 78 _item = r'(?:"(?:[^\\"]|\\.)*"|[A-Za-z_][-\w.]*)'
79 _arg = r'(?:"(?:[^\\"]|\\.)*"|[-\w.]+)'
76 _re_parse = re.compile(r'(\r?\n)|\[(%s(?: +%s)*)\]|(\[\[\])|\[#[^\]]*\]' % 80 _re_parse = re.compile(r'(\r?\n)|\[(%s(?: +%s)*)\]|(\[\[\])|\[#[^\]]*\]' %
77 (_item, _item)) 81 (_item, _arg))
78 82
79 _re_args = re.compile(r'"(?:[^\\"]|\\.)*"|[-\w.]+') 83 _re_args = re.compile(r'"(?:[^\\"]|\\.)*"|[-\w.]+')
80 84
81 # block commands and their argument counts 85 # block commands and their argument counts
82 _block_cmd_specs = { 'if-index':2, 'for':1, 'is':2, 'define':1, 'format':1 } 86 _block_cmd_specs = { 'if-index':2, 'for':1, 'is':2, 'define':1, 'format':1 }
83 _block_cmds = _block_cmd_specs.keys() 87 _block_cmds = _block_cmd_specs.keys()
84 88
85 # two regular expressions for compressing whitespace. the first is used to 89 # two regular expressions for compressing whitespace. the first is used to
86 # compress any whitespace including a newline into a single newline. the 90 # compress any whitespace including a newline into a single newline. the
87 # second regex is used to compress runs of whitespace into a single space. 91 # second regex is used to compress runs of whitespace into a single space.
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 raise UnclosedBlocksError('Block opened at line %s' % stack[-1][4], 287 raise UnclosedBlocksError('Block opened at line %s' % stack[-1][4],
284 filename=filename) 288 filename=filename)
285 return program 289 return program
286 290
287 def _execute(self, program, fp, ctx): 291 def _execute(self, program, fp, ctx):
288 """This private helper function takes a 'program' sequence as created 292 """This private helper function takes a 'program' sequence as created
289 by the method '_parse' and executes it step by step. strings are written 293 by the method '_parse' and executes it step by step. strings are written
290 to the file object 'fp' and functions are called. 294 to the file object 'fp' and functions are called.
291 """ 295 """
292 for step in program: 296 for step in program:
293 if isinstance(step, StringType): 297 if isinstance(step, basestring):
294 fp.write(step) 298 fp.write(step)
295 else: 299 else:
296 method, method_args, filename, line_number = step 300 method, method_args, filename, line_number = step
297 method(method_args, fp, ctx, filename, line_number) 301 method(method_args, fp, ctx, filename, line_number)
298 302
299 def _cmd_print(self, (transforms, valref), fp, ctx, filename, line_number): 303 def _cmd_print(self, (transforms, valref), fp, ctx, filename, line_number):
300 value = _get_value(valref, ctx, filename, line_number) 304 value = _get_value(valref, ctx, filename, line_number)
301 # if the value has a 'read' attribute, then it is a stream: copy it 305 # if the value has a 'read' attribute, then it is a stream: copy it
302 if hasattr(value, 'read'): 306 if hasattr(value, 'read'):
303 while 1: 307 while 1:
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 section = t_section 385 section = t_section
382 else: 386 else:
383 section = f_section 387 section = f_section
384 if section is not None: 388 if section is not None:
385 self._execute(section, fp, ctx) 389 self._execute(section, fp, ctx)
386 390
387 def _cmd_for(self, args, fp, ctx, filename, line_number): 391 def _cmd_for(self, args, fp, ctx, filename, line_number):
388 ((valref,), unused, section) = args 392 ((valref,), unused, section) = args
389 list = _get_value(valref, ctx, filename, line_number) 393 list = _get_value(valref, ctx, filename, line_number)
390 refname = valref[0] 394 refname = valref[0]
391 if isinstance(list, StringType): 395 if isinstance(list, basestring):
392 raise NeedSequenceError(refname, filename, line_number) 396 raise NeedSequenceError(refname, filename, line_number)
393 ctx.for_index[refname] = idx = [ list, 0 ] 397 ctx.for_index[refname] = idx = [ list, 0 ]
394 for item in list: 398 for item in list:
395 self._execute(section, fp, ctx) 399 self._execute(section, fp, ctx)
396 idx[1] = idx[1] + 1 400 idx[1] = idx[1] + 1
397 del ctx.for_index[refname] 401 del ctx.for_index[refname]
398 402
399 def _cmd_define(self, args, fp, ctx, filename, line_number): 403 def _cmd_define(self, args, fp, ctx, filename, line_number):
400 ((name,), unused, section) = args 404 ((name,), unused, section) = args
401 valfp = cStringIO.StringIO() 405 valfp = StringIO.StringIO()
402 if section is not None: 406 if section is not None:
403 self._execute(section, valfp, ctx) 407 self._execute(section, valfp, ctx)
404 ctx.defines[name] = valfp.getvalue() 408 ctx.defines[name] = valfp.getvalue()
405 409
406 def boolean(value): 410 def boolean(value):
407 "Return a value suitable for [if-any bool_var] usage in a template." 411 "Return a value suitable for [if-any bool_var] usage in a template."
408 if value: 412 if value:
409 return 'yes' 413 return 'yes'
410 return None 414 return None
411 415
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 elif ctx.defines.has_key(start): 481 elif ctx.defines.has_key(start):
478 ob = ctx.defines[start] 482 ob = ctx.defines[start]
479 elif hasattr(ctx.data, start): 483 elif hasattr(ctx.data, start):
480 ob = getattr(ctx.data, start) 484 ob = getattr(ctx.data, start)
481 else: 485 else:
482 raise UnknownReference(refname, filename, line_number) 486 raise UnknownReference(refname, filename, line_number)
483 487
484 # walk the rest of the dotted reference 488 # walk the rest of the dotted reference
485 for attr in rest: 489 for attr in rest:
486 try: 490 try:
487 ob = getattr(ob, attr) 491 if isinstance(ob, dict):
488 except AttributeError: 492 ob = ob[attr]
493 else:
494 ob = getattr(ob, attr)
495 except AttributeError, KeyError:
489 raise UnknownReference(refname, filename, line_number) 496 raise UnknownReference(refname, filename, line_number)
490 497
491 # make sure we return a string instead of some various Python types 498 # make sure we return a string instead of some various Python types
492 if isinstance(ob, (IntType, FloatType, LongType)): 499 if isinstance(ob, (IntType, FloatType, LongType)):
493 return str(ob) 500 return str(ob)
494 if ob is None: 501 if ob is None:
495 return '' 502 return ''
496 503
497 # string or a sequence 504 # string or a sequence
498 return ob 505 return ob
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 651
645 def _test(argv): 652 def _test(argv):
646 import doctest, ezt 653 import doctest, ezt
647 verbose = "-v" in argv 654 verbose = "-v" in argv
648 return doctest.testmod(ezt, verbose=verbose) 655 return doctest.testmod(ezt, verbose=verbose)
649 656
650 if __name__ == "__main__": 657 if __name__ == "__main__":
651 # invoke unit test for this module: 658 # invoke unit test for this module:
652 import sys 659 import sys
653 sys.exit(_test(sys.argv)[0]) 660 sys.exit(_test(sys.argv)[0])
OLDNEW
« no previous file with comments | « appengine/monorail/third_party/ezt.README ('k') | appengine/monorail/third_party/googleapiclient » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698