summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2012-03-30 19:51:24 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2012-03-30 19:51:24 -0400
commitd1e8233c2efa9a231c3a5fe91469189e289e2f5c (patch)
treeec7b408ecac3068a406e4e38b3fe89ca9912d76c
parent951d15087515582e0d08bbaecdd55469cb3fc17b (diff)
downloadmako-rel_0_7_0.tar.gz
- UNDEFINED is a reserved word too, fix docs, add testsrel_0_7_0
-rw-r--r--CHANGES2
-rw-r--r--doc/build/runtime.rst13
-rw-r--r--mako/codegen.py2
-rw-r--r--test/test_template.py33
4 files changed, 42 insertions, 8 deletions
diff --git a/CHANGES b/CHANGES
index 5fbc432..706c9cb 100644
--- a/CHANGES
+++ b/CHANGES
@@ -12,7 +12,7 @@
names, that is names which are never pulled
from the context and cannot be passed to
the template.render() method. Current names
- are "context", "loop".
+ are "context", "loop", "UNDEFINED".
- [feature] The html_error_template() will now
apply Pygments highlighting to the source
diff --git a/doc/build/runtime.rst b/doc/build/runtime.rst
index 3439955..e5e1e53 100644
--- a/doc/build/runtime.rst
+++ b/doc/build/runtime.rst
@@ -52,6 +52,8 @@ buffer stack. For this reason, just stick with
``context.write()`` and content will always go to the topmost
buffer.
+.. _context_vars:
+
Context Variables
------------------
@@ -363,10 +365,10 @@ All the built-in names
A one-stop shop for all the names Mako defines. Most of these
names are instances of :class:`.Namespace`, which are described
in the next section, :ref:`namespaces_toplevel`. Also, most of
-these names other than :class:`.Context` and ``UNDEFINED`` are
-also present *within* the :class:`.Context` itself. There are only
-two names, ``context`` and ``loop``, that are themselves not defined
-in the context and can't be replaced - see the section :ref:`reserved_names`.
+these names other than ``context``, ``UNDEFINED``, and ``loop`` are
+also present *within* the :class:`.Context` itself. The names
+``context``, ``loop`` and ``UNDEFINED`` themselves can't be passed
+to the context and can't be substituted - see the section :ref:`reserved_names`.
* ``context`` - this is the :class:`.Context` object, introduced
at :ref:`context`.
@@ -409,12 +411,13 @@ in the context and can't be replaced - see the section :ref:`reserved_names`.
Reserved names
--------------
-Mako has two words that are considered to be "reserved" and can't be used
+Mako has a few names that are considered to be "reserved" and can't be used
as variable names. As of 0.7, Mako raises an error if these words are found
passed to the template as context arguments, whereas in previous versions they'd be silently
ignored or lead to other error messages.
* ``context`` - see :ref:`context`
+* ``UNDEFINED`` - see :ref:`context_vars`
* ``loop`` - see :ref:`loop_context`. Note this can be disabled for legacy templates
via the ``enable_loop=False`` argument; see :ref:`migrating_loop`.
diff --git a/mako/codegen.py b/mako/codegen.py
index 8600202..904dc78 100644
--- a/mako/codegen.py
+++ b/mako/codegen.py
@@ -17,7 +17,7 @@ MAGIC_NUMBER = 8
# names which are hardwired into the
# template and are not accessed via the
# context itself
-RESERVED_NAMES = set(['context', 'loop'])
+RESERVED_NAMES = set(['context', 'loop', 'UNDEFINED'])
def compile(node,
uri,
diff --git a/test/test_template.py b/test/test_template.py
index 9841ac8..ae14d40 100644
--- a/test/test_template.py
+++ b/test/test_template.py
@@ -747,7 +747,38 @@ class UndefinedVarsTest(TemplateTest):
result_lines(t.render(t="T")),
['t is: T', 'a,b,c']
)
-
+
+class ReservedNameTest(TemplateTest):
+ def test_names_on_context(self):
+ for name in ('context', 'loop', 'UNDEFINED'):
+ assert_raises_message(
+ exceptions.NameConflictError,
+ r"Reserved words passed to render\(\): %s" % name,
+ Template("x").render, **{name:'foo'}
+ )
+
+ def test_names_in_template(self):
+ for name in ('context', 'loop', 'UNDEFINED'):
+ assert_raises_message(
+ exceptions.NameConflictError,
+ r"Reserved words declared in template: %s" % name,
+ Template, "<%% %s = 5 %%>" % name
+ )
+
+ def test_exclude_loop_context(self):
+ self._do_memory_test(
+ "loop is ${loop}",
+ "loop is 5",
+ template_args=dict(loop=5),
+ enable_loop=False
+ )
+
+ def test_exclude_loop_template(self):
+ self._do_memory_test(
+ "<% loop = 12 %>loop is ${loop}",
+ "loop is 12",
+ enable_loop=False
+ )
class ControlTest(TemplateTest):
def test_control(self):