From 4a634925401d6cea2e942fc1d5a61ea9a8903821 Mon Sep 17 00:00:00 2001
From: Mike Bayer <mike_mp@zzzcomputing.com>
Date: Mon, 2 Jun 2008 20:42:52 +0000
Subject: [PATCH] - dict/locals placed in mako-private namespace, [ticket:84]

---
 CHANGES             |  5 ++++-
 lib/mako/codegen.py |  6 ++++--
 test/template.py    | 17 ++++++++++++++---
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/CHANGES b/CHANGES
index 7036ee9..23a9600 100644
--- a/CHANGES
+++ b/CHANGES
@@ -50,7 +50,10 @@
 - Bugfixes:
   - can now use most names from __builtins__ as variable
     names without explicit declaration (i.e. 'id', 
-    'exception', 'range', etc.) [ticket:83]
+    'exception', 'range', etc.) [ticket:83] [ticket:84]
+    
+  - can also use builtin names as local variable names 
+    (i.e. dict, locals) (came from fix for [ticket:84])
     
   - fixed bug in python generation when variable names are
     used with identifiers like "else", "finally", etc.
diff --git a/lib/mako/codegen.py b/lib/mako/codegen.py
index 3600b3d..46dc502 100644
--- a/lib/mako/codegen.py
+++ b/lib/mako/codegen.py
@@ -118,6 +118,8 @@ class _GenerateRenderMethod(object):
             
         self.printer.writeline("from mako import runtime, filters, cache")
         self.printer.writeline("UNDEFINED = runtime.UNDEFINED")
+        self.printer.writeline("__M_dict_builtin = dict")
+        self.printer.writeline("__M_locals_builtin = locals")
         self.printer.writeline("_magic_number = %s" % repr(MAGIC_NUMBER))
         self.printer.writeline("_modified_time = %s" % repr(time.time()))
         self.printer.writeline("_template_filename=%s" % repr(self.compiler.filename))
@@ -171,7 +173,7 @@ class _GenerateRenderMethod(object):
             self.identifier_stack[-1].argument_declared.add('pageargs')
 
         if not self.in_def and (len(self.identifiers.locally_assigned) > 0 or len(self.identifiers.argument_declared)>0):
-            self.printer.writeline("__M_locals = dict(%s)" % ','.join(["%s=%s" % (x, x) for x in self.identifiers.argument_declared]))
+            self.printer.writeline("__M_locals = __M_dict_builtin(%s)" % ','.join(["%s=%s" % (x, x) for x in self.identifiers.argument_declared]))
 
         self.write_variable_declares(self.identifiers, toplevel=True)
 
@@ -497,7 +499,7 @@ class _GenerateRenderMethod(object):
             if not self.in_def and len(self.identifiers.locally_assigned) > 0:
                 # if we are the "template" def, fudge locally declared/modified variables into the "__M_locals" dictionary,
                 # which is used for def calls within the same template, to simulate "enclosing scope"
-                self.printer.writeline('__M_locals.update(dict([(__M_key, locals()[__M_key]) for __M_key in [%s] if __M_key in locals()]))' % ','.join([repr(x) for x in node.declared_identifiers()]))
+                self.printer.writeline('__M_locals.update(__M_dict_builtin([(__M_key, __M_locals_builtin()[__M_key]) for __M_key in [%s] if __M_key in __M_locals_builtin()]))' % ','.join([repr(x) for x in node.declared_identifiers()]))
                 
     def visitIncludeTag(self, node):
         self.write_source_comment(node)
diff --git a/test/template.py b/test/template.py
index 634a9a3..0c491f1 100644
--- a/test/template.py
+++ b/test/template.py
@@ -218,11 +218,22 @@ class PageArgsTest(unittest.TestCase):
     
     def test_canuse_builtin_names(self):
         template = Template("""
-            exception: ${exception}
+            exception: ${Exception}
             id: ${id}
         """)
-        assert flatten_result(template.render(id='some id', exception='some exception')) == "exception: some exception id: some id"
-        
+        assert flatten_result(template.render(id='some id', Exception='some exception')) == "exception: some exception id: some id"
+    
+    def test_dict_locals(self):
+        template = Template("""
+            <%
+                dict = "this is dict"
+                locals = "this is locals"
+            %>
+            dict: ${dict}
+            locals: ${locals}
+        """)
+        assert flatten_result(template.render()) == "dict: this is dict locals: this is locals"
+
 class IncludeTest(unittest.TestCase):
     def test_basic(self):
         lookup = TemplateLookup()
-- 
GitLab