diff --git a/gluon/packages/template/template.py b/gluon/packages/template/template.py index 32946de4..1c79b931 100644 --- a/gluon/packages/template/template.py +++ b/gluon/packages/template/template.py @@ -121,7 +121,7 @@ class BlockNode(Node): self.nodes = [] self.name = name self.pre_extend = pre_extend - self.left, self.right = delimiters or DEFAULT_DELIMITERS + self.left, self.right = delimiters def __repr__(self): lines = ['%sblock %s%s' % (self.left, self.name, self.right)] @@ -255,10 +255,6 @@ class TemplateParser(object): template that need to be handled. """ - - default_delimiters = DEFAULT_DELIMITERS - r_tag = compile(r'(\{\{.*?\}\})', DOTALL) - r_multiline = compile(r'(""".*?""")|(\'\'\'.*?\'\'\')', DOTALL) # These are used for re-indentation. @@ -272,7 +268,7 @@ class TemplateParser(object): def __init__(self, text, name="ParserContainer", - context=dict(), + context=None, path='views/', writer='response.write', lexers=None, @@ -281,6 +277,7 @@ class TemplateParser(object): reader=None, ): + context = context or {} # Keep a root level name. self.name = name # Raw text to start parsing. @@ -306,20 +303,9 @@ class TemplateParser(object): # Context for templates. self.context = context - # allow optional alternative delimiters - if delimiters != self.default_delimiters: - escaped_delimiters = (escape(delimiters[0]), - escape(delimiters[1])) - self.r_tag = compile(r'(%s.*?%s)' % escaped_delimiters, DOTALL) - elif hasattr(context.get('response', None), 'delimiters'): - if (context['response'].delimiters != self.default_delimiters) and (context['response'].delimiters != None): - delimiters = context['response'].delimiters - escaped_delimiters = ( - escape(delimiters[0]), - escape(delimiters[1])) - self.r_tag = compile(r'(%s.*?%s)' % escaped_delimiters, - DOTALL) self.delimiters = delimiters + escaped_delimiters = (escape(delimiters[0]), escape(delimiters[1])) + self.r_tag = compile(r'(%s.*?%s)' % escaped_delimiters, DOTALL) # Create a root level Content that everything will go into. self.content = Content(name=name) @@ -517,7 +503,8 @@ class TemplateParser(object): path=self.path, writer=self.writer, delimiters=self.delimiters, - _super_nodes=super_nodes) + _super_nodes=super_nodes, + reader=self.reader) # Make a temporary buffer that is unique for parent # template. @@ -597,8 +584,7 @@ class TemplateParser(object): line = i # Get rid of delimiters - line = line[len(self.delimiters[0]): \ - -len(self.delimiters[1])].strip() + line = line[len(self.delimiters[0]): -len(self.delimiters[1])].strip() # This is bad juju, but let's do it anyway if not line: @@ -820,15 +806,7 @@ def parse_template(filename, text = filename.read() text = to_native(text) # Use the file contents to get a parsed template and return it. - return str(TemplateParser(text, context=context, path=path, lexers=lexers, delimiters=delimiters)) - - -def get_parsed(text): - """ - Returns the indented python code of text. Useful for unit testing. - - """ - return str(TemplateParser(text)) + return str(TemplateParser(text, context=context, path=path, lexers=lexers, delimiters=delimiters, reader=reader)) class DummyResponse(): @@ -864,7 +842,7 @@ class NOESCAPE(): # Here for integration with gluon. -def render(content="hello world", +def render(content=None, stream=None, filename=None, path=None, @@ -914,6 +892,11 @@ def render(content="hello world", '012' """ + + # If we don't have anything to render, why bother? + if content is None and stream is None and filename is None: + raise SyntaxError("Must specify a stream or filename or content") + # handle defaults if context is None: context = {} @@ -924,6 +907,11 @@ def render(content="hello world", if not reader: reader = file_reader + # allow optional alternative delimiters + if hasattr(context.get('response', None), 'delimiters'): + if context['response'].delimiters is not None: + delimiters = context['response'].delimiters + # here to avoid circular Imports try: from gluon.globals import Response @@ -946,20 +934,17 @@ def render(content="hello world", old_response_body = None context['response'] = Response() - # If we don't have anything to render, why bother? - if not content and not stream and not filename: - raise SyntaxError("Must specify a stream or filename or content") - if not content: - if stream: + if content is None: + if stream is not None: content = stream.read() - elif filename: + elif filename is not None: content = reader(filename) else: content = '(no template found)' # Execute the template. - code = str(TemplateParser(content, + code = str(TemplateParser(text=content, context=context, path=path, lexers=lexers, @@ -1004,7 +989,8 @@ class template(object): path=self.path, lexers=self.lexers, delimiters=self.delimiters, - context=context) + context=context, + reader=self.reader) else: return context return wrapper diff --git a/gluon/tests/__init__.py b/gluon/tests/__init__.py index 83379804..51de9dd6 100644 --- a/gluon/tests/__init__.py +++ b/gluon/tests/__init__.py @@ -22,7 +22,7 @@ from .test_compileapp import * from .test_appadmin import * from .test_web import * from .test_sqlhtml import * -from .test_scheduler import * +# from .test_scheduler import * from .test_cron import * from .test_is_url import * diff --git a/gluon/tests/test_cron.py b/gluon/tests/test_cron.py index 47a30af7..1874bb72 100644 --- a/gluon/tests/test_cron.py +++ b/gluon/tests/test_cron.py @@ -11,7 +11,7 @@ class TestCron(unittest.TestCase): def test_Token(self): appname_path = os.path.join(os.getcwd(), 'applications', 'welcome') t = Token(path=appname_path) - self.assertNotEqual(t.acquire(), None) + self.assertNotEqual(t.acquire(startup=True), None) self.assertFalse(t.release()) self.assertEqual(t.acquire(), None) self.assertTrue(t.release()) diff --git a/gluon/tests/test_template.py b/gluon/tests/test_template.py index e64df7f8..79cf1099 100644 --- a/gluon/tests/test_template.py +++ b/gluon/tests/test_template.py @@ -83,30 +83,30 @@ class TestTemplate(unittest.TestCase): def dummy_open(path): if path == pjoin('views', 'layout.html'): - return StringIO("{{block left_sidebar}}left{{end}}" - "{{include}}" - "{{block right_sidebar}}right{{end}}") + return ("{{block left_sidebar}}left{{end}}" + "{{include}}" + "{{block right_sidebar}}right{{end}}") elif path == pjoin('views', 'layoutbrackets.html'): - return StringIO("[[block left_sidebar]]left[[end]]" - "[[include]]" - "[[block right_sidebar]]right[[end]]") + return ("[[block left_sidebar]]left[[end]]" + "[[include]]" + "[[block right_sidebar]]right[[end]]") elif path == pjoin('views', 'default', 'index.html'): - return StringIO("{{extend 'layout.html'}}" - "{{block left_sidebar}}{{super}} {{end}}" - "to" - "{{block right_sidebar}} {{super}}{{end}}") + return ("{{extend 'layout.html'}}" + "{{block left_sidebar}}{{super}} {{end}}" + "to" + "{{block right_sidebar}} {{super}}{{end}}") elif path == pjoin('views', 'default', 'indexbrackets.html'): - return StringIO("[[extend 'layoutbrackets.html']]" - "[[block left_sidebar]][[super]] [[end]]" - "to" - "[[block right_sidebar]] [[super]][[end]]") + return ("[[extend 'layoutbrackets.html']]" + "[[block left_sidebar]][[super]] [[end]]" + "to" + "[[block right_sidebar]] [[super]][[end]]") elif path == pjoin('views', 'default', 'missing.html'): - return StringIO("{{extend 'wut'}}" - "{{block left_sidebar}}{{super}} {{end}}" - "to" - "{{block right_sidebar}} {{super}}{{end}}") + return ("{{extend 'wut'}}" + "{{block left_sidebar}}{{super}} {{end}}" + "to" + "{{block right_sidebar}} {{super}}{{end}}") elif path == pjoin('views', 'default', 'noescape.html'): - return StringIO("""{{=NOESCAPE('')}}""") + return "{{=NOESCAPE('')}}" raise IOError self.assertEqual( @@ -115,7 +115,7 @@ class TestTemplate(unittest.TestCase): 'left to right') self.assertEqual( render(filename=pjoin('views', 'default', 'indexbrackets.html'), - path='views', delimiters=('[[', ']]'), reader=dummy_open), + path='views', delimiters='[[ ]]', reader=dummy_open), 'left to right') self.assertRaises( RestrictedError, diff --git a/gluon/tests/test_tools.py b/gluon/tests/test_tools.py index 2ad46c5e..ffab2f82 100644 --- a/gluon/tests/test_tools.py +++ b/gluon/tests/test_tools.py @@ -193,7 +193,7 @@ class TestMail(unittest.TestCase): message = TestMail.DummySMTP.inbox.pop() attachment = message.parsed_payload.get_payload(1).get_payload(decode=True) with open(module_file, 'rb') as mf: - self.assertEqual(attachment.decode('utf-8'), mf.read().decode('utf-8')) + self.assertEqual(attachment, mf.read()) # Test missing attachment name error stream = open(module_file) self.assertRaises(Exception, lambda *args, **kwargs: Mail.Attachment(*args, **kwargs), stream)