Skip to content

Commit

Permalink
- UNDEFINED is a reserved word too, fix docs, add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
zzzeek committed Mar 30, 2012
1 parent 951d150 commit d1e8233
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 8 deletions.
2 changes: 1 addition & 1 deletion CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 8 additions & 5 deletions doc/build/runtime.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
------------------

Expand Down Expand Up @@ -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`.
Expand Down Expand Up @@ -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`.

Expand Down
2 changes: 1 addition & 1 deletion mako/codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# 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,
Expand Down
33 changes: 32 additions & 1 deletion test/test_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,38 @@ def test_list_comprehensions_plus_undeclared_strict(self):
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):
Expand Down

0 comments on commit d1e8233

Please sign in to comment.