Skip to content

Commit 4e2de73

Browse files
committed
Revert "Support passing custom filters with the same name as built-in flags"
Reverted the fix for 🎫`140` released in Mako 1.3.7 as it produced regressions in existing user code. This reverts commit f37777c. Fixes: #415 Change-Id: I0fe9735828fd56bccae3d48bcc5a12b6de4aac40
1 parent fbfb812 commit 4e2de73

File tree

9 files changed

+48
-117
lines changed

9 files changed

+48
-117
lines changed

doc/build/changelog.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Changelog
1111
:include_notes_from: unreleased
1212

1313
.. changelog::
14-
:version: 1.3.7
14+
:version: 1.3.7 (yanked)
1515
:released: Tue Dec 3 2024
1616

1717
.. change::

doc/build/unreleased/415.rst

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.. change::
2+
:tags: bug, lexer
3+
:tickets: 415, 140
4+
5+
Reverted the fix for :ticket:`140` released in Mako 1.3.7 as it produced
6+
regressions in existing user code.
7+

mako/codegen.py

+9-35
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
from mako import filters
1717
from mako import parsetree
1818
from mako import util
19-
from mako.filters import DEFAULT_ESCAPE_PREFIX
2019
from mako.pygen import PythonPrinter
2120

2221

@@ -27,7 +26,6 @@
2726
# context itself
2827
TOPLEVEL_DECLARED = {"UNDEFINED", "STOP_RENDERING"}
2928
RESERVED_NAMES = {"context", "loop"}.union(TOPLEVEL_DECLARED)
30-
DEFAULT_ESCAPED_N = "%sn" % DEFAULT_ESCAPE_PREFIX
3129

3230

3331
def compile( # noqa
@@ -524,7 +522,6 @@ def write_variable_declares(self, identifiers, toplevel=False, limit=None):
524522
self.printer.writeline("loop = __M_loop = runtime.LoopStack()")
525523

526524
for ident in to_write:
527-
ident = ident.replace(DEFAULT_ESCAPE_PREFIX, "")
528525
if ident in comp_idents:
529526
comp = comp_idents[ident]
530527
if comp.is_block:
@@ -788,48 +785,25 @@ def locate_encode(name):
788785
else:
789786
return filters.DEFAULT_ESCAPES.get(name, name)
790787

791-
filter_args = set()
792-
if DEFAULT_ESCAPED_N not in args:
788+
if "n" not in args:
793789
if is_expression:
794790
if self.compiler.pagetag:
795791
args = self.compiler.pagetag.filter_args.args + args
796-
filter_args = set(self.compiler.pagetag.filter_args.args)
797-
if (
798-
self.compiler.default_filters
799-
and DEFAULT_ESCAPED_N not in args
800-
):
792+
if self.compiler.default_filters and "n" not in args:
801793
args = self.compiler.default_filters + args
802794
for e in args:
803-
if e == DEFAULT_ESCAPED_N:
804-
continue
805-
806-
if e.startswith(DEFAULT_ESCAPE_PREFIX):
807-
render_e = e.replace(DEFAULT_ESCAPE_PREFIX, "")
808-
is_default_filter = True
809-
else:
810-
render_e = e
811-
is_default_filter = False
812-
813795
# if filter given as a function, get just the identifier portion
796+
if e == "n":
797+
continue
814798
m = re.match(r"(.+?)(\(.*\))", e)
815799
if m:
816-
if not is_default_filter:
817-
ident, fargs = m.group(1, 2)
818-
f = locate_encode(ident)
819-
render_e = f + fargs
820-
target = "%s(%s)" % (render_e, target)
821-
elif is_default_filter and e not in filter_args:
822-
target = "%s(%s) if %s is not UNDEFINED else %s(%s)" % (
823-
render_e,
824-
target,
825-
render_e,
826-
locate_encode(render_e),
827-
target,
828-
)
800+
ident, fargs = m.group(1, 2)
801+
f = locate_encode(ident)
802+
e = f + fargs
829803
else:
830-
e = locate_encode(render_e)
804+
e = locate_encode(e)
831805
assert e is not None
832-
target = "%s(%s)" % (e, target)
806+
target = "%s(%s)" % (e, target)
833807
return target
834808

835809
def visitExpression(self, node):

mako/filters.py

-3
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,3 @@ def htmlentityreplace_errors(ex):
161161
"str": "str",
162162
"n": "n",
163163
}
164-
165-
166-
DEFAULT_ESCAPE_PREFIX = "__DEFAULT_ESCAPE_"

mako/pyparser.py

+2-19
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
from mako import compat
1919
from mako import exceptions
2020
from mako import util
21-
from mako.filters import DEFAULT_ESCAPE_PREFIX
22-
from mako.filters import DEFAULT_ESCAPES
2321

2422
# words that cannot be assigned to (notably
2523
# smaller than the total keys in __builtins__)
@@ -198,24 +196,9 @@ def visit_Tuple(self, node):
198196
p.declared_identifiers
199197
)
200198
lui = self.listener.undeclared_identifiers
201-
undeclared_identifiers = lui.union(p.undeclared_identifiers)
202-
conflict_identifiers = undeclared_identifiers.intersection(
203-
DEFAULT_ESCAPES
199+
self.listener.undeclared_identifiers = lui.union(
200+
p.undeclared_identifiers
204201
)
205-
if conflict_identifiers:
206-
_map = {
207-
i: DEFAULT_ESCAPE_PREFIX + i for i in conflict_identifiers
208-
}
209-
for i, arg in enumerate(self.listener.args):
210-
if arg in _map:
211-
self.listener.args[i] = _map[arg]
212-
self.listener.undeclared_identifiers = (
213-
undeclared_identifiers.symmetric_difference(
214-
conflict_identifiers
215-
).union(_map.values())
216-
)
217-
else:
218-
self.listener.undeclared_identifiers = undeclared_identifiers
219202

220203

221204
class ParseFunc(_ast_util.NodeVisitor):

test/test_ast.py

+5-25
Original file line numberDiff line numberDiff line change
@@ -285,36 +285,16 @@ def test_python_fragment(self):
285285

286286
def test_argument_list(self):
287287
parsed = ast.ArgumentList(
288-
"3, 5, 'hi', g+5, " "context.get('lala')", **exception_kwargs
288+
"3, 5, 'hi', x+5, " "context.get('lala')", **exception_kwargs
289289
)
290-
eq_(parsed.undeclared_identifiers, {"g", "context"})
290+
eq_(parsed.undeclared_identifiers, {"x", "context"})
291291
eq_(
292292
[x for x in parsed.args],
293-
["3", "5", "'hi'", "(g + 5)", "context.get('lala')"],
293+
["3", "5", "'hi'", "(x + 5)", "context.get('lala')"],
294294
)
295295

296-
parsed = ast.ArgumentList("m", **exception_kwargs)
297-
eq_(parsed.args, ["m"])
298-
299-
def test_conflict_argument_list(self):
300-
parsed = ast.ArgumentList(
301-
"x-2, h*2, '(u)', n+5, trim, entity, unicode, decode, str, other",
302-
**exception_kwargs,
303-
)
304-
eq_(
305-
parsed.undeclared_identifiers,
306-
{
307-
"__DEFAULT_ESCAPE_trim",
308-
"__DEFAULT_ESCAPE_h",
309-
"__DEFAULT_ESCAPE_decode",
310-
"__DEFAULT_ESCAPE_unicode",
311-
"__DEFAULT_ESCAPE_x",
312-
"__DEFAULT_ESCAPE_str",
313-
"__DEFAULT_ESCAPE_entity",
314-
"__DEFAULT_ESCAPE_n",
315-
"other",
316-
},
317-
)
296+
parsed = ast.ArgumentList("h", **exception_kwargs)
297+
eq_(parsed.args, ["h"])
318298

319299
def test_function_decl(self):
320300
"""test getting the arguments from a function"""

test/test_filters.py

-33
Original file line numberDiff line numberDiff line change
@@ -453,36 +453,3 @@ def test_capture_ccall(self):
453453

454454
# print t.render()
455455
assert flatten_result(t.render()) == "this is foo. body: ccall body"
456-
457-
def test_conflict_filter_ident(self):
458-
class h(object):
459-
foo = str
460-
461-
t = Template(
462-
"""
463-
X:
464-
${"asdf" | h.foo}
465-
"""
466-
)
467-
assert flatten_result(t.render(h=h)) == "X: asdf"
468-
469-
def h(i):
470-
return str(i) + "1"
471-
472-
t = Template(
473-
"""
474-
${123 | h}
475-
"""
476-
)
477-
assert flatten_result(t.render()) == "123"
478-
assert flatten_result(t.render(h=h)) == "1231"
479-
480-
t = Template(
481-
"""
482-
<%def name="foo()" filter="h">
483-
this is foo</%def>
484-
${foo()}
485-
"""
486-
)
487-
assert flatten_result(t.render()) == "this is foo"
488-
assert flatten_result(t.render(h=h)) == "this is foo1"

test/test_lexer.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1543,7 +1543,7 @@ def test_integration(self):
15431543
Text(" <tr>\n", (14, 1)),
15441544
ControlLine("for", "for x in j:", False, (15, 1)),
15451545
Text(" <td>Hello ", (16, 1)),
1546-
Expression("x", ["__DEFAULT_ESCAPE_h"], (16, 23)),
1546+
Expression("x", ["h"], (16, 23)),
15471547
Text("</td>\n", (16, 30)),
15481548
ControlLine("for", "endfor", True, (17, 1)),
15491549
Text(" </tr>\n", (18, 1)),

test/test_template.py

+23
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import os
22

3+
import pytest
4+
35
from mako import exceptions
46
from mako import runtime
57
from mako import util
@@ -722,6 +724,27 @@ def handle(context, error):
722724

723725

724726
class UndefinedVarsTest(TemplateTest):
727+
@pytest.mark.parametrize(
728+
"filters",
729+
[
730+
["str", "n"],
731+
["n"],
732+
["str", "h"],
733+
["h"],
734+
[],
735+
],
736+
)
737+
def test_140_regression(self, filters):
738+
"""test #415, regression on #140"""
739+
740+
t1 = Template(
741+
"hello world ${x}",
742+
strict_undefined=True,
743+
default_filters=filters,
744+
)
745+
746+
t1.render_unicode(x="hi")
747+
725748
def test_undefined(self):
726749
t = Template(
727750
"""

0 commit comments

Comments
 (0)