aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2019-05-29 18:18:04 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2019-05-31 14:03:02 -0400
commitfb7f0437323ba836c68947d38f3604c3336e3a9b (patch)
tree756512a2b68f1c7270f028b487228fd0e3f13778
parentdb498f217e03d772e0c0c37a526226d48ed790e2 (diff)
downloadexternal_python_mako-fb7f0437323ba836c68947d38f3604c3336e3a9b.tar.gz
external_python_mako-fb7f0437323ba836c68947d38f3604c3336e3a9b.tar.bz2
external_python_mako-fb7f0437323ba836c68947d38f3604c3336e3a9b.zip
Use tox / zimports
Change-Id: Ia047c7052a6d242c2cf1c7a83981f1e38ea4d928
-rw-r--r--.pre-commit-config.yaml15
-rw-r--r--mako/__init__.py2
-rw-r--r--mako/_ast_util.py388
-rw-r--r--mako/ast.py62
-rw-r--r--mako/cache.py16
-rwxr-xr-xmako/cmd.py42
-rw-r--r--mako/codegen.py700
-rw-r--r--mako/compat.py64
-rw-r--r--mako/exceptions.py96
-rw-r--r--mako/ext/autohandler.py38
-rw-r--r--mako/ext/babelplugin.py28
-rw-r--r--mako/ext/beaker_cache.py32
-rw-r--r--mako/ext/extract.py47
-rw-r--r--mako/ext/linguaplugin.py52
-rw-r--r--mako/ext/preprocessors.py2
-rw-r--r--mako/ext/pygmentplugin.py166
-rw-r--r--mako/ext/turbogears.py17
-rw-r--r--mako/filters.py92
-rw-r--r--mako/lexer.py273
-rw-r--r--mako/lookup.py163
-rw-r--r--mako/parsetree.py381
-rw-r--r--mako/pygen.py46
-rw-r--r--mako/pyparser.py77
-rw-r--r--mako/runtime.py183
-rw-r--r--mako/template.py352
-rw-r--r--mako/util.py91
-rw-r--r--setup.cfg14
-rw-r--r--setup.py84
-rw-r--r--test/__init__.py116
-rw-r--r--test/ext/test_babelplugin.py127
-rw-r--r--test/ext/test_linguaplugin.py61
-rw-r--r--test/foo/mod_no_encoding.py7
-rw-r--r--test/foo/test_ns.py7
-rw-r--r--test/sample_module_namespace.py7
-rw-r--r--test/test_ast.py196
-rw-r--r--test/test_block.py355
-rw-r--r--test/test_cache.py388
-rw-r--r--test/test_call.py213
-rw-r--r--test/test_cmd.py56
-rw-r--r--test/test_decorators.py57
-rw-r--r--test/test_def.py371
-rw-r--r--test/test_exceptions.py287
-rw-r--r--test/test_filters.py339
-rw-r--r--test/test_inheritance.py351
-rw-r--r--test/test_lexer.py1164
-rw-r--r--test/test_lookup.py98
-rw-r--r--test/test_loop.py245
-rw-r--r--test/test_lru.py97
-rw-r--r--test/test_namespace.py546
-rw-r--r--test/test_pygen.py104
-rw-r--r--test/test_runtime.py18
-rw-r--r--test/test_template.py1349
-rw-r--r--test/test_tgplugin.py51
-rw-r--r--test/test_util.py29
-rw-r--r--test/util.py10
-rw-r--r--tox.ini18
56 files changed, 6203 insertions, 3987 deletions
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..f9b217e
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,15 @@
+# See https://pre-commit.com for more information
+# See https://pre-commit.com/hooks.html for more hooks
+repos:
+- repo: https://github.com/python/black/
+ rev: 19.3b0
+ hooks:
+ - id: black
+ args: [-l 79]
+
+- repo: https://github.com/sqlalchemyorg/zimports/
+ rev: master
+ hooks:
+ - id: zimports
+
+
diff --git a/mako/__init__.py b/mako/__init__.py
index 2435b72..90a4b36 100644
--- a/mako/__init__.py
+++ b/mako/__init__.py
@@ -5,4 +5,4 @@
# the MIT License: http://www.opensource.org/licenses/mit-license.php
-__version__ = '1.0.11'
+__version__ = "1.0.11"
diff --git a/mako/_ast_util.py b/mako/_ast_util.py
index e2c7d24..be95bfb 100644
--- a/mako/_ast_util.py
+++ b/mako/_ast_util.py
@@ -30,47 +30,77 @@
:copyright: Copyright 2008 by Armin Ronacher.
:license: Python License.
"""
-from _ast import * # noqa
+from _ast import Add
+from _ast import And
+from _ast import AST
+from _ast import BitAnd
+from _ast import BitOr
+from _ast import BitXor
+from _ast import ClassDef
+from _ast import Div
+from _ast import Eq
+from _ast import Expression
+from _ast import FloorDiv
+from _ast import FunctionDef
+from _ast import Gt
+from _ast import GtE
+from _ast import If
+from _ast import In
+from _ast import Interactive
+from _ast import Invert
+from _ast import Is
+from _ast import IsNot
+from _ast import LShift
+from _ast import Lt
+from _ast import LtE
+from _ast import Mod
+from _ast import mod
+from _ast import Module
+from _ast import Mult
+from _ast import Name
+from _ast import Not
+from _ast import NotEq
+from _ast import NotIn
+from _ast import Or
+from _ast import PyCF_ONLY_AST
+from _ast import RShift
+from _ast import Str
+from _ast import Sub
+from _ast import UAdd
+from _ast import USub
+
from mako.compat import arg_stringname
-BOOLOP_SYMBOLS = {
- And: 'and',
- Or: 'or'
-}
+BOOLOP_SYMBOLS = {And: "and", Or: "or"}
BINOP_SYMBOLS = {
- Add: '+',
- Sub: '-',
- Mult: '*',
- Div: '/',
- FloorDiv: '//',
- Mod: '%',
- LShift: '<<',
- RShift: '>>',
- BitOr: '|',
- BitAnd: '&',
- BitXor: '^'
+ Add: "+",
+ Sub: "-",
+ Mult: "*",
+ Div: "/",
+ FloorDiv: "//",
+ Mod: "%",
+ LShift: "<<",
+ RShift: ">>",
+ BitOr: "|",
+ BitAnd: "&",
+ BitXor: "^",
}
CMPOP_SYMBOLS = {
- Eq: '==',
- Gt: '>',
- GtE: '>=',
- In: 'in',
- Is: 'is',
- IsNot: 'is not',
- Lt: '<',
- LtE: '<=',
- NotEq: '!=',
- NotIn: 'not in'
+ Eq: "==",
+ Gt: ">",
+ GtE: ">=",
+ In: "in",
+ Is: "is",
+ IsNot: "is not",
+ Lt: "<",
+ LtE: "<=",
+ NotEq: "!=",
+ NotIn: "not in",
}
-UNARYOP_SYMBOLS = {
- Invert: '~',
- Not: 'not',
- UAdd: '+',
- USub: '-'
-}
+UNARYOP_SYMBOLS = {Invert: "~", Not: "not", UAdd: "+", USub: "-"}
ALL_SYMBOLS = {}
ALL_SYMBOLS.update(BOOLOP_SYMBOLS)
@@ -79,12 +109,12 @@ ALL_SYMBOLS.update(CMPOP_SYMBOLS)
ALL_SYMBOLS.update(UNARYOP_SYMBOLS)
-def parse(expr, filename='<unknown>', mode='exec'):
+def parse(expr, filename="<unknown>", mode="exec"):
"""Parse an expression into an AST node."""
return compile(expr, filename, mode, PyCF_ONLY_AST)
-def to_source(node, indent_with=' ' * 4):
+def to_source(node, indent_with=" " * 4):
"""
This function can convert a node tree back into python sourcecode. This
is useful for debugging purposes, especially if you're dealing with custom
@@ -101,7 +131,7 @@ def to_source(node, indent_with=' ' * 4):
"""
generator = SourceGenerator(indent_with)
generator.visit(node)
- return ''.join(generator.result)
+ return "".join(generator.result)
def dump(node):
@@ -109,16 +139,21 @@ def dump(node):
A very verbose representation of the node passed. This is useful for
debugging purposes.
"""
+
def _format(node):
if isinstance(node, AST):
- return '%s(%s)' % (node.__class__.__name__,
- ', '.join('%s=%s' % (a, _format(b))
- for a, b in iter_fields(node)))
+ return "%s(%s)" % (
+ node.__class__.__name__,
+ ", ".join(
+ "%s=%s" % (a, _format(b)) for a, b in iter_fields(node)
+ ),
+ )
elif isinstance(node, list):
- return '[%s]' % ', '.join(_format(x) for x in node)
+ return "[%s]" % ", ".join(_format(x) for x in node)
return repr(node)
+
if not isinstance(node, AST):
- raise TypeError('expected AST, got %r' % node.__class__.__name__)
+ raise TypeError("expected AST, got %r" % node.__class__.__name__)
return _format(node)
@@ -127,9 +162,12 @@ def copy_location(new_node, old_node):
Copy the source location hint (`lineno` and `col_offset`) from the
old to the new node if possible and return the new one.
"""
- for attr in 'lineno', 'col_offset':
- if attr in old_node._attributes and attr in new_node._attributes \
- and hasattr(old_node, attr):
+ for attr in "lineno", "col_offset":
+ if (
+ attr in old_node._attributes
+ and attr in new_node._attributes
+ and hasattr(old_node, attr)
+ ):
setattr(new_node, attr, getattr(old_node, attr))
return new_node
@@ -146,19 +184,21 @@ def fix_missing_locations(node):
Unlike `copy_location` this works recursive and won't touch nodes that
already have a location information.
"""
+
def _fix(node, lineno, col_offset):
- if 'lineno' in node._attributes:
- if not hasattr(node, 'lineno'):
+ if "lineno" in node._attributes:
+ if not hasattr(node, "lineno"):
node.lineno = lineno
else:
lineno = node.lineno
- if 'col_offset' in node._attributes:
- if not hasattr(node, 'col_offset'):
+ if "col_offset" in node._attributes:
+ if not hasattr(node, "col_offset"):
node.col_offset = col_offset
else:
col_offset = node.col_offset
for child in iter_child_nodes(node):
_fix(child, lineno, col_offset)
+
_fix(node, 1, 0)
return node
@@ -170,14 +210,14 @@ def increment_lineno(node, n=1):
file.
"""
for node in zip((node,), walk(node)):
- if 'lineno' in node._attributes:
- node.lineno = getattr(node, 'lineno', 0) + n
+ if "lineno" in node._attributes:
+ node.lineno = getattr(node, "lineno", 0) + n
def iter_fields(node):
"""Iterate over all fields of a node, only yielding existing fields."""
# CPython 2.5 compat
- if not hasattr(node, '_fields') or not node._fields:
+ if not hasattr(node, "_fields") or not node._fields:
return
for field in node._fields:
try:
@@ -213,11 +253,10 @@ def get_compile_mode(node):
node (`Expression`, `Module` etc.) a `TypeError` is thrown.
"""
if not isinstance(node, mod):
- raise TypeError('expected mod node, got %r' % node.__class__.__name__)
- return {
- Expression: 'eval',
- Interactive: 'single'
- }.get(node.__class__, 'expr')
+ raise TypeError("expected mod node, got %r" % node.__class__.__name__)
+ return {Expression: "eval", Interactive: "single"}.get(
+ node.__class__, "expr"
+ )
def get_docstring(node):
@@ -238,6 +277,7 @@ def walk(node):
place and don't care about the context or the order the nodes are returned.
"""
from collections import deque
+
todo = deque([node])
while todo:
node = todo.popleft()
@@ -269,7 +309,7 @@ class NodeVisitor(object):
exists for this node. In that case the generic visit function is
used instead.
"""
- method = 'visit_' + node.__class__.__name__
+ method = "visit_" + node.__class__.__name__
return getattr(self, method, None)
def visit(self, node):
@@ -367,7 +407,7 @@ class SourceGenerator(NodeVisitor):
def write(self, x):
if self.new_lines:
if self.result:
- self.result.append('\n' * self.new_lines)
+ self.result.append("\n" * self.new_lines)
self.result.append(self.indent_with * self.indentation)
self.new_lines = 0
self.result.append(x)
@@ -386,7 +426,7 @@ class SourceGenerator(NodeVisitor):
self.body(node.body)
if node.orelse:
self.newline()
- self.write('else:')
+ self.write("else:")
self.body(node.orelse)
def signature(self, node):
@@ -394,7 +434,7 @@ class SourceGenerator(NodeVisitor):
def write_comma():
if want_comma:
- self.write(', ')
+ self.write(", ")
else:
want_comma.append(True)
@@ -403,19 +443,19 @@ class SourceGenerator(NodeVisitor):
write_comma()
self.visit(arg)
if default is not None:
- self.write('=')
+ self.write("=")
self.visit(default)
if node.vararg is not None:
write_comma()
- self.write('*' + arg_stringname(node.vararg))
+ self.write("*" + arg_stringname(node.vararg))
if node.kwarg is not None:
write_comma()
- self.write('**' + arg_stringname(node.kwarg))
+ self.write("**" + arg_stringname(node.kwarg))
def decorators(self, node):
for decorator in node.decorator_list:
self.newline()
- self.write('@')
+ self.write("@")
self.visit(decorator)
# Statements
@@ -424,29 +464,29 @@ class SourceGenerator(NodeVisitor):
self.newline()
for idx, target in enumerate(node.targets):
if idx:
- self.write(', ')
+ self.write(", ")
self.visit(target)
- self.write(' = ')
+ self.write(" = ")
self.visit(node.value)
def visit_AugAssign(self, node):
self.newline()
self.visit(node.target)
- self.write(BINOP_SYMBOLS[type(node.op)] + '=')
+ self.write(BINOP_SYMBOLS[type(node.op)] + "=")
self.visit(node.value)
def visit_ImportFrom(self, node):
self.newline()
- self.write('from %s%s import ' % ('.' * node.level, node.module))
+ self.write("from %s%s import " % ("." * node.level, node.module))
for idx, item in enumerate(node.names):
if idx:
- self.write(', ')
+ self.write(", ")
self.write(item)
def visit_Import(self, node):
self.newline()
for item in node.names:
- self.write('import ')
+ self.write("import ")
self.visit(item)
def visit_Expr(self, node):
@@ -457,9 +497,9 @@ class SourceGenerator(NodeVisitor):
self.newline(n=2)
self.decorators(node)
self.newline()
- self.write('def %s(' % node.name)
+ self.write("def %s(" % node.name)
self.signature(node.args)
- self.write('):')
+ self.write("):")
self.body(node.body)
def visit_ClassDef(self, node):
@@ -467,200 +507,200 @@ class SourceGenerator(NodeVisitor):
def paren_or_comma():
if have_args:
- self.write(', ')
+ self.write(", ")
else:
have_args.append(True)
- self.write('(')
+ self.write("(")
self.newline(n=3)
self.decorators(node)
self.newline()
- self.write('class %s' % node.name)
+ self.write("class %s" % node.name)
for base in node.bases:
paren_or_comma()
self.visit(base)
# XXX: the if here is used to keep this module compatible
# with python 2.6.
- if hasattr(node, 'keywords'):
+ if hasattr(node, "keywords"):
for keyword in node.keywords:
paren_or_comma()
- self.write(keyword.arg + '=')
+ self.write(keyword.arg + "=")
self.visit(keyword.value)
if getattr(node, "starargs", None):
paren_or_comma()
- self.write('*')
+ self.write("*")
self.visit(node.starargs)
if getattr(node, "kwargs", None):
paren_or_comma()
- self.write('**')
+ self.write("**")
self.visit(node.kwargs)
- self.write(have_args and '):' or ':')
+ self.write(have_args and "):" or ":")
self.body(node.body)
def visit_If(self, node):
self.newline()
- self.write('if ')
+ self.write("if ")
self.visit(node.test)
- self.write(':')
+ self.write(":")
self.body(node.body)
while True:
else_ = node.orelse
if len(else_) == 1 and isinstance(else_[0], If):
node = else_[0]
self.newline()
- self.write('elif ')
+ self.write("elif ")
self.visit(node.test)
- self.write(':')
+ self.write(":")
self.body(node.body)
else:
self.newline()
- self.write('else:')
+ self.write("else:")
self.body(else_)
break
def visit_For(self, node):
self.newline()
- self.write('for ')
+ self.write("for ")
self.visit(node.target)
- self.write(' in ')
+ self.write(" in ")
self.visit(node.iter)
- self.write(':')
+ self.write(":")
self.body_or_else(node)
def visit_While(self, node):
self.newline()
- self.write('while ')
+ self.write("while ")
self.visit(node.test)
- self.write(':')
+ self.write(":")
self.body_or_else(node)
def visit_With(self, node):
self.newline()
- self.write('with ')
+ self.write("with ")
self.visit(node.context_expr)
if node.optional_vars is not None:
- self.write(' as ')
+ self.write(" as ")
self.visit(node.optional_vars)
- self.write(':')
+ self.write(":")
self.body(node.body)
def visit_Pass(self, node):
self.newline()
- self.write('pass')
+ self.write("pass")
def visit_Print(self, node):
# XXX: python 2.6 only
self.newline()
- self.write('print ')
+ self.write("print ")
want_comma = False
if node.dest is not None:
- self.write(' >> ')
+ self.write(" >> ")
self.visit(node.dest)
want_comma = True
for value in node.values:
if want_comma:
- self.write(', ')
+ self.write(", ")
self.visit(value)
want_comma = True
if not node.nl:
- self.write(',')
+ self.write(",")
def visit_Delete(self, node):
self.newline()
- self.write('del ')
+ self.write("del ")
for idx, target in enumerate(node):
if idx:
- self.write(', ')
+ self.write(", ")
self.visit(target)
def visit_TryExcept(self, node):
self.newline()
- self.write('try:')
+ self.write("try:")
self.body(node.body)
for handler in node.handlers:
self.visit(handler)
def visit_TryFinally(self, node):
self.newline()
- self.write('try:')
+ self.write("try:")
self.body(node.body)
self.newline()
- self.write('finally:')
+ self.write("finally:")
self.body(node.finalbody)
def visit_Global(self, node):
self.newline()
- self.write('global ' + ', '.join(node.names))
+ self.write("global " + ", ".join(node.names))
def visit_Nonlocal(self, node):
self.newline()
- self.write('nonlocal ' + ', '.join(node.names))
+ self.write("nonlocal " + ", ".join(node.names))
def visit_Return(self, node):
self.newline()
- self.write('return ')
+ self.write("return ")
self.visit(node.value)
def visit_Break(self, node):
self.newline()
- self.write('break')
+ self.write("break")
def visit_Continue(self, node):
self.newline()
- self.write('continue')
+ self.write("continue")
def visit_Raise(self, node):
# XXX: Python 2.6 / 3.0 compatibility
self.newline()
- self.write('raise')
- if hasattr(node, 'exc') and node.exc is not None:
- self.write(' ')
+ self.write("raise")
+ if hasattr(node, "exc") and node.exc is not None:
+ self.write(" ")
self.visit(node.exc)
if node.cause is not None:
- self.write(' from ')
+ self.write(" from ")
self.visit(node.cause)
- elif hasattr(node, 'type') and node.type is not None:
+ elif hasattr(node, "type") and node.type is not None:
self.visit(node.type)
if node.inst is not None:
- self.write(', ')
+ self.write(", ")
self.visit(node.inst)
if node.tback is not None:
- self.write(', ')
+ self.write(", ")
self.visit(node.tback)
# Expressions
def visit_Attribute(self, node):
self.visit(node.value)
- self.write('.' + node.attr)
+ self.write("." + node.attr)
def visit_Call(self, node):
want_comma = []
def write_comma():
if want_comma:
- self.write(', ')
+ self.write(", ")
else:
want_comma.append(True)
self.visit(node.func)
- self.write('(')
+ self.write("(")
for arg in node.args:
write_comma()
self.visit(arg)
for keyword in node.keywords:
write_comma()
- self.write(keyword.arg + '=')
+ self.write(keyword.arg + "=")
self.visit(keyword.value)
if getattr(node, "starargs", None):
write_comma()
- self.write('*')
+ self.write("*")
self.visit(node.starargs)
if getattr(node, "kwargs", None):
write_comma()
- self.write('**')
+ self.write("**")
self.visit(node.kwargs)
- self.write(')')
+ self.write(")")
def visit_Name(self, node):
self.write(node.id)
@@ -685,105 +725,106 @@ class SourceGenerator(NodeVisitor):
self.write(repr(node.value))
def visit_Tuple(self, node):
- self.write('(')
+ self.write("(")
idx = -1
for idx, item in enumerate(node.elts):
if idx:
- self.write(', ')
+ self.write(", ")
self.visit(item)
- self.write(idx and ')' or ',)')
+ self.write(idx and ")" or ",)")
def sequence_visit(left, right):
def visit(self, node):
self.write(left)
for idx, item in enumerate(node.elts):
if idx:
- self.write(', ')
+ self.write(", ")
self.visit(item)
self.write(right)
+
return visit
- visit_List = sequence_visit('[', ']')
- visit_Set = sequence_visit('{', '}')
+ visit_List = sequence_visit("[", "]")
+ visit_Set = sequence_visit("{", "}")
del sequence_visit
def visit_Dict(self, node):
- self.write('{')
+ self.write("{")
for idx, (key, value) in enumerate(zip(node.keys, node.values)):
if idx:
- self.write(', ')
+ self.write(", ")
self.visit(key)
- self.write(': ')
+ self.write(": ")
self.visit(value)
- self.write('}')
+ self.write("}")
def visit_BinOp(self, node):
- self.write('(')
+ self.write("(")
self.visit(node.left)
- self.write(' %s ' % BINOP_SYMBOLS[type(node.op)])
+ self.write(" %s " % BINOP_SYMBOLS[type(node.op)])
self.visit(node.right)
- self.write(')')
+ self.write(")")
def visit_BoolOp(self, node):
- self.write('(')
+ self.write("(")
for idx, value in enumerate(node.values):
if idx:
- self.write(' %s ' % BOOLOP_SYMBOLS[type(node.op)])
+ self.write(" %s " % BOOLOP_SYMBOLS[type(node.op)])
self.visit(value)
- self.write(')')
+ self.write(")")
def visit_Compare(self, node):
- self.write('(')
+ self.write("(")
self.visit(node.left)
for op, right in zip(node.ops, node.comparators):
- self.write(' %s ' % CMPOP_SYMBOLS[type(op)])
+ self.write(" %s " % CMPOP_SYMBOLS[type(op)])
self.visit(right)
- self.write(')')
+ self.write(")")
def visit_UnaryOp(self, node):
- self.write('(')
+ self.write("(")
op = UNARYOP_SYMBOLS[type(node.op)]
self.write(op)
- if op == 'not':
- self.write(' ')
+ if op == "not":
+ self.write(" ")
self.visit(node.operand)
- self.write(')')
+ self.write(")")
def visit_Subscript(self, node):
self.visit(node.value)
- self.write('[')
+ self.write("[")
self.visit(node.slice)
- self.write(']')
+ self.write("]")
def visit_Slice(self, node):
if node.lower is not None:
self.visit(node.lower)
- self.write(':')
+ self.write(":")
if node.upper is not None:
self.visit(node.upper)
if node.step is not None:
- self.write(':')
- if not (isinstance(node.step, Name) and node.step.id == 'None'):
+ self.write(":")
+ if not (isinstance(node.step, Name) and node.step.id == "None"):
self.visit(node.step)
def visit_ExtSlice(self, node):
for idx, item in node.dims:
if idx:
- self.write(', ')
+ self.write(", ")
self.visit(item)
def visit_Yield(self, node):
- self.write('yield ')
+ self.write("yield ")
self.visit(node.value)
def visit_Lambda(self, node):
- self.write('lambda ')
+ self.write("lambda ")
self.signature(node.args)
- self.write(': ')
+ self.write(": ")
self.visit(node.body)
def visit_Ellipsis(self, node):
- self.write('Ellipsis')
+ self.write("Ellipsis")
def generator_visit(left, right):
def visit(self, node):
@@ -792,64 +833,65 @@ class SourceGenerator(NodeVisitor):
for comprehension in node.generators:
self.visit(comprehension)
self.write(right)
+
return visit
- visit_ListComp = generator_visit('[', ']')
- visit_GeneratorExp = generator_visit('(', ')')
- visit_SetComp = generator_visit('{', '}')
+ visit_ListComp = generator_visit("[", "]")
+ visit_GeneratorExp = generator_visit("(", ")")
+ visit_SetComp = generator_visit("{", "}")
del generator_visit
def visit_DictComp(self, node):
- self.write('{')
+ self.write("{")
self.visit(node.key)
- self.write(': ')
+ self.write(": ")
self.visit(node.value)
for comprehension in node.generators:
self.visit(comprehension)
- self.write('}')
+ self.write("}")
def visit_IfExp(self, node):
self.visit(node.body)
- self.write(' if ')
+ self.write(" if ")
self.visit(node.test)
- self.write(' else ')
+ self.write(" else ")
self.visit(node.orelse)
def visit_Starred(self, node):
- self.write('*')
+ self.write("*")
self.visit(node.value)
def visit_Repr(self, node):
# XXX: python 2.6 only
- self.write('`')
+ self.write("`")
self.visit(node.value)
- self.write('`')
+ self.write("`")
# Helper Nodes
def visit_alias(self, node):
self.write(node.name)
if node.asname is not None:
- self.write(' as ' + node.asname)
+ self.write(" as " + node.asname)
def visit_comprehension(self, node):
- self.write(' for ')
+ self.write(" for ")
self.visit(node.target)
- self.write(' in ')
+ self.write(" in ")
self.visit(node.iter)
if node.ifs:
for if_ in node.ifs:
- self.write(' if ')
+ self.write(" if ")
self.visit(if_)
def visit_excepthandler(self, node):
self.newline()
- self.write('except')
+ self.write("except")
if node.type is not None:
- self.write(' ')
+ self.write(" ")
self.visit(node.type)
if node.name is not None:
- self.write(' as ')
+ self.write(" as ")
self.visit(node.name)
- self.write(':')
+ self.write(":")
self.body(node.body)
diff --git a/mako/ast.py b/mako/ast.py
index 8d2d150..2081d5d 100644
--- a/mako/ast.py
+++ b/mako/ast.py
@@ -7,9 +7,12 @@
"""utilities for analyzing expressions and blocks of Python
code, as well as generating Python from AST nodes"""
-from mako import exceptions, pyparser, compat
import re
+from mako import compat
+from mako import exceptions
+from mako import pyparser
+
class PythonCode(object):
@@ -72,36 +75,39 @@ class PythonFragment(PythonCode):
"""extends PythonCode to provide identifier lookups in partial control
statements
- e.g.
+ e.g.::
+
for x in 5:
elif y==9:
except (MyException, e):
- etc.
+
"""
def __init__(self, code, **exception_kwargs):
- m = re.match(r'^(\w+)(?:\s+(.*?))?:\s*(#|$)', code.strip(), re.S)
+ m = re.match(r"^(\w+)(?:\s+(.*?))?:\s*(#|$)", code.strip(), re.S)
if not m:
raise exceptions.CompileException(
- "Fragment '%s' is not a partial control statement" %
- code, **exception_kwargs)
+ "Fragment '%s' is not a partial control statement" % code,
+ **exception_kwargs
+ )
if m.group(3):
- code = code[:m.start(3)]
+ code = code[: m.start(3)]
(keyword, expr) = m.group(1, 2)
- if keyword in ['for', 'if', 'while']:
+ if keyword in ["for", "if", "while"]:
code = code + "pass"
- elif keyword == 'try':
+ elif keyword == "try":
code = code + "pass\nexcept:pass"
- elif keyword == 'elif' or keyword == 'else':
+ elif keyword == "elif" or keyword == "else":
code = "if False:pass\n" + code + "pass"
- elif keyword == 'except':
+ elif keyword == "except":
code = "try:pass\n" + code + "pass"
- elif keyword == 'with':
+ elif keyword == "with":
code = code + "pass"
else:
raise exceptions.CompileException(
- "Unsupported control keyword: '%s'" %
- keyword, **exception_kwargs)
+ "Unsupported control keyword: '%s'" % keyword,
+ **exception_kwargs
+ )
super(PythonFragment, self).__init__(code, **exception_kwargs)
@@ -115,14 +121,17 @@ class FunctionDecl(object):
f = pyparser.ParseFunc(self, **exception_kwargs)
f.visit(expr)
- if not hasattr(self, 'funcname'):
+ if not hasattr(self, "funcname"):
raise exceptions.CompileException(
"Code '%s' is not a function declaration" % code,
- **exception_kwargs)
+ **exception_kwargs
+ )
if not allow_kwargs and self.kwargs:
raise exceptions.CompileException(
- "'**%s' keyword argument not allowed here" %
- self.kwargnames[-1], **exception_kwargs)
+ "'**%s' keyword argument not allowed here"
+ % self.kwargnames[-1],
+ **exception_kwargs
+ )
def get_argument_expressions(self, as_call=False):
"""Return the argument declarations of this FunctionDecl as a printable
@@ -157,8 +166,10 @@ class FunctionDecl(object):
# `def foo(*, a=1, b, c=3)`
namedecls.append(name)
else:
- namedecls.append("%s=%s" % (
- name, pyparser.ExpressionGenerator(default).value()))
+ namedecls.append(
+ "%s=%s"
+ % (name, pyparser.ExpressionGenerator(default).value())
+ )
else:
namedecls.append(name)
@@ -171,8 +182,10 @@ class FunctionDecl(object):
namedecls.append(name)
else:
default = defaults.pop(0)
- namedecls.append("%s=%s" % (
- name, pyparser.ExpressionGenerator(default).value()))
+ namedecls.append(
+ "%s=%s"
+ % (name, pyparser.ExpressionGenerator(default).value())
+ )
namedecls.reverse()
return namedecls
@@ -187,5 +200,6 @@ class FunctionArgs(FunctionDecl):
"""the argument portion of a function declaration"""
def __init__(self, code, **kwargs):
- super(FunctionArgs, self).__init__("def ANON(%s):pass" % code,
- **kwargs)
+ super(FunctionArgs, self).__init__(
+ "def ANON(%s):pass" % code, **kwargs
+ )
diff --git a/mako/cache.py b/mako/cache.py
index 1af17dd..57821d7 100644
--- a/mako/cache.py
+++ b/mako/cache.py
@@ -4,7 +4,8 @@
# This module is part of Mako and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php
-from mako import compat, util
+from mako import compat
+from mako import util
_cache_plugins = util.PluginLoader("mako.cache")
@@ -90,9 +91,8 @@ class Cache(object):
return creation_function()
return self.impl.get_or_create(
- key,
- creation_function,
- **self._get_cache_kw(kw, context))
+ key, creation_function, **self._get_cache_kw(kw, context)
+ )
def set(self, key, value, **kw):
r"""Place a value in the cache.
@@ -141,7 +141,7 @@ class Cache(object):
template.
"""
- self.invalidate('render_body', __M_defname='render_body')
+ self.invalidate("render_body", __M_defname="render_body")
def invalidate_def(self, name):
"""Invalidate the cached content of a particular ``<%def>`` within this
@@ -149,7 +149,7 @@ class Cache(object):
"""
- self.invalidate('render_%s' % name, __M_defname='render_%s' % name)
+ self.invalidate("render_%s" % name, __M_defname="render_%s" % name)
def invalidate_closure(self, name):
"""Invalidate a nested ``<%def>`` within this template.
@@ -165,7 +165,7 @@ class Cache(object):
self.invalidate(name, __M_defname=name)
def _get_cache_kw(self, kw, context):
- defname = kw.pop('__M_defname', None)
+ defname = kw.pop("__M_defname", None)
if not defname:
tmpl_kw = self.template.cache_args.copy()
tmpl_kw.update(kw)
@@ -177,7 +177,7 @@ class Cache(object):
self._def_regions[defname] = tmpl_kw
if context and self.impl.pass_context:
tmpl_kw = tmpl_kw.copy()
- tmpl_kw.setdefault('context', context)
+ tmpl_kw.setdefault("context", context)
return tmpl_kw
diff --git a/mako/cmd.py b/mako/cmd.py
index ff738c4..e51f021 100755
--- a/mako/cmd.py
+++ b/mako/cmd.py
@@ -4,11 +4,13 @@
# This module is part of Mako and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php
from argparse import ArgumentParser
-from os.path import isfile, dirname
+from os.path import dirname
+from os.path import isfile
import sys
-from mako.template import Template
-from mako.lookup import TemplateLookup
+
from mako import exceptions
+from mako.lookup import TemplateLookup
+from mako.template import Template
def varsplit(var):
@@ -26,29 +28,39 @@ def cmdline(argv=None):
parser = ArgumentParser()
parser.add_argument(
- "--var", default=[], action="append",
- help="variable (can be used multiple times, use name=value)")
+ "--var",
+ default=[],
+ action="append",
+ help="variable (can be used multiple times, use name=value)",
+ )
parser.add_argument(
- "--template-dir", default=[], action="append",
+ "--template-dir",
+ default=[],
+ action="append",
help="Directory to use for template lookup (multiple "
"directories may be provided). If not given then if the "
"template is read from stdin, the value defaults to be "
"the current directory, otherwise it defaults to be the "
- "parent directory of the file provided.")
+ "parent directory of the file provided.",
+ )
parser.add_argument(
- "--output-encoding", default=None,
- help="force output encoding")
- parser.add_argument('input', nargs='?', default='-')
+ "--output-encoding", default=None, help="force output encoding"
+ )
+ parser.add_argument("input", nargs="?", default="-")
options = parser.parse_args(argv)
output_encoding = options.output_encoding
- if options.input == '-':
+ if options.input == "-":
lookup_dirs = options.template_dir or ["."]
lookup = TemplateLookup(lookup_dirs)
try:
- template = Template(sys.stdin.read(), lookup=lookup, output_encoding=output_encoding)
+ template = Template(
+ sys.stdin.read(),
+ lookup=lookup,
+ output_encoding=output_encoding,
+ )
except:
_exit()
else:
@@ -58,7 +70,11 @@ def cmdline(argv=None):
lookup_dirs = options.template_dir or [dirname(filename)]
lookup = TemplateLookup(lookup_dirs)
try:
- template = Template(filename=filename, lookup=lookup, output_encoding=output_encoding)
+ template = Template(
+ filename=filename,
+ lookup=lookup,
+ output_encoding=output_encoding,
+ )
except:
_exit()
diff --git a/mako/codegen.py b/mako/codegen.py
index d4ecbe8..d7e48f9 100644
--- a/mako/codegen.py
+++ b/mako/codegen.py
@@ -7,11 +7,16 @@
"""provides functionality for rendering a parsetree constructing into module
source code."""
-import time
import re
-from mako.pygen import PythonPrinter
-from mako import util, ast, parsetree, filters, exceptions
+import time
+
+from mako import ast
from mako import compat
+from mako import exceptions
+from mako import filters
+from mako import parsetree
+from mako import util
+from mako.pygen import PythonPrinter
MAGIC_NUMBER = 10
@@ -20,22 +25,24 @@ MAGIC_NUMBER = 10
# template and are not accessed via the
# context itself
TOPLEVEL_DECLARED = set(["UNDEFINED", "STOP_RENDERING"])
-RESERVED_NAMES = set(['context', 'loop']).union(TOPLEVEL_DECLARED)
-
-
-def compile(node,
- uri,
- filename=None,
- default_filters=None,
- buffer_filters=None,
- imports=None,
- future_imports=None,
- source_encoding=None,
- generate_magic_comment=True,
- disable_unicode=False,
- strict_undefined=False,
- enable_loop=True,
- reserved_names=frozenset()):
+RESERVED_NAMES = set(["context", "loop"]).union(TOPLEVEL_DECLARED)
+
+
+def compile( # noqa
+ node,
+ uri,
+ filename=None,
+ default_filters=None,
+ buffer_filters=None,
+ imports=None,
+ future_imports=None,
+ source_encoding=None,
+ generate_magic_comment=True,
+ disable_unicode=False,
+ strict_undefined=False,
+ enable_loop=True,
+ reserved_names=frozenset(),
+):
"""Generate module source code given a parsetree node,
uri, and optional source filename"""
@@ -49,38 +56,43 @@ def compile(node,
buf = util.FastEncodingBuffer()
printer = PythonPrinter(buf)
- _GenerateRenderMethod(printer,
- _CompileContext(uri,
- filename,
- default_filters,
- buffer_filters,
- imports,
- future_imports,
- source_encoding,
- generate_magic_comment,
- disable_unicode,
- strict_undefined,
- enable_loop,
- reserved_names),
- node)
+ _GenerateRenderMethod(
+ printer,
+ _CompileContext(
+ uri,
+ filename,
+ default_filters,
+ buffer_filters,
+ imports,
+ future_imports,
+ source_encoding,
+ generate_magic_comment,
+ disable_unicode,
+ strict_undefined,
+ enable_loop,
+ reserved_names,
+ ),
+ node,
+ )
return buf.getvalue()
class _CompileContext(object):
-
- def __init__(self,
- uri,
- filename,
- default_filters,
- buffer_filters,
- imports,
- future_imports,
- source_encoding,
- generate_magic_comment,
- disable_unicode,
- strict_undefined,
- enable_loop,
- reserved_names):
+ def __init__(
+ self,
+ uri,
+ filename,
+ default_filters,
+ buffer_filters,
+ imports,
+ future_imports,
+ source_encoding,
+ generate_magic_comment,
+ disable_unicode,
+ strict_undefined,
+ enable_loop,
+ reserved_names,
+ ):
self.uri = uri
self.filename = filename
self.default_filters = default_filters
@@ -113,12 +125,12 @@ class _GenerateRenderMethod(object):
name = "render_%s" % node.funcname
args = node.get_argument_expressions()
filtered = len(node.filter_args.args) > 0
- buffered = eval(node.attributes.get('buffered', 'False'))
- cached = eval(node.attributes.get('cached', 'False'))
+ buffered = eval(node.attributes.get("buffered", "False"))
+ cached = eval(node.attributes.get("cached", "False"))
defs = None
pagetag = None
if node.is_block and not node.is_anonymous:
- args += ['**pageargs']
+ args += ["**pageargs"]
else:
defs = self.write_toplevel()
pagetag = self.compiler.pagetag
@@ -126,25 +138,23 @@ class _GenerateRenderMethod(object):
if pagetag is not None:
args = pagetag.body_decl.get_argument_expressions()
if not pagetag.body_decl.kwargs:
- args += ['**pageargs']
- cached = eval(pagetag.attributes.get('cached', 'False'))
+ args += ["**pageargs"]
+ cached = eval(pagetag.attributes.get("cached", "False"))
self.compiler.enable_loop = self.compiler.enable_loop or eval(
- pagetag.attributes.get(
- 'enable_loop', 'False')
+ pagetag.attributes.get("enable_loop", "False")
)
else:
- args = ['**pageargs']
+ args = ["**pageargs"]
cached = False
buffered = filtered = False
if args is None:
- args = ['context']
+ args = ["context"]
else:
- args = [a for a in ['context'] + args]
+ args = [a for a in ["context"] + args]
self.write_render_callable(
- pagetag or node,
- name, args,
- buffered, filtered, cached)
+ pagetag or node, name, args, buffered, filtered, cached
+ )
if defs is not None:
for node in defs:
@@ -154,8 +164,9 @@ class _GenerateRenderMethod(object):
self.write_metadata_struct()
def write_metadata_struct(self):
- self.printer.source_map[self.printer.lineno] = \
- max(self.printer.source_map)
+ self.printer.source_map[self.printer.lineno] = max(
+ self.printer.source_map
+ )
struct = {
"filename": self.compiler.filename,
"uri": self.compiler.uri,
@@ -164,10 +175,9 @@ class _GenerateRenderMethod(object):
}
self.printer.writelines(
'"""',
- '__M_BEGIN_METADATA',
+ "__M_BEGIN_METADATA",
compat.json.dumps(struct),
- '__M_END_METADATA\n'
- '"""'
+ "__M_END_METADATA\n" '"""',
)
@property
@@ -186,7 +196,6 @@ class _GenerateRenderMethod(object):
self.compiler.pagetag = None
class FindTopLevel(object):
-
def visitInheritTag(s, node):
inherit.append(node)
@@ -214,14 +223,19 @@ class _GenerateRenderMethod(object):
module_identifiers.declared = module_ident
# module-level names, python code
- if self.compiler.generate_magic_comment and \
- self.compiler.source_encoding:
- self.printer.writeline("# -*- coding:%s -*-" %
- self.compiler.source_encoding)
+ if (
+ self.compiler.generate_magic_comment
+ and self.compiler.source_encoding
+ ):
+ self.printer.writeline(
+ "# -*- coding:%s -*-" % self.compiler.source_encoding
+ )
if self.compiler.future_imports:
- self.printer.writeline("from __future__ import %s" %
- (", ".join(self.compiler.future_imports),))
+ self.printer.writeline(
+ "from __future__ import %s"
+ % (", ".join(self.compiler.future_imports),)
+ )
self.printer.writeline("from mako import runtime, filters, cache")
self.printer.writeline("UNDEFINED = runtime.UNDEFINED")
self.printer.writeline("STOP_RENDERING = runtime.STOP_RENDERING")
@@ -231,36 +245,41 @@ class _GenerateRenderMethod(object):
self.printer.writeline("_modified_time = %r" % time.time())
self.printer.writeline("_enable_loop = %r" % self.compiler.enable_loop)
self.printer.writeline(
- "_template_filename = %r" % self.compiler.filename)
+ "_template_filename = %r" % self.compiler.filename
+ )
self.printer.writeline("_template_uri = %r" % self.compiler.uri)
self.printer.writeline(
- "_source_encoding = %r" % self.compiler.source_encoding)
+ "_source_encoding = %r" % self.compiler.source_encoding
+ )
if self.compiler.imports:
- buf = ''
+ buf = ""
for imp in self.compiler.imports:
buf += imp + "\n"
self.printer.writeline(imp)
impcode = ast.PythonCode(
buf,
- source='', lineno=0,
+ source="",
+ lineno=0,
pos=0,
- filename='template defined imports')
+ filename="template defined imports",
+ )
else:
impcode = None
main_identifiers = module_identifiers.branch(self.node)
- module_identifiers.topleveldefs = \
- module_identifiers.topleveldefs.\
- union(main_identifiers.topleveldefs)
+ mit = module_identifiers.topleveldefs
+ module_identifiers.topleveldefs = mit.union(
+ main_identifiers.topleveldefs
+ )
module_identifiers.declared.update(TOPLEVEL_DECLARED)
if impcode:
module_identifiers.declared.update(impcode.declared_identifiers)
self.compiler.identifiers = module_identifiers
- self.printer.writeline("_exports = %r" %
- [n.name for n in
- main_identifiers.topleveldefs.values()]
- )
+ self.printer.writeline(
+ "_exports = %r"
+ % [n.name for n in main_identifiers.topleveldefs.values()]
+ )
self.printer.write_blanks(2)
if len(module_code):
@@ -274,8 +293,9 @@ class _GenerateRenderMethod(object):
return list(main_identifiers.topleveldefs.values())
- def write_render_callable(self, node, name, args, buffered, filtered,
- cached):
+ def write_render_callable(
+ self, node, name, args, buffered, filtered, cached
+ ):
"""write a top-level render callable.
this could be the main render() method or that of a top-level def."""
@@ -284,32 +304,38 @@ class _GenerateRenderMethod(object):
decorator = node.decorator
if decorator:
self.printer.writeline(
- "@runtime._decorate_toplevel(%s)" % decorator)
+ "@runtime._decorate_toplevel(%s)" % decorator
+ )
self.printer.start_source(node.lineno)
self.printer.writelines(
- "def %s(%s):" % (name, ','.join(args)),
+ "def %s(%s):" % (name, ",".join(args)),
# push new frame, assign current frame to __M_caller
"__M_caller = context.caller_stack._push_frame()",
- "try:"
+ "try:",
)
if buffered or filtered or cached:
self.printer.writeline("context._push_buffer()")
self.identifier_stack.append(
- self.compiler.identifiers.branch(self.node))
- if (not self.in_def or self.node.is_block) and '**pageargs' in args:
- self.identifier_stack[-1].argument_declared.add('pageargs')
+ self.compiler.identifiers.branch(self.node)
+ )
+ if (not self.in_def or self.node.is_block) and "**pageargs" in args:
+ 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
+ len(self.identifiers.locally_assigned) > 0
+ or len(self.identifiers.argument_declared) > 0
):
- self.printer.writeline("__M_locals = __M_dict_builtin(%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)
@@ -321,9 +347,8 @@ class _GenerateRenderMethod(object):
self.printer.write_blanks(2)
if cached:
self.write_cache_decorator(
- node, name,
- args, buffered,
- self.identifiers, toplevel=True)
+ node, name, args, buffered, self.identifiers, toplevel=True
+ )
def write_module_code(self, module_code):
"""write module-level template code, i.e. that which
@@ -338,9 +363,9 @@ class _GenerateRenderMethod(object):
self.printer.writelines(
"def _mako_inherit(template, context):",
"_mako_generate_namespaces(context)",
- "return runtime._inherit_from(context, %s, _template_uri)" %
- (node.parsed_attributes['file']),
- None
+ "return runtime._inherit_from(context, %s, _template_uri)"
+ % (node.parsed_attributes["file"]),
+ None,
)
def write_namespaces(self, namespaces):
@@ -352,12 +377,13 @@ class _GenerateRenderMethod(object):
"except KeyError:",
"_mako_generate_namespaces(context)",
"return context.namespaces[(__name__, name)]",
- None, None
+ None,
+ None,
)
self.printer.writeline("def _mako_generate_namespaces(context):")
for node in namespaces.values():
- if 'import' in node.attributes:
+ if "import" in node.attributes:
self.compiler.has_ns_imports = True
self.printer.start_source(node.lineno)
if len(node.nodes):
@@ -367,7 +393,6 @@ class _GenerateRenderMethod(object):
self.in_def = True
class NSDefVisitor(object):
-
def visitDefTag(s, node):
s.visitDefOrBase(node)
@@ -383,56 +408,54 @@ class _GenerateRenderMethod(object):
)
self.write_inline_def(node, identifiers, nested=False)
export.append(node.funcname)
+
vis = NSDefVisitor()
for n in node.nodes:
n.accept_visitor(vis)
- self.printer.writeline("return [%s]" % (','.join(export)))
+ self.printer.writeline("return [%s]" % (",".join(export)))
self.printer.writeline(None)
self.in_def = False
callable_name = "make_namespace()"
else:
callable_name = "None"
- if 'file' in node.parsed_attributes:
+ if "file" in node.parsed_attributes:
self.printer.writeline(
"ns = runtime.TemplateNamespace(%r,"
" context._clean_inheritance_tokens(),"
" templateuri=%s, callables=%s, "
- " calling_uri=_template_uri)" %
- (
+ " calling_uri=_template_uri)"
+ % (
node.name,
- node.parsed_attributes.get('file', 'None'),
+ node.parsed_attributes.get("file", "None"),
callable_name,
)
)
- elif 'module' in node.parsed_attributes:
+ elif "module" in node.parsed_attributes:
self.printer.writeline(
"ns = runtime.ModuleNamespace(%r,"
" context._clean_inheritance_tokens(),"
" callables=%s, calling_uri=_template_uri,"
- " module=%s)" %
- (
+ " module=%s)"
+ % (
node.name,
callable_name,
- node.parsed_attributes.get(
- 'module', 'None')
+ node.parsed_attributes.get("module", "None"),
)
)
else:
self.printer.writeline(
"ns = runtime.Namespace(%r,"
" context._clean_inheritance_tokens(),"
- " callables=%s, calling_uri=_template_uri)" %
- (
- node.name,
- callable_name,
- )
+ " callables=%s, calling_uri=_template_uri)"
+ % (node.name, callable_name)
)
- if eval(node.attributes.get('inheritable', "False")):
+ if eval(node.attributes.get("inheritable", "False")):
self.printer.writeline("context['self'].%s = ns" % (node.name))
self.printer.writeline(
- "context.namespaces[(__name__, %s)] = ns" % repr(node.name))
+ "context.namespaces[(__name__, %s)] = ns" % repr(node.name)
+ )
self.printer.write_blanks(1)
if not len(namespaces):
self.printer.writeline("pass")
@@ -468,7 +491,8 @@ class _GenerateRenderMethod(object):
# write closure functions for closures that we define
# right here
to_write = to_write.union(
- [c.funcname for c in identifiers.closuredefs.values()])
+ [c.funcname for c in identifiers.closuredefs.values()]
+ )
# remove identifiers that are declared in the argument
# signature of the callable
@@ -492,23 +516,22 @@ class _GenerateRenderMethod(object):
if limit is not None:
to_write = to_write.intersection(limit)
- if toplevel and getattr(self.compiler, 'has_ns_imports', False):
+ if toplevel and getattr(self.compiler, "has_ns_imports", False):
self.printer.writeline("_import_ns = {}")
self.compiler.has_imports = True
for ident, ns in self.compiler.namespaces.items():
- if 'import' in ns.attributes:
+ if "import" in ns.attributes:
self.printer.writeline(
"_mako_get_namespace(context, %r)."
- "_populate(_import_ns, %r)" %
- (
+ "_populate(_import_ns, %r)"
+ % (
ident,
- re.split(r'\s*,\s*', ns.attributes['import'])
- ))
+ re.split(r"\s*,\s*", ns.attributes["import"]),
+ )
+ )
if has_loop:
- self.printer.writeline(
- 'loop = __M_loop = runtime.LoopStack()'
- )
+ self.printer.writeline("loop = __M_loop = runtime.LoopStack()")
for ident in to_write:
if ident in comp_idents:
@@ -526,37 +549,36 @@ class _GenerateRenderMethod(object):
elif ident in self.compiler.namespaces:
self.printer.writeline(
- "%s = _mako_get_namespace(context, %r)" %
- (ident, ident)
+ "%s = _mako_get_namespace(context, %r)" % (ident, ident)
)
else:
- if getattr(self.compiler, 'has_ns_imports', False):
+ if getattr(self.compiler, "has_ns_imports", False):
if self.compiler.strict_undefined:
self.printer.writelines(
- "%s = _import_ns.get(%r, UNDEFINED)" %
- (ident, ident),
+ "%s = _import_ns.get(%r, UNDEFINED)"
+ % (ident, ident),
"if %s is UNDEFINED:" % ident,
"try:",
"%s = context[%r]" % (ident, ident),
"except KeyError:",
- "raise NameError(\"'%s' is not defined\")" %
- ident,
- None, None
+ "raise NameError(\"'%s' is not defined\")" % ident,
+ None,
+ None,
)
else:
self.printer.writeline(
"%s = _import_ns.get"
- "(%r, context.get(%r, UNDEFINED))" %
- (ident, ident, ident))
+ "(%r, context.get(%r, UNDEFINED))"
+ % (ident, ident, ident)
+ )
else:
if self.compiler.strict_undefined:
self.printer.writelines(
"try:",
"%s = context[%r]" % (ident, ident),
"except KeyError:",
- "raise NameError(\"'%s' is not defined\")" %
- ident,
- None
+ "raise NameError(\"'%s' is not defined\")" % ident,
+ None,
)
else:
self.printer.writeline(
@@ -572,14 +594,16 @@ class _GenerateRenderMethod(object):
nameargs = node.get_argument_expressions(as_call=True)
if not self.in_def and (
- len(self.identifiers.locally_assigned) > 0 or
- len(self.identifiers.argument_declared) > 0):
- nameargs.insert(0, 'context._locals(__M_locals)')
+ len(self.identifiers.locally_assigned) > 0
+ or len(self.identifiers.argument_declared) > 0
+ ):
+ nameargs.insert(0, "context._locals(__M_locals)")
else:
- nameargs.insert(0, 'context')
+ nameargs.insert(0, "context")
self.printer.writeline("def %s(%s):" % (funcname, ",".join(namedecls)))
self.printer.writeline(
- "return render_%s(%s)" % (funcname, ",".join(nameargs)))
+ "return render_%s(%s)" % (funcname, ",".join(nameargs))
+ )
self.printer.writeline(None)
def write_inline_def(self, node, identifiers, nested):
@@ -590,21 +614,21 @@ class _GenerateRenderMethod(object):
decorator = node.decorator
if decorator:
self.printer.writeline(
- "@runtime._decorate_inline(context, %s)" % decorator)
+ "@runtime._decorate_inline(context, %s)" % decorator
+ )
self.printer.writeline(
- "def %s(%s):" % (node.funcname, ",".join(namedecls)))
+ "def %s(%s):" % (node.funcname, ",".join(namedecls))
+ )
filtered = len(node.filter_args.args) > 0
- buffered = eval(node.attributes.get('buffered', 'False'))
- cached = eval(node.attributes.get('cached', 'False'))
+ buffered = eval(node.attributes.get("buffered", "False"))
+ cached = eval(node.attributes.get("cached", "False"))
self.printer.writelines(
# push new frame, assign current frame to __M_caller
"__M_caller = context.caller_stack._push_frame()",
- "try:"
+ "try:",
)
if buffered or filtered or cached:
- self.printer.writelines(
- "context._push_buffer()",
- )
+ self.printer.writelines("context._push_buffer()")
identifiers = identifiers.branch(node, nested=nested)
@@ -618,12 +642,19 @@ class _GenerateRenderMethod(object):
self.write_def_finish(node, buffered, filtered, cached)
self.printer.writeline(None)
if cached:
- self.write_cache_decorator(node, node.funcname,
- namedecls, False, identifiers,
- inline=True, toplevel=False)
+ self.write_cache_decorator(
+ node,
+ node.funcname,
+ namedecls,
+ False,
+ identifiers,
+ inline=True,
+ toplevel=False,
+ )
- def write_def_finish(self, node, buffered, filtered, cached,
- callstack=True):
+ def write_def_finish(
+ self, node, buffered, filtered, cached, callstack=True
+ ):
"""write the end section of a rendering function, either outermost or
inline.
@@ -636,9 +667,7 @@ class _GenerateRenderMethod(object):
self.printer.writeline("return ''")
if callstack:
self.printer.writelines(
- "finally:",
- "context.caller_stack._pop_frame()",
- None
+ "finally:", "context.caller_stack._pop_frame()", None
)
if buffered or filtered or cached:
@@ -648,13 +677,12 @@ class _GenerateRenderMethod(object):
# implemenation might be using a context with no
# extra buffers
self.printer.writelines(
- "finally:",
- "__M_buf = context._pop_buffer()"
+ "finally:", "__M_buf = context._pop_buffer()"
)
else:
self.printer.writelines(
"finally:",
- "__M_buf, __M_writer = context._pop_buffer_and_writer()"
+ "__M_buf, __M_writer = context._pop_buffer_and_writer()",
)
if callstack:
@@ -662,89 +690,100 @@ class _GenerateRenderMethod(object):
s = "__M_buf.getvalue()"
if filtered:
- s = self.create_filter_callable(node.filter_args.args, s,
- False)
+ s = self.create_filter_callable(
+ node.filter_args.args, s, False
+ )
self.printer.writeline(None)
if buffered and not cached:
- s = self.create_filter_callable(self.compiler.buffer_filters,
- s, False)
+ s = self.create_filter_callable(
+ self.compiler.buffer_filters, s, False
+ )
if buffered or cached:
self.printer.writeline("return %s" % s)
else:
- self.printer.writelines(
- "__M_writer(%s)" % s,
- "return ''"
- )
-
- def write_cache_decorator(self, node_or_pagetag, name,
- args, buffered, identifiers,
- inline=False, toplevel=False):
+ self.printer.writelines("__M_writer(%s)" % s, "return ''")
+
+ def write_cache_decorator(
+ self,
+ node_or_pagetag,
+ name,
+ args,
+ buffered,
+ identifiers,
+ inline=False,
+ toplevel=False,
+ ):
"""write a post-function decorator to replace a rendering
callable with a cached version of itself."""
self.printer.writeline("__M_%s = %s" % (name, name))
- cachekey = node_or_pagetag.parsed_attributes.get('cache_key',
- repr(name))
+ cachekey = node_or_pagetag.parsed_attributes.get(
+ "cache_key", repr(name)
+ )
cache_args = {}
if self.compiler.pagetag is not None:
cache_args.update(
- (
- pa[6:],
- self.compiler.pagetag.parsed_attributes[pa]
- )
+ (pa[6:], self.compiler.pagetag.parsed_attributes[pa])
for pa in self.compiler.pagetag.parsed_attributes
- if pa.startswith('cache_') and pa != 'cache_key'
+ if pa.startswith("cache_") and pa != "cache_key"
)
cache_args.update(
- (
- pa[6:],
- node_or_pagetag.parsed_attributes[pa]
- ) for pa in node_or_pagetag.parsed_attributes
- if pa.startswith('cache_') and pa != 'cache_key'
+ (pa[6:], node_or_pagetag.parsed_attributes[pa])
+ for pa in node_or_pagetag.parsed_attributes
+ if pa.startswith("cache_") and pa != "cache_key"
)
- if 'timeout' in cache_args:
- cache_args['timeout'] = int(eval(cache_args['timeout']))
+ if "timeout" in cache_args:
+ cache_args["timeout"] = int(eval(cache_args["timeout"]))
- self.printer.writeline("def %s(%s):" % (name, ','.join(args)))
+ self.printer.writeline("def %s(%s):" % (name, ",".join(args)))
# form "arg1, arg2, arg3=arg3, arg4=arg4", etc.
pass_args = [
- "%s=%s" % ((a.split('=')[0],) * 2) if '=' in a else a
- for a in args
+ "%s=%s" % ((a.split("=")[0],) * 2) if "=" in a else a for a in args
]
self.write_variable_declares(
identifiers,
toplevel=toplevel,
- limit=node_or_pagetag.undeclared_identifiers()
+ limit=node_or_pagetag.undeclared_identifiers(),
)
if buffered:
- s = "context.get('local')."\
- "cache._ctx_get_or_create("\
- "%s, lambda:__M_%s(%s), context, %s__M_defname=%r)" % (
- cachekey, name, ','.join(pass_args),
- ''.join(["%s=%s, " % (k, v)
- for k, v in cache_args.items()]),
- name
+ s = (
+ "context.get('local')."
+ "cache._ctx_get_or_create("
+ "%s, lambda:__M_%s(%s), context, %s__M_defname=%r)"
+ % (
+ cachekey,
+ name,
+ ",".join(pass_args),
+ "".join(
+ ["%s=%s, " % (k, v) for k, v in cache_args.items()]
+ ),
+ name,
)
+ )
# apply buffer_filters
- s = self.create_filter_callable(self.compiler.buffer_filters, s,
- False)
+ s = self.create_filter_callable(
+ self.compiler.buffer_filters, s, False
+ )
self.printer.writelines("return " + s, None)
else:
self.printer.writelines(
"__M_writer(context.get('local')."
"cache._ctx_get_or_create("
- "%s, lambda:__M_%s(%s), context, %s__M_defname=%r))" %
- (
- cachekey, name, ','.join(pass_args),
- ''.join(["%s=%s, " % (k, v)
- for k, v in cache_args.items()]),
+ "%s, lambda:__M_%s(%s), context, %s__M_defname=%r))"
+ % (
+ cachekey,
+ name,
+ ",".join(pass_args),
+ "".join(
+ ["%s=%s, " % (k, v) for k, v in cache_args.items()]
+ ),
name,
),
"return ''",
- None
+ None,
)
def create_filter_callable(self, args, target, is_expression):
@@ -753,14 +792,14 @@ class _GenerateRenderMethod(object):
'default' filter aliases as needed."""
def locate_encode(name):
- if re.match(r'decode\..+', name):
+ if re.match(r"decode\..+", name):
return "filters." + name
elif self.compiler.disable_unicode:
return filters.NON_UNICODE_ESCAPES.get(name, name)
else:
return filters.DEFAULT_ESCAPES.get(name, name)
- if 'n' not in args:
+ if "n" not in args:
if is_expression:
if self.compiler.pagetag:
args = self.compiler.pagetag.filter_args.args + args
@@ -768,9 +807,9 @@ class _GenerateRenderMethod(object):
args = self.compiler.default_filters + args
for e in args:
# if filter given as a function, get just the identifier portion
- if e == 'n':
+ if e == "n":
continue
- m = re.match(r'(.+?)(\(.*\))', e)
+ m = re.match(r"(.+?)(\(.*\))", e)
if m:
ident, fargs = m.group(1, 2)
f = locate_encode(ident)
@@ -783,15 +822,18 @@ class _GenerateRenderMethod(object):
def visitExpression(self, node):
self.printer.start_source(node.lineno)
- if len(node.escapes) or \
- (
- self.compiler.pagetag is not None and
- len(self.compiler.pagetag.filter_args.args)
- ) or \
- len(self.compiler.default_filters):
-
- s = self.create_filter_callable(node.escapes_code.args,
- "%s" % node.text, True)
+ if (
+ len(node.escapes)
+ or (
+ self.compiler.pagetag is not None
+ and len(self.compiler.pagetag.filter_args.args)
+ )
+ or len(self.compiler.default_filters)
+ ):
+
+ s = self.create_filter_callable(
+ node.escapes_code.args, "%s" % node.text, True
+ )
self.printer.writeline("__M_writer(%s)" % s)
else:
self.printer.writeline("__M_writer(%s)" % node.text)
@@ -800,12 +842,12 @@ class _GenerateRenderMethod(object):
if node.isend:
self.printer.writeline(None)
if node.has_loop_context:
- self.printer.writeline('finally:')
+ self.printer.writeline("finally:")
self.printer.writeline("loop = __M_loop._exit()")
self.printer.writeline(None)
else:
self.printer.start_source(node.lineno)
- if self.compiler.enable_loop and node.keyword == 'for':
+ if self.compiler.enable_loop and node.keyword == "for":
text = mangle_mako_loop(node, self.printer)
else:
text = node.text
@@ -817,12 +859,16 @@ class _GenerateRenderMethod(object):
# and end control lines, and
# 3) any control line with no content other than comments
if not children or (
- compat.all(isinstance(c, (parsetree.Comment,
- parsetree.ControlLine))
- for c in children) and
- compat.all((node.is_ternary(c.keyword) or c.isend)
- for c in children
- if isinstance(c, parsetree.ControlLine))):
+ compat.all(
+ isinstance(c, (parsetree.Comment, parsetree.ControlLine))
+ for c in children
+ )
+ and compat.all(
+ (node.is_ternary(c.keyword) or c.isend)
+ for c in children
+ if isinstance(c, parsetree.ControlLine)
+ )
+ ):
self.printer.writeline("pass")
def visitText(self, node):
@@ -833,8 +879,7 @@ class _GenerateRenderMethod(object):
filtered = len(node.filter_args.args) > 0
if filtered:
self.printer.writelines(
- "__M_writer = context._push_writer()",
- "try:",
+ "__M_writer = context._push_writer()", "try:"
)
for n in node.nodes:
n.accept_visitor(self)
@@ -842,12 +887,11 @@ class _GenerateRenderMethod(object):
self.printer.writelines(
"finally:",
"__M_buf, __M_writer = context._pop_buffer_and_writer()",
- "__M_writer(%s)" %
- self.create_filter_callable(
- node.filter_args.args,
- "__M_buf.getvalue()",
- False),
- None
+ "__M_writer(%s)"
+ % self.create_filter_callable(
+ node.filter_args.args, "__M_buf.getvalue()", False
+ ),
+ None,
)
def visitCode(self, node):
@@ -861,24 +905,28 @@ class _GenerateRenderMethod(object):
# which is used for def calls within the same template,
# to simulate "enclosing scope"
self.printer.writeline(
- '__M_locals_builtin_stored = __M_locals_builtin()')
+ "__M_locals_builtin_stored = __M_locals_builtin()"
+ )
self.printer.writeline(
- '__M_locals.update(__M_dict_builtin([(__M_key,'
- ' __M_locals_builtin_stored[__M_key]) for __M_key in'
- ' [%s] if __M_key in __M_locals_builtin_stored]))' %
- ','.join([repr(x) for x in node.declared_identifiers()]))
+ "__M_locals.update(__M_dict_builtin([(__M_key,"
+ " __M_locals_builtin_stored[__M_key]) for __M_key in"
+ " [%s] if __M_key in __M_locals_builtin_stored]))"
+ % ",".join([repr(x) for x in node.declared_identifiers()])
+ )
def visitIncludeTag(self, node):
self.printer.start_source(node.lineno)
- args = node.attributes.get('args')
+ args = node.attributes.get("args")
if args:
self.printer.writeline(
- "runtime._include_file(context, %s, _template_uri, %s)" %
- (node.parsed_attributes['file'], args))
+ "runtime._include_file(context, %s, _template_uri, %s)"
+ % (node.parsed_attributes["file"], args)
+ )
else:
self.printer.writeline(
- "runtime._include_file(context, %s, _template_uri)" %
- (node.parsed_attributes['file']))
+ "runtime._include_file(context, %s, _template_uri)"
+ % (node.parsed_attributes["file"])
+ )
def visitNamespaceTag(self, node):
pass
@@ -891,13 +939,14 @@ class _GenerateRenderMethod(object):
self.printer.writeline("%s()" % node.funcname)
else:
nameargs = node.get_argument_expressions(as_call=True)
- nameargs += ['**pageargs']
+ nameargs += ["**pageargs"]
self.printer.writeline(
"if 'parent' not in context._data or "
- "not hasattr(context._data['parent'], '%s'):"
- % node.funcname)
+ "not hasattr(context._data['parent'], '%s'):" % node.funcname
+ )
self.printer.writeline(
- "context['self'].%s(%s)" % (node.funcname, ",".join(nameargs)))
+ "context['self'].%s(%s)" % (node.funcname, ",".join(nameargs))
+ )
self.printer.writeline("\n")
def visitCallNamespaceTag(self, node):
@@ -908,19 +957,18 @@ class _GenerateRenderMethod(object):
def visitCallTag(self, node):
self.printer.writeline("def ccall(caller):")
- export = ['body']
+ export = ["body"]
callable_identifiers = self.identifiers.branch(node, nested=True)
body_identifiers = callable_identifiers.branch(node, nested=False)
# we want the 'caller' passed to ccall to be used
# for the body() function, but for other non-body()
# <%def>s within <%call> we want the current caller
# off the call stack (if any)
- body_identifiers.add_declared('caller')
+ body_identifiers.add_declared("caller")
self.identifier_stack.append(body_identifiers)
class DefVisitor(object):
-
def visitDefTag(s, node):
s.visitDefOrBase(node)
@@ -942,16 +990,13 @@ class _GenerateRenderMethod(object):
self.identifier_stack.pop()
bodyargs = node.body_decl.get_argument_expressions()
- self.printer.writeline("def body(%s):" % ','.join(bodyargs))
+ self.printer.writeline("def body(%s):" % ",".join(bodyargs))
# TODO: figure out best way to specify
# buffering/nonbuffering (at call time would be better)
buffered = False
if buffered:
- self.printer.writelines(
- "context._push_buffer()",
- "try:"
- )
+ self.printer.writelines("context._push_buffer()", "try:")
self.write_variable_declares(body_identifiers)
self.identifier_stack.append(body_identifiers)
@@ -960,25 +1005,22 @@ class _GenerateRenderMethod(object):
self.identifier_stack.pop()
self.write_def_finish(node, buffered, False, False, callstack=False)
- self.printer.writelines(
- None,
- "return [%s]" % (','.join(export)),
- None
- )
+ self.printer.writelines(None, "return [%s]" % (",".join(export)), None)
self.printer.writelines(
# push on caller for nested call
"context.caller_stack.nextcaller = "
"runtime.Namespace('caller', context, "
"callables=ccall(__M_caller))",
- "try:")
+ "try:",
+ )
self.printer.start_source(node.lineno)
self.printer.writelines(
- "__M_writer(%s)" % self.create_filter_callable(
- [], node.expression, True),
+ "__M_writer(%s)"
+ % self.create_filter_callable([], node.expression, True),
"finally:",
"context.caller_stack.nextcaller = None",
- None
+ None,
)
@@ -996,10 +1038,12 @@ class _Identifiers(object):
else:
# things that have already been declared
# in an enclosing namespace (i.e. names we can just use)
- self.declared = set(parent.declared).\
- union([c.name for c in parent.closuredefs.values()]).\
- union(parent.locally_declared).\
- union(parent.argument_declared)
+ self.declared = (
+ set(parent.declared)
+ .union([c.name for c in parent.closuredefs.values()])
+ .union(parent.locally_declared)
+ .union(parent.argument_declared)
+ )
# if these identifiers correspond to a "nested"
# scope, it means whatever the parent identifiers
@@ -1043,11 +1087,13 @@ class _Identifiers(object):
node.accept_visitor(self)
illegal_names = self.compiler.reserved_names.intersection(
- self.locally_declared)
+ self.locally_declared
+ )
if illegal_names:
raise exceptions.NameConflictError(
- "Reserved words declared in template: %s" %
- ", ".join(illegal_names))
+ "Reserved words declared in template: %s"
+ % ", ".join(illegal_names)
+ )
def branch(self, node, **kwargs):
"""create a new Identifiers for a new Node, with
@@ -1060,24 +1106,28 @@ class _Identifiers(object):
return set(self.topleveldefs.union(self.closuredefs).values())
def __repr__(self):
- return "Identifiers(declared=%r, locally_declared=%r, "\
- "undeclared=%r, topleveldefs=%r, closuredefs=%r, "\
- "argumentdeclared=%r)" %\
- (
+ return (
+ "Identifiers(declared=%r, locally_declared=%r, "
+ "undeclared=%r, topleveldefs=%r, closuredefs=%r, "
+ "argumentdeclared=%r)"
+ % (
list(self.declared),
list(self.locally_declared),
list(self.undeclared),
[c.name for c in self.topleveldefs.values()],
[c.name for c in self.closuredefs.values()],
- self.argument_declared)
+ self.argument_declared,
+ )
+ )
def check_declared(self, node):
"""update the state of this Identifiers with the undeclared
and declared identifiers of the given node."""
for ident in node.undeclared_identifiers():
- if ident != 'context' and\
- ident not in self.declared.union(self.locally_declared):
+ if ident != "context" and ident not in self.declared.union(
+ self.locally_declared
+ ):
self.undeclared.add(ident)
for ident in node.declared_identifiers():
self.locally_declared.add(ident)
@@ -1097,7 +1147,8 @@ class _Identifiers(object):
if not node.ismodule:
self.check_declared(node)
self.locally_assigned = self.locally_assigned.union(
- node.declared_identifiers())
+ node.declared_identifiers()
+ )
def visitNamespaceTag(self, node):
# only traverse into the sub-elements of a
@@ -1110,13 +1161,16 @@ class _Identifiers(object):
def _check_name_exists(self, collection, node):
existing = collection.get(node.funcname)
collection[node.funcname] = node
- if existing is not None and \
- existing is not node and \
- (node.is_block or existing.is_block):
+ if (
+ existing is not None
+ and existing is not node
+ and (node.is_block or existing.is_block)
+ ):
raise exceptions.CompileException(
"%%def or %%block named '%s' already "
- "exists in this template." %
- node.funcname, **node.exception_kwargs)
+ "exists in this template." % node.funcname,
+ **node.exception_kwargs
+ )
def visitDefTag(self, node):
if node.is_root() and not node.is_anonymous:
@@ -1125,8 +1179,9 @@ class _Identifiers(object):
self._check_name_exists(self.closuredefs, node)
for ident in node.undeclared_identifiers():
- if ident != 'context' and \
- ident not in self.declared.union(self.locally_declared):
+ if ident != "context" and ident not in self.declared.union(
+ self.locally_declared
+ ):
self.undeclared.add(ident)
# visit defs only one level deep
@@ -1143,16 +1198,22 @@ class _Identifiers(object):
if isinstance(self.node, parsetree.DefTag):
raise exceptions.CompileException(
"Named block '%s' not allowed inside of def '%s'"
- % (node.name, self.node.name), **node.exception_kwargs)
- elif isinstance(self.node,
- (parsetree.CallTag, parsetree.CallNamespaceTag)):
+ % (node.name, self.node.name),
+ **node.exception_kwargs
+ )
+ elif isinstance(
+ self.node, (parsetree.CallTag, parsetree.CallNamespaceTag)
+ ):
raise exceptions.CompileException(
"Named block '%s' not allowed inside of <%%call> tag"
- % (node.name, ), **node.exception_kwargs)
+ % (node.name,),
+ **node.exception_kwargs
+ )
for ident in node.undeclared_identifiers():
- if ident != 'context' and \
- ident not in self.declared.union(self.locally_declared):
+ if ident != "context" and ident not in self.declared.union(
+ self.locally_declared
+ ):
self.undeclared.add(ident)
if not node.is_anonymous:
@@ -1167,8 +1228,9 @@ class _Identifiers(object):
def visitTextTag(self, node):
for ident in node.undeclared_identifiers():
- if ident != 'context' and \
- ident not in self.declared.union(self.locally_declared):
+ if ident != "context" and ident not in self.declared.union(
+ self.locally_declared
+ ):
self.undeclared.add(ident)
def visitIncludeTag(self, node):
@@ -1185,9 +1247,9 @@ class _Identifiers(object):
def visitCallTag(self, node):
if node is self.node:
for ident in node.undeclared_identifiers():
- if ident != 'context' and \
- ident not in self.declared.union(
- self.locally_declared):
+ if ident != "context" and ident not in self.declared.union(
+ self.locally_declared
+ ):
self.undeclared.add(ident)
for ident in node.declared_identifiers():
self.argument_declared.add(ident)
@@ -1195,15 +1257,15 @@ class _Identifiers(object):
n.accept_visitor(self)
else:
for ident in node.undeclared_identifiers():
- if ident != 'context' and \
- ident not in self.declared.union(
- self.locally_declared):
+ if ident != "context" and ident not in self.declared.union(
+ self.locally_declared
+ ):
self.undeclared.add(ident)
_FOR_LOOP = re.compile(
- r'^for\s+((?:\(?)\s*[A-Za-z_][A-Za-z_0-9]*'
- r'(?:\s*,\s*(?:[A-Za-z_][A-Za-z0-9_]*),??)*\s*(?:\)?))\s+in\s+(.*):'
+ r"^for\s+((?:\(?)\s*[A-Za-z_][A-Za-z_0-9]*"
+ r"(?:\s*,\s*(?:[A-Za-z_][A-Za-z0-9_]*),??)*\s*(?:\)?))\s+in\s+(.*):"
)
@@ -1218,11 +1280,11 @@ def mangle_mako_loop(node, printer):
match = _FOR_LOOP.match(node.text)
if match:
printer.writelines(
- 'loop = __M_loop._enter(%s)' % match.group(2),
- 'try:'
+ "loop = __M_loop._enter(%s)" % match.group(2),
+ "try:"
# 'with __M_loop(%s) as loop:' % match.group(2)
)
- text = 'for %s in loop:' % match.group(1)
+ text = "for %s in loop:" % match.group(1)
else:
raise SyntaxError("Couldn't apply loop context: %s" % node.text)
else:
@@ -1239,7 +1301,7 @@ class LoopVariable(object):
self.detected = False
def _loop_reference_detected(self, node):
- if 'loop' in node.undeclared_identifiers():
+ if "loop" in node.undeclared_identifiers():
self.detected = True
else:
for n in node.get_children():
diff --git a/mako/compat.py b/mako/compat.py
index 312bbd8..5f9d9ac 100644
--- a/mako/compat.py
+++ b/mako/compat.py
@@ -1,3 +1,4 @@
+import json # noqa
import sys
import time
@@ -5,9 +6,9 @@ py3k = sys.version_info >= (3, 0)
py33 = sys.version_info >= (3, 3)
py2k = sys.version_info < (3,)
py27 = sys.version_info >= (2, 7)
-jython = sys.platform.startswith('java')
-win32 = sys.platform.startswith('win')
-pypy = hasattr(sys, 'pypy_version_info')
+jython = sys.platform.startswith("java")
+win32 = sys.platform.startswith("win")
+pypy = hasattr(sys, "pypy_version_info")
if py3k:
# create a "getargspec" from getfullargspec(), which is not deprecated
@@ -17,15 +18,16 @@ if py3k:
# with that for now.
import collections
+
ArgSpec = collections.namedtuple(
- "ArgSpec",
- ["args", "varargs", "keywords", "defaults"])
+ "ArgSpec", ["args", "varargs", "keywords", "defaults"]
+ )
from inspect import getfullargspec as inspect_getfullargspec
def inspect_getargspec(func):
- return ArgSpec(
- *inspect_getfullargspec(func)[0:4]
- )
+ return ArgSpec(*inspect_getfullargspec(func)[0:4])
+
+
else:
from inspect import getargspec as inspect_getargspec # noqa
@@ -35,7 +37,8 @@ if py3k:
import builtins as compat_builtins
from urllib.parse import quote_plus, unquote_plus
from html.entities import codepoint2name, name2codepoint
- string_types = str,
+
+ string_types = (str,)
binary_type = bytes
text_type = str
@@ -50,8 +53,10 @@ if py3k:
def octal(lit):
return eval("0o" + lit)
+
else:
import __builtin__ as compat_builtins # noqa
+
try:
from cStringIO import StringIO
except:
@@ -61,7 +66,8 @@ else:
from urllib import quote_plus, unquote_plus # noqa
from htmlentitydefs import codepoint2name, name2codepoint # noqa
- string_types = basestring, # noqa
+
+ string_types = (basestring,) # noqa
binary_type = str
text_type = unicode # noqa
@@ -80,11 +86,13 @@ if py33:
def load_module(module_id, path):
return machinery.SourceFileLoader(module_id, path).load_module()
+
+
else:
import imp
def load_module(module_id, path):
- fp = open(path, 'rb')
+ fp = open(path, "rb")
try:
return imp.load_source(module_id, path, fp)
finally:
@@ -92,28 +100,36 @@ else:
if py3k:
+
def reraise(tp, value, tb=None, cause=None):
if cause is not None:
value.__cause__ = cause
if value.__traceback__ is not tb:
raise value.with_traceback(tb)
raise value
+
+
else:
- exec("def reraise(tp, value, tb=None, cause=None):\n"
- " raise tp, value, tb\n")
+ exec(
+ "def reraise(tp, value, tb=None, cause=None):\n"
+ " raise tp, value, tb\n"
+ )
def exception_as():
return sys.exc_info()[1]
+
try:
import threading
+
if py3k:
import _thread as thread
else:
import thread
except ImportError:
import dummy_threading as threading # noqa
+
if py3k:
import _dummy_thread as thread
else:
@@ -127,21 +143,23 @@ else:
try:
from functools import partial
except:
+
def partial(func, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = keywords.copy()
newkeywords.update(fkeywords)
return func(*(args + fargs), **newkeywords)
+
return newfunc
-all = all
-import json # noqa
+all = all # noqa
def exception_name(exc):
return exc.__class__.__name__
+
try:
from inspect import CO_VARKEYWORDS, CO_VARARGS
@@ -167,17 +185,23 @@ try:
return args, varargs, varkw, fn.__defaults__
else:
return args, varargs, varkw, fn.func_defaults
+
+
except ImportError:
import inspect
def inspect_func_args(fn):
return inspect.getargspec(fn)
+
if py3k:
- def callable(fn):
- return hasattr(fn, '__call__')
+ # TODO: this has been restored in py3k
+ def callable(fn): # noqa
+ return hasattr(fn, "__call__")
+
+
else:
- callable = callable
+ callable = callable # noqa
################################################
@@ -186,6 +210,8 @@ else:
def with_metaclass(meta, base=object):
"""Create a base class with a metaclass."""
return meta("%sBase" % meta.__name__, (base,), {})
+
+
################################################
@@ -194,7 +220,7 @@ def arg_stringname(func_arg):
In Python3.4 a function's args are
of _ast.arg type not _ast.name
"""
- if hasattr(func_arg, 'arg'):
+ if hasattr(func_arg, "arg"):
return func_arg.arg
else:
return str(func_arg)
diff --git a/mako/exceptions.py b/mako/exceptions.py
index e2d78bd..7720356 100644
--- a/mako/exceptions.py
+++ b/mako/exceptions.py
@@ -6,9 +6,11 @@
"""exception classes"""
-import traceback
import sys
-from mako import util, compat
+import traceback
+
+from mako import compat
+from mako import util
class MakoException(Exception):
@@ -27,11 +29,10 @@ def _format_filepos(lineno, pos, filename):
class CompileException(MakoException):
-
def __init__(self, message, source, lineno, pos, filename):
MakoException.__init__(
- self,
- message + _format_filepos(lineno, pos, filename))
+ self, message + _format_filepos(lineno, pos, filename)
+ )
self.lineno = lineno
self.pos = pos
self.filename = filename
@@ -39,11 +40,10 @@ class CompileException(MakoException):
class SyntaxException(MakoException):
-
def __init__(self, message, source, lineno, pos, filename):
MakoException.__init__(
- self,
- message + _format_filepos(lineno, pos, filename))
+ self, message + _format_filepos(lineno, pos, filename)
+ )
self.lineno = lineno
self.pos = pos
self.filename = filename
@@ -115,7 +115,7 @@ class RichTraceback(object):
# str(Exception(u'\xe6')) work in Python < 2.6
self.message = self.error.args[0]
if not isinstance(self.message, compat.text_type):
- self.message = compat.text_type(self.message, 'ascii', 'replace')
+ self.message = compat.text_type(self.message, "ascii", "replace")
def _get_reformatted_records(self, records):
for rec in records:
@@ -151,12 +151,13 @@ class RichTraceback(object):
source, and code line from that line number of the template."""
import mako.template
+
mods = {}
rawrecords = traceback.extract_tb(trcback)
new_trcback = []
for filename, lineno, function, line in rawrecords:
if not line:
- line = ''
+ line = ""
try:
(line_map, template_lines) = mods[filename]
except KeyError:
@@ -169,7 +170,7 @@ class RichTraceback(object):
# A normal .py file (not a Template)
if not compat.py3k:
try:
- fp = open(filename, 'rb')
+ fp = open(filename, "rb")
encoding = util.parse_encoding(fp)
fp.close()
except IOError:
@@ -177,20 +178,32 @@ class RichTraceback(object):
if encoding:
line = line.decode(encoding)
else:
- line = line.decode('ascii', 'replace')
- new_trcback.append((filename, lineno, function, line,
- None, None, None, None))
+ line = line.decode("ascii", "replace")
+ new_trcback.append(
+ (
+ filename,
+ lineno,
+ function,
+ line,
+ None,
+ None,
+ None,
+ None,
+ )
+ )
continue
template_ln = 1
- source_map = mako.template.ModuleInfo.\
- get_module_source_metadata(
- module_source, full_line_map=True)
- line_map = source_map['full_line_map']
+ mtm = mako.template.ModuleInfo
+ source_map = mtm.get_module_source_metadata(
+ module_source, full_line_map=True
+ )
+ line_map = source_map["full_line_map"]
- template_lines = [line_ for line_ in
- template_source.split("\n")]
+ template_lines = [
+ line_ for line_ in template_source.split("\n")
+ ]
mods[filename] = (line_map, template_lines)
template_ln = line_map[lineno - 1]
@@ -199,9 +212,18 @@ class RichTraceback(object):
template_line = template_lines[template_ln - 1]
else:
template_line = None
- new_trcback.append((filename, lineno, function,
- line, template_filename, template_ln,
- template_line, template_source))
+ new_trcback.append(
+ (
+ filename,
+ lineno,
+ function,
+ line,
+ template_filename,
+ template_ln,
+ template_line,
+ template_source,
+ )
+ )
if not self.source:
for l in range(len(new_trcback) - 1, 0, -1):
if new_trcback[l][5]:
@@ -212,17 +234,17 @@ class RichTraceback(object):
if new_trcback:
try:
# A normal .py file (not a Template)
- fp = open(new_trcback[-1][0], 'rb')
+ fp = open(new_trcback[-1][0], "rb")
encoding = util.parse_encoding(fp)
if compat.py3k and not encoding:
- encoding = 'utf-8'
+ encoding = "utf-8"
fp.seek(0)
self.source = fp.read()
fp.close()
if encoding:
self.source = self.source.decode(encoding)
except IOError:
- self.source = ''
+ self.source = ""
self.lineno = new_trcback[-1][1]
return new_trcback
@@ -235,7 +257,9 @@ def text_error_template(lookup=None):
"""
import mako.template
- return mako.template.Template(r"""
+
+ return mako.template.Template(
+ r"""
<%page args="error=None, traceback=None"/>
<%!
from mako.exceptions import RichTraceback
@@ -249,7 +273,8 @@ Traceback (most recent call last):
${line | trim}
% endfor
${tback.errorname}: ${tback.message}
-""")
+"""
+ )
def _install_pygments():
@@ -261,9 +286,10 @@ def _install_pygments():
def _install_fallback():
global syntax_highlight, pygments_html_formatter
from mako.filters import html_escape
+
pygments_html_formatter = None
- def syntax_highlight(filename='', language=None):
+ def syntax_highlight(filename="", language=None):
return html_escape
@@ -272,6 +298,8 @@ def _install_highlighting():
_install_pygments()
except ImportError:
_install_fallback()
+
+
_install_highlighting()
@@ -289,7 +317,9 @@ def html_error_template():
"""
import mako.template
- return mako.template.Template(r"""
+
+ return mako.template.Template(
+ r"""
<%!
from mako.exceptions import RichTraceback, syntax_highlight,\
pygments_html_formatter
@@ -392,5 +422,7 @@ def html_error_template():
</body>
</html>
% endif
-""", output_encoding=sys.getdefaultencoding(),
- encoding_errors='htmlentityreplace')
+""",
+ output_encoding=sys.getdefaultencoding(),
+ encoding_errors="htmlentityreplace",
+ )
diff --git a/mako/ext/autohandler.py b/mako/ext/autohandler.py
index 9d1c911..f262b13 100644
--- a/mako/ext/autohandler.py
+++ b/mako/ext/autohandler.py
@@ -8,29 +8,29 @@
requires that the TemplateLookup class is used with templates.
-usage:
+usage::
-<%!
- from mako.ext.autohandler import autohandler
-%>
-<%inherit file="${autohandler(template, context)}"/>
+ <%!
+ from mako.ext.autohandler import autohandler
+ %>
+ <%inherit file="${autohandler(template, context)}"/>
-or with custom autohandler filename:
+or with custom autohandler filename::
-<%!
- from mako.ext.autohandler import autohandler
-%>
-<%inherit file="${autohandler(template, context, name='somefilename')}"/>
+ <%!
+ from mako.ext.autohandler import autohandler
+ %>
+ <%inherit file="${autohandler(template, context, name='somefilename')}"/>
"""
-import posixpath
import os
+import posixpath
import re
-def autohandler(template, context, name='autohandler'):
+def autohandler(template, context, name="autohandler"):
lookup = context.lookup
_template_uri = template.module._template_uri
if not lookup.filesystem_checks:
@@ -39,13 +39,14 @@ def autohandler(template, context, name='autohandler'):
except KeyError:
pass
- tokens = re.findall(r'([^/]+)', posixpath.dirname(_template_uri)) + [name]
+ tokens = re.findall(r"([^/]+)", posixpath.dirname(_template_uri)) + [name]
while len(tokens):
- path = '/' + '/'.join(tokens)
+ path = "/" + "/".join(tokens)
if path != _template_uri and _file_exists(lookup, path):
if not lookup.filesystem_checks:
return lookup._uri_cache.setdefault(
- (autohandler, _template_uri, name), path)
+ (autohandler, _template_uri, name), path
+ )
else:
return path
if len(tokens) == 1:
@@ -54,15 +55,16 @@ def autohandler(template, context, name='autohandler'):
if not lookup.filesystem_checks:
return lookup._uri_cache.setdefault(
- (autohandler, _template_uri, name), None)
+ (autohandler, _template_uri, name), None
+ )
else:
return None
def _file_exists(lookup, path):
- psub = re.sub(r'^/', '', path)
+ psub = re.sub(r"^/", "", path)
for d in lookup.directories:
- if os.path.exists(d + '/' + psub):
+ if os.path.exists(d + "/" + psub):
return True
else:
return False
diff --git a/mako/ext/babelplugin.py b/mako/ext/babelplugin.py
index 0b5e84f..e7e93f5 100644
--- a/mako/ext/babelplugin.py
+++ b/mako/ext/babelplugin.py
@@ -6,18 +6,19 @@
"""gettext message extraction via Babel: http://babel.edgewall.org/"""
from babel.messages.extract import extract_python
+
from mako.ext.extract import MessageExtractor
class BabelMakoExtractor(MessageExtractor):
-
def __init__(self, keywords, comment_tags, options):
self.keywords = keywords
self.options = options
self.config = {
- 'comment-tags': u' '.join(comment_tags),
- 'encoding': options.get('input_encoding',
- options.get('encoding', None)),
+ "comment-tags": u" ".join(comment_tags),
+ "encoding": options.get(
+ "input_encoding", options.get("encoding", None)
+ ),
}
super(BabelMakoExtractor, self).__init__()
@@ -25,12 +26,19 @@ class BabelMakoExtractor(MessageExtractor):
return self.process_file(fileobj)
def process_python(self, code, code_lineno, translator_strings):
- comment_tags = self.config['comment-tags']
- for lineno, funcname, messages, python_translator_comments \
- in extract_python(code,
- self.keywords, comment_tags, self.options):
- yield (code_lineno + (lineno - 1), funcname, messages,
- translator_strings + python_translator_comments)
+ comment_tags = self.config["comment-tags"]
+ for (
+ lineno,
+ funcname,
+ messages,
+ python_translator_comments,
+ ) in extract_python(code, self.keywords, comment_tags, self.options):
+ yield (
+ code_lineno + (lineno - 1),
+ funcname,
+ messages,
+ translator_strings + python_translator_comments,
+ )
def extract(fileobj, keywords, comment_tags, options):
diff --git a/mako/ext/beaker_cache.py b/mako/ext/beaker_cache.py
index c7c260d..ebca8a9 100644
--- a/mako/ext/beaker_cache.py
+++ b/mako/ext/beaker_cache.py
@@ -1,7 +1,6 @@
"""Provide a :class:`.CacheImpl` for the Beaker caching system."""
from mako import exceptions
-
from mako.cache import CacheImpl
try:
@@ -27,36 +26,37 @@ class BeakerCacheImpl(CacheImpl):
def __init__(self, cache):
if not has_beaker:
raise exceptions.RuntimeException(
- "Can't initialize Beaker plugin; Beaker is not installed.")
+ "Can't initialize Beaker plugin; Beaker is not installed."
+ )
global _beaker_cache
if _beaker_cache is None:
- if 'manager' in cache.template.cache_args:
- _beaker_cache = cache.template.cache_args['manager']
+ if "manager" in cache.template.cache_args:
+ _beaker_cache = cache.template.cache_args["manager"]
else:
_beaker_cache = beaker_cache.CacheManager()
super(BeakerCacheImpl, self).__init__(cache)
def _get_cache(self, **kw):
- expiretime = kw.pop('timeout', None)
- if 'dir' in kw:
- kw['data_dir'] = kw.pop('dir')
+ expiretime = kw.pop("timeout", None)
+ if "dir" in kw:
+ kw["data_dir"] = kw.pop("dir")
elif self.cache.template.module_directory:
- kw['data_dir'] = self.cache.template.module_directory
+ kw["data_dir"] = self.cache.template.module_directory
- if 'manager' in kw:
- kw.pop('manager')
+ if "manager" in kw:
+ kw.pop("manager")
- if kw.get('type') == 'memcached':
- kw['type'] = 'ext:memcached'
+ if kw.get("type") == "memcached":
+ kw["type"] = "ext:memcached"
- if 'region' in kw:
- region = kw.pop('region')
+ if "region" in kw:
+ region = kw.pop("region")
cache = _beaker_cache.get_cache_region(self.cache.id, region, **kw)
else:
cache = _beaker_cache.get_cache(self.cache.id, **kw)
- cache_args = {'starttime': self.cache.starttime}
+ cache_args = {"starttime": self.cache.starttime}
if expiretime:
- cache_args['expiretime'] = expiretime
+ cache_args["expiretime"] = expiretime
return cache, cache_args
def get_or_create(self, key, creation_function, **kw):
diff --git a/mako/ext/extract.py b/mako/ext/extract.py
index d777ea8..766129b 100644
--- a/mako/ext/extract.py
+++ b/mako/ext/extract.py
@@ -1,30 +1,33 @@
import re
+
from mako import compat
from mako import lexer
from mako import parsetree
class MessageExtractor(object):
-
def process_file(self, fileobj):
template_node = lexer.Lexer(
- fileobj.read(),
- input_encoding=self.config['encoding']).parse()
+ fileobj.read(), input_encoding=self.config["encoding"]
+ ).parse()
for extracted in self.extract_nodes(template_node.get_children()):
yield extracted
def extract_nodes(self, nodes):
translator_comments = []
in_translator_comments = False
- input_encoding = self.config['encoding'] or 'ascii'
+ input_encoding = self.config["encoding"] or "ascii"
comment_tags = list(
- filter(None, re.split(r'\s+', self.config['comment-tags'])))
+ filter(None, re.split(r"\s+", self.config["comment-tags"]))
+ )
for node in nodes:
child_nodes = None
- if in_translator_comments and \
- isinstance(node, parsetree.Text) and \
- not node.content.strip():
+ if (
+ in_translator_comments
+ and isinstance(node, parsetree.Text)
+ and not node.content.strip()
+ ):
# Ignore whitespace within translator comments
continue
@@ -32,13 +35,15 @@ class MessageExtractor(object):
value = node.text.strip()
if in_translator_comments:
translator_comments.extend(
- self._split_comment(node.lineno, value))
+ self._split_comment(node.lineno, value)
+ )
continue
for comment_tag in comment_tags:
if value.startswith(comment_tag):
in_translator_comments = True
translator_comments.extend(
- self._split_comment(node.lineno, value))
+ self._split_comment(node.lineno, value)
+ )
continue
if isinstance(node, parsetree.DefTag):
@@ -69,15 +74,18 @@ class MessageExtractor(object):
continue
# Comments don't apply unless they immediately precede the message
- if translator_comments and \
- translator_comments[-1][0] < node.lineno - 1:
+ if (
+ translator_comments
+ and translator_comments[-1][0] < node.lineno - 1
+ ):
translator_comments = []
translator_strings = [
- comment[1] for comment in translator_comments]
+ comment[1] for comment in translator_comments
+ ]
if isinstance(code, compat.text_type):
- code = code.encode(input_encoding, 'backslashreplace')
+ code = code.encode(input_encoding, "backslashreplace")
used_translator_comments = False
# We add extra newline to work around a pybabel bug
@@ -85,10 +93,11 @@ class MessageExtractor(object):
# input string of the input is non-ascii)
# Also, because we added it, we have to subtract one from
# node.lineno
- code = compat.byte_buffer(compat.b('\n') + code)
+ code = compat.byte_buffer(compat.b("\n") + code)
for message in self.process_python(
- code, node.lineno - 1, translator_strings):
+ code, node.lineno - 1, translator_strings
+ ):
yield message
used_translator_comments = True
@@ -104,5 +113,7 @@ class MessageExtractor(object):
def _split_comment(lineno, comment):
"""Return the multiline comment at lineno split into a list of
comment line numbers and the accompanying comment line"""
- return [(lineno + index, line) for index, line in
- enumerate(comment.splitlines())]
+ return [
+ (lineno + index, line)
+ for index, line in enumerate(comment.splitlines())
+ ]
diff --git a/mako/ext/linguaplugin.py b/mako/ext/linguaplugin.py
index 46b0d6a..dda3422 100644
--- a/mako/ext/linguaplugin.py
+++ b/mako/ext/linguaplugin.py
@@ -1,43 +1,51 @@
import io
+
from lingua.extractors import Extractor
-from lingua.extractors import Message
from lingua.extractors import get_extractor
-from mako.ext.extract import MessageExtractor
+from lingua.extractors import Message
+
from mako import compat
+from mako.ext.extract import MessageExtractor
class LinguaMakoExtractor(Extractor, MessageExtractor):
- '''Mako templates'''
- extensions = ['.mako']
- default_config = {
- 'encoding': 'utf-8',
- 'comment-tags': '',
- }
+ """Mako templates"""
+
+ extensions = [".mako"]
+ default_config = {"encoding": "utf-8", "comment-tags": ""}
def __call__(self, filename, options, fileobj=None):
self.options = options
self.filename = filename
- self.python_extractor = get_extractor('x.py')
+ self.python_extractor = get_extractor("x.py")
if fileobj is None:
- fileobj = open(filename, 'rb')
+ fileobj = open(filename, "rb")
return self.process_file(fileobj)
def process_python(self, code, code_lineno, translator_strings):
source = code.getvalue().strip()
- if source.endswith(compat.b(':')):
- if source in (compat.b('try:'), compat.b('else:')) or source.startswith(compat.b('except')):
- source = compat.b('') # Ignore try/except and else
- elif source.startswith(compat.b('elif')):
- source = source[2:] # Replace "elif" with "if"
- source += compat.b('pass')
+ if source.endswith(compat.b(":")):
+ if source in (
+ compat.b("try:"),
+ compat.b("else:"),
+ ) or source.startswith(compat.b("except")):
+ source = compat.b("") # Ignore try/except and else
+ elif source.startswith(compat.b("elif")):
+ source = source[2:] # Replace "elif" with "if"
+ source += compat.b("pass")
code = io.BytesIO(source)
for msg in self.python_extractor(
- self.filename, self.options, code, code_lineno -1):
+ self.filename, self.options, code, code_lineno - 1
+ ):
if translator_strings:
- msg = Message(msg.msgctxt, msg.msgid, msg.msgid_plural,
- msg.flags,
- compat.u(' ').join(
- translator_strings + [msg.comment]),
- msg.tcomment, msg.location)
+ msg = Message(
+ msg.msgctxt,
+ msg.msgid,
+ msg.msgid_plural,
+ msg.flags,
+ compat.u(" ").join(translator_strings + [msg.comment]),
+ msg.tcomment,
+ msg.location,
+ )
yield msg
diff --git a/mako/ext/preprocessors.py b/mako/ext/preprocessors.py
index 9b700d1..524b87f 100644
--- a/mako/ext/preprocessors.py
+++ b/mako/ext/preprocessors.py
@@ -17,4 +17,4 @@ def convert_comments(text):
from mako.ext.preprocessors import convert_comments
t = Template(..., preprocessor=convert_comments)"""
- return re.sub(r'(?<=\n)\s*#[^#]', "##", text)
+ return re.sub(r"(?<=\n)\s*#[^#]", "##", text)
diff --git a/mako/ext/pygmentplugin.py b/mako/ext/pygmentplugin.py
index 4057caa..809e696 100644
--- a/mako/ext/pygmentplugin.py
+++ b/mako/ext/pygmentplugin.py
@@ -4,42 +4,70 @@
# This module is part of Mako and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php
-from pygments.lexers.web import \
- HtmlLexer, XmlLexer, JavascriptLexer, CssLexer
-from pygments.lexers.agile import PythonLexer, Python3Lexer
-from pygments.lexer import DelegatingLexer, RegexLexer, bygroups, \
- include, using
-from pygments.token import \
- Text, Comment, Operator, Keyword, Name, String, Other
-from pygments.formatters.html import HtmlFormatter
from pygments import highlight
+from pygments.formatters.html import HtmlFormatter
+from pygments.lexer import bygroups
+from pygments.lexer import DelegatingLexer
+from pygments.lexer import include
+from pygments.lexer import RegexLexer
+from pygments.lexer import using
+from pygments.lexers.agile import Python3Lexer
+from pygments.lexers.agile import PythonLexer
+from pygments.lexers.web import CssLexer
+from pygments.lexers.web import HtmlLexer
+from pygments.lexers.web import JavascriptLexer
+from pygments.lexers.web import XmlLexer
+from pygments.token import Comment
+from pygments.token import Keyword
+from pygments.token import Name
+from pygments.token import Operator
+from pygments.token import Other
+from pygments.token import String
+from pygments.token import Text
+
from mako import compat
class MakoLexer(RegexLexer):
- name = 'Mako'
- aliases = ['mako']
- filenames = ['*.mao']
+ name = "Mako"
+ aliases = ["mako"]
+ filenames = ["*.mao"]
tokens = {
- 'root': [
- (r'(\s*)(\%)(\s*end(?:\w+))(\n|\Z)',
- bygroups(Text, Comment.Preproc, Keyword, Other)),
- (r'(\s*)(\%(?!%))([^\n]*)(\n|\Z)',
- bygroups(Text, Comment.Preproc, using(PythonLexer), Other)),
- (r'(\s*)(##[^\n]*)(\n|\Z)',
- bygroups(Text, Comment.Preproc, Other)),
- (r'''(?s)<%doc>.*?</%doc>''', Comment.Preproc),
- (r'(<%)([\w\.\:]+)',
- bygroups(Comment.Preproc, Name.Builtin), 'tag'),
- (r'(</%)([\w\.\:]+)(>)',
- bygroups(Comment.Preproc, Name.Builtin, Comment.Preproc)),
- (r'<%(?=([\w\.\:]+))', Comment.Preproc, 'ondeftags'),
- (r'(<%(?:!?))(.*?)(%>)(?s)',
- bygroups(Comment.Preproc, using(PythonLexer), Comment.Preproc)),
- (r'(\$\{)(.*?)(\})',
- bygroups(Comment.Preproc, using(PythonLexer), Comment.Preproc)),
- (r'''(?sx)
+ "root": [
+ (
+ r"(\s*)(\%)(\s*end(?:\w+))(\n|\Z)",
+ bygroups(Text, Comment.Preproc, Keyword, Other),
+ ),
+ (
+ r"(\s*)(\%(?!%))([^\n]*)(\n|\Z)",
+ bygroups(Text, Comment.Preproc, using(PythonLexer), Other),
+ ),
+ (
+ r"(\s*)(##[^\n]*)(\n|\Z)",
+ bygroups(Text, Comment.Preproc, Other),
+ ),
+ (r"""(?s)<%doc>.*?</%doc>""", Comment.Preproc),
+ (
+ r"(<%)([\w\.\:]+)",
+ bygroups(Comment.Preproc, Name.Builtin),
+ "tag",
+ ),
+ (
+ r"(</%)([\w\.\:]+)(>)",
+ bygroups(Comment.Preproc, Name.Builtin, Comment.Preproc),
+ ),
+ (r"<%(?=([\w\.\:]+))", Comment.Preproc, "ondeftags"),
+ (
+ r"(<%(?:!?))(.*?)(%>)(?s)",
+ bygroups(Comment.Preproc, using(PythonLexer), Comment.Preproc),
+ ),
+ (
+ r"(\$\{)(.*?)(\})",
+ bygroups(Comment.Preproc, using(PythonLexer), Comment.Preproc),
+ ),
+ (
+ r"""(?sx)
(.+?) # anything, followed by:
(?:
(?<=\n)(?=%(?!%)|\#\#) | # an eval or comment line
@@ -52,76 +80,78 @@ class MakoLexer(RegexLexer):
(\\\n) | # an escaped newline
\Z # end of string
)
- ''', bygroups(Other, Operator)),
- (r'\s+', Text),
+ """,
+ bygroups(Other, Operator),
+ ),
+ (r"\s+", Text),
],
- 'ondeftags': [
- (r'<%', Comment.Preproc),
- (r'(?<=<%)(include|inherit|namespace|page)', Name.Builtin),
- include('tag'),
+ "ondeftags": [
+ (r"<%", Comment.Preproc),
+ (r"(?<=<%)(include|inherit|namespace|page)", Name.Builtin),
+ include("tag"),
],
- 'tag': [
- (r'((?:\w+)\s*=)\s*(".*?")',
- bygroups(Name.Attribute, String)),
- (r'/?\s*>', Comment.Preproc, '#pop'),
- (r'\s+', Text),
+ "tag": [
+ (r'((?:\w+)\s*=)\s*(".*?")', bygroups(Name.Attribute, String)),
+ (r"/?\s*>", Comment.Preproc, "#pop"),
+ (r"\s+", Text),
],
- 'attr': [
- ('".*?"', String, '#pop'),
- ("'.*?'", String, '#pop'),
- (r'[^\s>]+', String, '#pop'),
+ "attr": [
+ ('".*?"', String, "#pop"),
+ ("'.*?'", String, "#pop"),
+ (r"[^\s>]+", String, "#pop"),
],
}
class MakoHtmlLexer(DelegatingLexer):
- name = 'HTML+Mako'
- aliases = ['html+mako']
+ name = "HTML+Mako"
+ aliases = ["html+mako"]
def __init__(self, **options):
- super(MakoHtmlLexer, self).__init__(HtmlLexer, MakoLexer,
- **options)
+ super(MakoHtmlLexer, self).__init__(HtmlLexer, MakoLexer, **options)
class MakoXmlLexer(DelegatingLexer):
- name = 'XML+Mako'
- aliases = ['xml+mako']
+ name = "XML+Mako"
+ aliases = ["xml+mako"]
def __init__(self, **options):
- super(MakoXmlLexer, self).__init__(XmlLexer, MakoLexer,
- **options)
+ super(MakoXmlLexer, self).__init__(XmlLexer, MakoLexer, **options)
class MakoJavascriptLexer(DelegatingLexer):
- name = 'JavaScript+Mako'
- aliases = ['js+mako', 'javascript+mako']
+ name = "JavaScript+Mako"
+ aliases = ["js+mako", "javascript+mako"]
def __init__(self, **options):
- super(MakoJavascriptLexer, self).__init__(JavascriptLexer,
- MakoLexer, **options)
+ super(MakoJavascriptLexer, self).__init__(
+ JavascriptLexer, MakoLexer, **options
+ )
class MakoCssLexer(DelegatingLexer):
- name = 'CSS+Mako'
- aliases = ['css+mako']
+ name = "CSS+Mako"
+ aliases = ["css+mako"]
def __init__(self, **options):
- super(MakoCssLexer, self).__init__(CssLexer, MakoLexer,
- **options)
+ super(MakoCssLexer, self).__init__(CssLexer, MakoLexer, **options)
-pygments_html_formatter = HtmlFormatter(cssclass='syntax-highlighted',
- linenos=True)
+pygments_html_formatter = HtmlFormatter(
+ cssclass="syntax-highlighted", linenos=True
+)
-def syntax_highlight(filename='', language=None):
+def syntax_highlight(filename="", language=None):
mako_lexer = MakoLexer()
if compat.py3k:
python_lexer = Python3Lexer()
else:
python_lexer = PythonLexer()
- if filename.startswith('memory:') or language == 'mako':
- return lambda string: highlight(string, mako_lexer,
- pygments_html_formatter)
- return lambda string: highlight(string, python_lexer,
- pygments_html_formatter)
+ if filename.startswith("memory:") or language == "mako":
+ return lambda string: highlight(
+ string, mako_lexer, pygments_html_formatter
+ )
+ return lambda string: highlight(
+ string, python_lexer, pygments_html_formatter
+ )
diff --git a/mako/ext/turbogears.py b/mako/ext/turbogears.py
index eaa2d78..ee1147d 100644
--- a/mako/ext/turbogears.py
+++ b/mako/ext/turbogears.py
@@ -13,7 +13,7 @@ class TGPlugin(object):
"""TurboGears compatible Template Plugin."""
- def __init__(self, extra_vars_func=None, options=None, extension='mak'):
+ def __init__(self, extra_vars_func=None, options=None, extension="mak"):
self.extra_vars_func = extra_vars_func
self.extension = extension
if not options:
@@ -22,9 +22,9 @@ class TGPlugin(object):
# Pull the options out and initialize the lookup
lookup_options = {}
for k, v in options.items():
- if k.startswith('mako.'):
+ if k.startswith("mako."):
lookup_options[k[5:]] = v
- elif k in ['directories', 'filesystem_checks', 'module_directory']:
+ elif k in ["directories", "filesystem_checks", "module_directory"]:
lookup_options[k] = v
self.lookup = TemplateLookup(**lookup_options)
@@ -40,14 +40,17 @@ class TGPlugin(object):
if template_string is not None:
return Template(template_string, **self.tmpl_options)
# Translate TG dot notation to normal / template path
- if '/' not in templatename:
- templatename = '/' + templatename.replace('.', '/') + '.' +\
- self.extension
+ if "/" not in templatename:
+ templatename = (
+ "/" + templatename.replace(".", "/") + "." + self.extension
+ )
# Lookup template
return self.lookup.get_template(templatename)
- def render(self, info, format="html", fragment=False, template=None):
+ def render(
+ self, info, format="html", fragment=False, template=None # noqa
+ ):
if isinstance(template, compat.string_types):
template = self.load_template(template)
diff --git a/mako/filters.py b/mako/filters.py
index c082690..56d1d73 100644
--- a/mako/filters.py
+++ b/mako/filters.py
@@ -5,20 +5,21 @@
# the MIT License: http://www.opensource.org/licenses/mit-license.php
-import re
import codecs
-
-from mako.compat import quote_plus, unquote_plus, codepoint2name, \
- name2codepoint
+import re
from mako import compat
+from mako.compat import codepoint2name
+from mako.compat import name2codepoint
+from mako.compat import quote_plus
+from mako.compat import unquote_plus
xml_escapes = {
- '&': '&amp;',
- '>': '&gt;',
- '<': '&lt;',
- '"': '&#34;', # also &quot; in html-only
- "'": '&#39;' # also &apos; in html-only
+ "&": "&amp;",
+ ">": "&gt;",
+ "<": "&lt;",
+ '"': "&#34;", # also &quot; in html-only
+ "'": "&#39;", # also &apos; in html-only
}
# XXX: &quot; is valid in HTML and XML
@@ -37,6 +38,7 @@ def legacy_html_escape(s):
try:
import markupsafe
+
html_escape = markupsafe.escape
except ImportError:
html_escape = legacy_html_escape
@@ -69,7 +71,6 @@ def trim(string):
class Decode(object):
-
def __getattr__(self, key):
def decode(x):
if isinstance(x, compat.text_type):
@@ -78,24 +79,31 @@ class Decode(object):
return decode(str(x))
else:
return compat.text_type(x, encoding=key)
+
return decode
+
+
decode = Decode()
-_ASCII_re = re.compile(r'\A[\x00-\x7f]*\Z')
+_ASCII_re = re.compile(r"\A[\x00-\x7f]*\Z")
def is_ascii_str(text):
return isinstance(text, str) and _ASCII_re.match(text)
+
################################################################
class XMLEntityEscaper(object):
-
def __init__(self, codepoint2name, name2codepoint):
- self.codepoint2entity = dict([(c, compat.text_type('&%s;' % n))
- for c, n in codepoint2name.items()])
+ self.codepoint2entity = dict(
+ [
+ (c, compat.text_type("&%s;" % n))
+ for c, n in codepoint2name.items()
+ ]
+ )
self.name2codepoint = name2codepoint
def escape_entities(self, text):
@@ -110,7 +118,7 @@ class XMLEntityEscaper(object):
try:
return self.codepoint2entity[codepoint]
except (KeyError, IndexError):
- return '&#x%X;' % codepoint
+ return "&#x%X;" % codepoint
__escapable = re.compile(r'["&<>]|[^\x00-\x7f]')
@@ -123,19 +131,22 @@ class XMLEntityEscaper(object):
The return value is guaranteed to be ASCII.
"""
- return self.__escapable.sub(self.__escape, compat.text_type(text)
- ).encode('ascii')
+ return self.__escapable.sub(
+ self.__escape, compat.text_type(text)
+ ).encode("ascii")
# XXX: This regexp will not match all valid XML entity names__.
# (It punts on details involving involving CombiningChars and Extenders.)
#
# .. __: http://www.w3.org/TR/2000/REC-xml-20001006#NT-EntityRef
- __characterrefs = re.compile(r'''& (?:
+ __characterrefs = re.compile(
+ r"""& (?:
\#(\d+)
| \#x([\da-f]+)
| ( (?!\d) [:\w] [-.:\w]+ )
- ) ;''',
- re.X | re.UNICODE)
+ ) ;""",
+ re.X | re.UNICODE,
+ )
def __unescape(self, m):
dval, hval, name = m.groups()
@@ -144,7 +155,7 @@ class XMLEntityEscaper(object):
elif hval:
codepoint = int(hval, 16)
else:
- codepoint = self.name2codepoint.get(name, 0xfffd)
+ codepoint = self.name2codepoint.get(name, 0xFFFD)
# U+FFFD = "REPLACEMENT CHARACTER"
if codepoint < 128:
return chr(codepoint)
@@ -168,42 +179,41 @@ html_entities_unescape = _html_entities_escaper.unescape
def htmlentityreplace_errors(ex):
"""An encoding error handler.
- This python `codecs`_ error handler replaces unencodable
+ This python codecs error handler replaces unencodable
characters with HTML entities, or, if no HTML entity exists for
- the character, XML character references.
+ the character, XML character references::
- >>> u'The cost was \u20ac12.'.encode('latin1', 'htmlentityreplace')
- 'The cost was &euro;12.'
+ >>> u'The cost was \u20ac12.'.encode('latin1', 'htmlentityreplace')
+ 'The cost was &euro;12.'
"""
if isinstance(ex, UnicodeEncodeError):
# Handle encoding errors
- bad_text = ex.object[ex.start:ex.end]
+ bad_text = ex.object[ex.start : ex.end]
text = _html_entities_escaper.escape(bad_text)
return (compat.text_type(text), ex.end)
raise ex
-codecs.register_error('htmlentityreplace', htmlentityreplace_errors)
+
+codecs.register_error("htmlentityreplace", htmlentityreplace_errors)
# TODO: options to make this dynamic per-compilation will be added in a later
# release
DEFAULT_ESCAPES = {
- 'x': 'filters.xml_escape',
- 'h': 'filters.html_escape',
- 'u': 'filters.url_escape',
- 'trim': 'filters.trim',
- 'entity': 'filters.html_entities_escape',
- 'unicode': 'unicode',
- 'decode': 'decode',
- 'str': 'str',
- 'n': 'n'
+ "x": "filters.xml_escape",
+ "h": "filters.html_escape",
+ "u": "filters.url_escape",
+ "trim": "filters.trim",
+ "entity": "filters.html_entities_escape",
+ "unicode": "unicode",
+ "decode": "decode",
+ "str": "str",
+ "n": "n",
}
if compat.py3k:
- DEFAULT_ESCAPES.update({
- 'unicode': 'str'
- })
+ DEFAULT_ESCAPES.update({"unicode": "str"})
NON_UNICODE_ESCAPES = DEFAULT_ESCAPES.copy()
-NON_UNICODE_ESCAPES['h'] = 'filters.legacy_html_escape'
-NON_UNICODE_ESCAPES['u'] = 'filters.legacy_url_escape'
+NON_UNICODE_ESCAPES["h"] = "filters.legacy_html_escape"
+NON_UNICODE_ESCAPES["u"] = "filters.legacy_url_escape"
diff --git a/mako/lexer.py b/mako/lexer.py
index cf4187f..e11a949 100644
--- a/mako/lexer.py
+++ b/mako/lexer.py
@@ -6,19 +6,26 @@
"""provides the Lexer class for parsing template strings into parse trees."""
-import re
import codecs
-from mako import parsetree, exceptions, compat
+import re
+
+from mako import compat
+from mako import exceptions
+from mako import parsetree
from mako.pygen import adjust_whitespace
_regexp_cache = {}
class Lexer(object):
-
- def __init__(self, text, filename=None,
- disable_unicode=False,
- input_encoding=None, preprocessor=None):
+ def __init__(
+ self,
+ text,
+ filename=None,
+ disable_unicode=False,
+ input_encoding=None,
+ preprocessor=None,
+ ):
self.text = text
self.filename = filename
self.template = parsetree.TemplateNode(self.filename)
@@ -34,22 +41,24 @@ class Lexer(object):
if compat.py3k and disable_unicode:
raise exceptions.UnsupportedError(
- "Mako for Python 3 does not "
- "support disabling Unicode")
+ "Mako for Python 3 does not " "support disabling Unicode"
+ )
if preprocessor is None:
self.preprocessor = []
- elif not hasattr(preprocessor, '__iter__'):
+ elif not hasattr(preprocessor, "__iter__"):
self.preprocessor = [preprocessor]
else:
self.preprocessor = preprocessor
@property
def exception_kwargs(self):
- return {'source': self.text,
- 'lineno': self.matched_lineno,
- 'pos': self.matched_charpos,
- 'filename': self.filename}
+ return {
+ "source": self.text,
+ "lineno": self.matched_lineno,
+ "pos": self.matched_charpos,
+ "filename": self.filename,
+ }
def match(self, regexp, flags=None):
"""compile the given regexp, cache the reg, and call match_reg()."""
@@ -83,9 +92,9 @@ class Lexer(object):
else:
self.match_position = end
self.matched_lineno = self.lineno
- lines = re.findall(r"\n", self.text[mp:self.match_position])
+ lines = re.findall(r"\n", self.text[mp : self.match_position])
cp = mp - 1
- while (cp >= 0 and cp < self.textlength and self.text[cp] != '\n'):
+ while cp >= 0 and cp < self.textlength and self.text[cp] != "\n":
cp -= 1
self.matched_charpos = mp - cp
self.lineno += len(lines)
@@ -97,46 +106,49 @@ class Lexer(object):
def parse_until_text(self, watch_nesting, *text):
startpos = self.match_position
- text_re = r'|'.join(text)
+ text_re = r"|".join(text)
brace_level = 0
paren_level = 0
bracket_level = 0
while True:
- match = self.match(r'#.*\n')
+ match = self.match(r"#.*\n")
if match:
continue
- match = self.match(r'(\"\"\"|\'\'\'|\"|\')[^\\]*?(\\.[^\\]*?)*\1',
- re.S)
+ match = self.match(
+ r"(\"\"\"|\'\'\'|\"|\')[^\\]*?(\\.[^\\]*?)*\1", re.S
+ )
if match:
continue
- match = self.match(r'(%s)' % text_re)
- if match and not (watch_nesting
- and (brace_level > 0 or paren_level > 0
- or bracket_level > 0)):
- return \
- self.text[startpos:
- self.match_position - len(match.group(1))],\
- match.group(1)
+ match = self.match(r"(%s)" % text_re)
+ if match and not (
+ watch_nesting
+ and (brace_level > 0 or paren_level > 0 or bracket_level > 0)
+ ):
+ return (
+ self.text[
+ startpos : self.match_position - len(match.group(1))
+ ],
+ match.group(1),
+ )
elif not match:
match = self.match(r"(.*?)(?=\"|\'|#|%s)" % text_re, re.S)
if match:
- brace_level += match.group(1).count('{')
- brace_level -= match.group(1).count('}')
- paren_level += match.group(1).count('(')
- paren_level -= match.group(1).count(')')
- bracket_level += match.group(1).count('[')
- bracket_level -= match.group(1).count(']')
+ brace_level += match.group(1).count("{")
+ brace_level -= match.group(1).count("}")
+ paren_level += match.group(1).count("(")
+ paren_level -= match.group(1).count(")")
+ bracket_level += match.group(1).count("[")
+ bracket_level -= match.group(1).count("]")
continue
raise exceptions.SyntaxException(
- "Expected: %s" %
- ','.join(text),
- **self.exception_kwargs)
+ "Expected: %s" % ",".join(text), **self.exception_kwargs
+ )
def append_node(self, nodecls, *args, **kwargs):
- kwargs.setdefault('source', self.text)
- kwargs.setdefault('lineno', self.matched_lineno)
- kwargs.setdefault('pos', self.matched_charpos)
- kwargs['filename'] = self.filename
+ kwargs.setdefault("source", self.text)
+ kwargs.setdefault("lineno", self.matched_lineno)
+ kwargs.setdefault("pos", self.matched_charpos)
+ kwargs["filename"] = self.filename
node = nodecls(*args, **kwargs)
if len(self.tag):
self.tag[-1].nodes.append(node)
@@ -149,8 +161,10 @@ class Lexer(object):
if self.control_line:
control_frame = self.control_line[-1]
control_frame.nodes.append(node)
- if not (isinstance(node, parsetree.ControlLine) and
- control_frame.is_ternary(node.keyword)):
+ if not (
+ isinstance(node, parsetree.ControlLine)
+ and control_frame.is_ternary(node.keyword)
+ ):
if self.ternary_stack and self.ternary_stack[-1]:
self.ternary_stack[-1][-1].nodes.append(node)
if isinstance(node, parsetree.Tag):
@@ -164,17 +178,20 @@ class Lexer(object):
elif node.is_primary:
self.control_line.append(node)
self.ternary_stack.append([])
- elif self.control_line and \
- self.control_line[-1].is_ternary(node.keyword):
+ elif self.control_line and self.control_line[-1].is_ternary(
+ node.keyword
+ ):
self.ternary_stack[-1].append(node)
- elif self.control_line and \
- not self.control_line[-1].is_ternary(node.keyword):
+ elif self.control_line and not self.control_line[-1].is_ternary(
+ node.keyword
+ ):
raise exceptions.SyntaxException(
- "Keyword '%s' not a legal ternary for keyword '%s'" %
- (node.keyword, self.control_line[-1].keyword),
- **self.exception_kwargs)
+ "Keyword '%s' not a legal ternary for keyword '%s'"
+ % (node.keyword, self.control_line[-1].keyword),
+ **self.exception_kwargs
+ )
- _coding_re = re.compile(r'#.*coding[:=]\s*([-\w.]+).*\r?\n')
+ _coding_re = re.compile(r"#.*coding[:=]\s*([-\w.]+).*\r?\n")
def decode_raw_stream(self, text, decode_raw, known_encoding, filename):
"""given string/unicode or bytes/string, determine encoding
@@ -184,44 +201,48 @@ class Lexer(object):
"""
if isinstance(text, compat.text_type):
m = self._coding_re.match(text)
- encoding = m and m.group(1) or known_encoding or 'ascii'
+ encoding = m and m.group(1) or known_encoding or "ascii"
return encoding, text
if text.startswith(codecs.BOM_UTF8):
- text = text[len(codecs.BOM_UTF8):]
- parsed_encoding = 'utf-8'
- m = self._coding_re.match(text.decode('utf-8', 'ignore'))
- if m is not None and m.group(1) != 'utf-8':
+ text = text[len(codecs.BOM_UTF8) :]
+ parsed_encoding = "utf-8"
+ m = self._coding_re.match(text.decode("utf-8", "ignore"))
+ if m is not None and m.group(1) != "utf-8":
raise exceptions.CompileException(
"Found utf-8 BOM in file, with conflicting "
"magic encoding comment of '%s'" % m.group(1),
- text.decode('utf-8', 'ignore'),
- 0, 0, filename)
+ text.decode("utf-8", "ignore"),
+ 0,
+ 0,
+ filename,
+ )
else:
- m = self._coding_re.match(text.decode('utf-8', 'ignore'))
+ m = self._coding_re.match(text.decode("utf-8", "ignore"))
if m:
parsed_encoding = m.group(1)
else:
- parsed_encoding = known_encoding or 'ascii'
+ parsed_encoding = known_encoding or "ascii"
if decode_raw:
try:
text = text.decode(parsed_encoding)
except UnicodeDecodeError:
raise exceptions.CompileException(
- "Unicode decode operation of encoding '%s' failed" %
- parsed_encoding,
- text.decode('utf-8', 'ignore'),
- 0, 0, filename)
+ "Unicode decode operation of encoding '%s' failed"
+ % parsed_encoding,
+ text.decode("utf-8", "ignore"),
+ 0,
+ 0,
+ filename,
+ )
return parsed_encoding, text
def parse(self):
self.encoding, self.text = self.decode_raw_stream(
- self.text,
- not self.disable_unicode,
- self.encoding,
- self.filename)
+ self.text, not self.disable_unicode, self.encoding, self.filename
+ )
for preproc in self.preprocessor:
self.text = preproc(self.text)
@@ -232,7 +253,7 @@ class Lexer(object):
self.textlength = len(self.text)
- while (True):
+ while True:
if self.match_position > self.textlength:
break
@@ -258,20 +279,24 @@ class Lexer(object):
raise exceptions.CompileException("assertion failed")
if len(self.tag):
- raise exceptions.SyntaxException("Unclosed tag: <%%%s>" %
- self.tag[-1].keyword,
- **self.exception_kwargs)
+ raise exceptions.SyntaxException(
+ "Unclosed tag: <%%%s>" % self.tag[-1].keyword,
+ **self.exception_kwargs
+ )
if len(self.control_line):
raise exceptions.SyntaxException(
- "Unterminated control keyword: '%s'" %
- self.control_line[-1].keyword,
+ "Unterminated control keyword: '%s'"
+ % self.control_line[-1].keyword,
self.text,
self.control_line[-1].lineno,
- self.control_line[-1].pos, self.filename)
+ self.control_line[-1].pos,
+ self.filename,
+ )
return self.template
def match_tag_start(self):
- match = self.match(r'''
+ match = self.match(
+ r"""
\<% # opening tag
([\w\.\:]+) # keyword
@@ -283,9 +308,9 @@ class Lexer(object):
(/)?> # closing
- ''',
-
- re.I | re.S | re.X)
+ """,
+ re.I | re.S | re.X,
+ )
if match:
keyword, attr, isend = match.groups()
@@ -293,22 +318,23 @@ class Lexer(object):
attributes = {}
if attr:
for att in re.findall(
- r"\s*(\w+)\s*=\s*(?:'([^']*)'|\"([^\"]*)\")", attr):
+ r"\s*(\w+)\s*=\s*(?:'([^']*)'|\"([^\"]*)\")", attr
+ ):
key, val1, val2 = att
text = val1 or val2
- text = text.replace('\r\n', '\n')
+ text = text.replace("\r\n", "\n")
attributes[key] = text
self.append_node(parsetree.Tag, keyword, attributes)
if isend:
self.tag.pop()
else:
- if keyword == 'text':
- match = self.match(r'(.*?)(?=\</%text>)', re.S)
+ if keyword == "text":
+ match = self.match(r"(.*?)(?=\</%text>)", re.S)
if not match:
raise exceptions.SyntaxException(
- "Unclosed tag: <%%%s>" %
- self.tag[-1].keyword,
- **self.exception_kwargs)
+ "Unclosed tag: <%%%s>" % self.tag[-1].keyword,
+ **self.exception_kwargs
+ )
self.append_node(parsetree.Text, match.group(1))
return self.match_tag_end()
return True
@@ -316,25 +342,27 @@ class Lexer(object):
return False
def match_tag_end(self):
- match = self.match(r'\</%[\t ]*(.+?)[\t ]*>')
+ match = self.match(r"\</%[\t ]*(.+?)[\t ]*>")
if match:
if not len(self.tag):
raise exceptions.SyntaxException(
- "Closing tag without opening tag: </%%%s>" %
- match.group(1),
- **self.exception_kwargs)
+ "Closing tag without opening tag: </%%%s>"
+ % match.group(1),
+ **self.exception_kwargs
+ )
elif self.tag[-1].keyword != match.group(1):
raise exceptions.SyntaxException(
- "Closing tag </%%%s> does not match tag: <%%%s>" %
- (match.group(1), self.tag[-1].keyword),
- **self.exception_kwargs)
+ "Closing tag </%%%s> does not match tag: <%%%s>"
+ % (match.group(1), self.tag[-1].keyword),
+ **self.exception_kwargs
+ )
self.tag.pop()
return True
else:
return False
def match_end(self):
- match = self.match(r'\Z', re.S)
+ match = self.match(r"\Z", re.S)
if match:
string = match.group()
if string:
@@ -345,7 +373,8 @@ class Lexer(object):
return False
def match_text(self):
- match = self.match(r"""
+ match = self.match(
+ r"""
(.*?) # anything, followed by:
(
(?<=\n)(?=[ \t]*(?=%|\#\#)) # an eval or line-based
@@ -360,7 +389,9 @@ class Lexer(object):
(\\\r?\n) # an escaped newline - throw away
|
\Z # end of string
- )""", re.X | re.S)
+ )""",
+ re.X | re.S,
+ )
if match:
text = match.group(1)
@@ -374,14 +405,17 @@ class Lexer(object):
match = self.match(r"<%(!)?")
if match:
line, pos = self.matched_lineno, self.matched_charpos
- text, end = self.parse_until_text(False, r'%>')
+ text, end = self.parse_until_text(False, r"%>")
# the trailing newline helps
# compiler.parse() not complain about indentation
text = adjust_whitespace(text) + "\n"
self.append_node(
parsetree.Code,
text,
- match.group(1) == '!', lineno=line, pos=pos)
+ match.group(1) == "!",
+ lineno=line,
+ pos=pos,
+ )
return True
else:
return False
@@ -390,16 +424,19 @@ class Lexer(object):
match = self.match(r"\${")
if match:
line, pos = self.matched_lineno, self.matched_charpos
- text, end = self.parse_until_text(True, r'\|', r'}')
- if end == '|':
- escapes, end = self.parse_until_text(True, r'}')
+ text, end = self.parse_until_text(True, r"\|", r"}")
+ if end == "|":
+ escapes, end = self.parse_until_text(True, r"}")
else:
escapes = ""
- text = text.replace('\r\n', '\n')
+ text = text.replace("\r\n", "\n")
self.append_node(
parsetree.Expression,
- text, escapes.strip(),
- lineno=line, pos=pos)
+ text,
+ escapes.strip(),
+ lineno=line,
+ pos=pos,
+ )
return True
else:
return False
@@ -407,31 +444,35 @@ class Lexer(object):
def match_control_line(self):
match = self.match(
r"(?<=^)[\t ]*(%(?!%)|##)[\t ]*((?:(?:\\r?\n)|[^\r\n])*)"
- r"(?:\r?\n|\Z)", re.M)
+ r"(?:\r?\n|\Z)",
+ re.M,
+ )
if match:
operator = match.group(1)
text = match.group(2)
- if operator == '%':
- m2 = re.match(r'(end)?(\w+)\s*(.*)', text)
+ if operator == "%":
+ m2 = re.match(r"(end)?(\w+)\s*(.*)", text)
if not m2:
raise exceptions.SyntaxException(
- "Invalid control line: '%s'" %
- text,
- **self.exception_kwargs)
+ "Invalid control line: '%s'" % text,
+ **self.exception_kwargs
+ )
isend, keyword = m2.group(1, 2)
- isend = (isend is not None)
+ isend = isend is not None
if isend:
if not len(self.control_line):
raise exceptions.SyntaxException(
- "No starting keyword '%s' for '%s'" %
- (keyword, text),
- **self.exception_kwargs)
+ "No starting keyword '%s' for '%s'"
+ % (keyword, text),
+ **self.exception_kwargs
+ )
elif self.control_line[-1].keyword != keyword:
raise exceptions.SyntaxException(
- "Keyword '%s' doesn't match keyword '%s'" %
- (text, self.control_line[-1].keyword),
- **self.exception_kwargs)
+ "Keyword '%s' doesn't match keyword '%s'"
+ % (text, self.control_line[-1].keyword),
+ **self.exception_kwargs
+ )
self.append_node(parsetree.ControlLine, keyword, isend, text)
else:
self.append_node(parsetree.Comment, text)
diff --git a/mako/lookup.py b/mako/lookup.py
index 0d3f304..a3010d5 100644
--- a/mako/lookup.py
+++ b/mako/lookup.py
@@ -5,10 +5,12 @@
# the MIT License: http://www.opensource.org/licenses/mit-license.php
import os
-import stat
import posixpath
import re
-from mako import exceptions, util
+import stat
+
+from mako import exceptions
+from mako import util
from mako.template import Template
try:
@@ -151,41 +153,41 @@ class TemplateLookup(TemplateCollection):
"""
- def __init__(self,
- directories=None,
- module_directory=None,
- filesystem_checks=True,
- collection_size=-1,
- format_exceptions=False,
- error_handler=None,
- disable_unicode=False,
- bytestring_passthrough=False,
- output_encoding=None,
- encoding_errors='strict',
-
- cache_args=None,
- cache_impl='beaker',
- cache_enabled=True,
- cache_type=None,
- cache_dir=None,
- cache_url=None,
-
- modulename_callable=None,
- module_writer=None,
- default_filters=None,
- buffer_filters=(),
- strict_undefined=False,
- imports=None,
- future_imports=None,
- enable_loop=True,
- input_encoding=None,
- preprocessor=None,
- lexer_cls=None,
- include_error_handler=None):
-
- self.directories = [posixpath.normpath(d) for d in
- util.to_list(directories, ())
- ]
+ def __init__(
+ self,
+ directories=None,
+ module_directory=None,
+ filesystem_checks=True,
+ collection_size=-1,
+ format_exceptions=False,
+ error_handler=None,
+ disable_unicode=False,
+ bytestring_passthrough=False,
+ output_encoding=None,
+ encoding_errors="strict",
+ cache_args=None,
+ cache_impl="beaker",
+ cache_enabled=True,
+ cache_type=None,
+ cache_dir=None,
+ cache_url=None,
+ modulename_callable=None,
+ module_writer=None,
+ default_filters=None,
+ buffer_filters=(),
+ strict_undefined=False,
+ imports=None,
+ future_imports=None,
+ enable_loop=True,
+ input_encoding=None,
+ preprocessor=None,
+ lexer_cls=None,
+ include_error_handler=None,
+ ):
+
+ self.directories = [
+ posixpath.normpath(d) for d in util.to_list(directories, ())
+ ]
self.module_directory = module_directory
self.modulename_callable = modulename_callable
self.filesystem_checks = filesystem_checks
@@ -195,34 +197,34 @@ class TemplateLookup(TemplateCollection):
cache_args = {}
# transfer deprecated cache_* args
if cache_dir:
- cache_args.setdefault('dir', cache_dir)
+ cache_args.setdefault("dir", cache_dir)
if cache_url:
- cache_args.setdefault('url', cache_url)
+ cache_args.setdefault("url", cache_url)
if cache_type:
- cache_args.setdefault('type', cache_type)
+ cache_args.setdefault("type", cache_type)
self.template_args = {
- 'format_exceptions': format_exceptions,
- 'error_handler': error_handler,
- 'include_error_handler': include_error_handler,
- 'disable_unicode': disable_unicode,
- 'bytestring_passthrough': bytestring_passthrough,
- 'output_encoding': output_encoding,
- 'cache_impl': cache_impl,
- 'encoding_errors': encoding_errors,
- 'input_encoding': input_encoding,
- 'module_directory': module_directory,
- 'module_writer': module_writer,
- 'cache_args': cache_args,
- 'cache_enabled': cache_enabled,
- 'default_filters': default_filters,
- 'buffer_filters': buffer_filters,
- 'strict_undefined': strict_undefined,
- 'imports': imports,
- 'future_imports': future_imports,
- 'enable_loop': enable_loop,
- 'preprocessor': preprocessor,
- 'lexer_cls': lexer_cls
+ "format_exceptions": format_exceptions,
+ "error_handler": error_handler,
+ "include_error_handler": include_error_handler,
+ "disable_unicode": disable_unicode,
+ "bytestring_passthrough": bytestring_passthrough,
+ "output_encoding": output_encoding,
+ "cache_impl": cache_impl,
+ "encoding_errors": encoding_errors,
+ "input_encoding": input_encoding,
+ "module_directory": module_directory,
+ "module_writer": module_writer,
+ "cache_args": cache_args,
+ "cache_enabled": cache_enabled,
+ "default_filters": default_filters,
+ "buffer_filters": buffer_filters,
+ "strict_undefined": strict_undefined,
+ "imports": imports,
+ "future_imports": future_imports,
+ "enable_loop": enable_loop,
+ "preprocessor": preprocessor,
+ "lexer_cls": lexer_cls,
}
if collection_size == -1:
@@ -248,17 +250,18 @@ class TemplateLookup(TemplateCollection):
else:
return self._collection[uri]
except KeyError:
- u = re.sub(r'^\/+', '', uri)
- for dir in self.directories:
+ u = re.sub(r"^\/+", "", uri)
+ for dir_ in self.directories:
# make sure the path seperators are posix - os.altsep is empty
# on POSIX and cannot be used.
- dir = dir.replace(os.path.sep, posixpath.sep)
- srcfile = posixpath.normpath(posixpath.join(dir, u))
+ dir_ = dir_.replace(os.path.sep, posixpath.sep)
+ srcfile = posixpath.normpath(posixpath.join(dir_, u))
if os.path.isfile(srcfile):
return self._load(srcfile, uri)
else:
raise exceptions.TopLevelLookupException(
- "Cant locate template for uri %r" % uri)
+ "Cant locate template for uri %r" % uri
+ )
def adjust_uri(self, uri, relativeto):
"""Adjust the given ``uri`` based on the given relative URI."""
@@ -267,12 +270,13 @@ class TemplateLookup(TemplateCollection):
if key in self._uri_cache:
return self._uri_cache[key]
- if uri[0] != '/':
+ if uri[0] != "/":
if relativeto is not None:
v = self._uri_cache[key] = posixpath.join(
- posixpath.dirname(relativeto), uri)
+ posixpath.dirname(relativeto), uri
+ )
else:
- v = self._uri_cache[key] = '/' + uri
+ v = self._uri_cache[key] = "/" + uri
else:
v = self._uri_cache[key] = uri
return v
@@ -295,9 +299,9 @@ class TemplateLookup(TemplateCollection):
"""
filename = posixpath.normpath(filename)
- for dir in self.directories:
- if filename[0:len(dir)] == dir:
- return filename[len(dir):]
+ for dir_ in self.directories:
+ if filename[0 : len(dir_)] == dir_:
+ return filename[len(dir_) :]
else:
return None
@@ -320,7 +324,8 @@ class TemplateLookup(TemplateCollection):
filename=posixpath.normpath(filename),
lookup=self,
module_filename=module_filename,
- **self.template_args)
+ **self.template_args
+ )
return template
except:
# if compilation fails etc, ensure
@@ -337,8 +342,7 @@ class TemplateLookup(TemplateCollection):
try:
template_stat = os.stat(template.filename)
- if template.module._modified_time < \
- template_stat[stat.ST_MTIME]:
+ if template.module._modified_time < template_stat[stat.ST_MTIME]:
self._collection.pop(uri, None)
return self._load(template.filename, uri)
else:
@@ -346,7 +350,8 @@ class TemplateLookup(TemplateCollection):
except OSError:
self._collection.pop(uri, None)
raise exceptions.TemplateLookupException(
- "Cant locate template for uri %r" % uri)
+ "Cant locate template for uri %r" % uri
+ )
def put_string(self, uri, text):
"""Place a new :class:`.Template` object into this
@@ -355,10 +360,8 @@ class TemplateLookup(TemplateCollection):
"""
self._collection[uri] = Template(
- text,
- lookup=self,
- uri=uri,
- **self.template_args)
+ text, lookup=self, uri=uri, **self.template_args
+ )
def put_template(self, uri, template):
"""Place a new :class:`.Template` object into this
diff --git a/mako/parsetree.py b/mako/parsetree.py
index e129916..7f06667 100644
--- a/mako/parsetree.py
+++ b/mako/parsetree.py
@@ -6,9 +6,14 @@
"""defines the parse tree components for Mako templates."""
-from mako import exceptions, ast, util, filters, compat
import re
+from mako import ast
+from mako import compat
+from mako import exceptions
+from mako import filters
+from mako import util
+
class Node(object):
@@ -22,8 +27,12 @@ class Node(object):
@property
def exception_kwargs(self):
- return {'source': self.source, 'lineno': self.lineno,
- 'pos': self.pos, 'filename': self.filename}
+ return {
+ "source": self.source,
+ "lineno": self.lineno,
+ "pos": self.pos,
+ "filename": self.filename,
+ }
def get_children(self):
return []
@@ -42,7 +51,7 @@ class TemplateNode(Node):
"""a 'container' node that stores the overall collection of nodes."""
def __init__(self, filename):
- super(TemplateNode, self).__init__('', 0, 0, filename)
+ super(TemplateNode, self).__init__("", 0, 0, filename)
self.nodes = []
self.page_attributes = {}
@@ -52,7 +61,8 @@ class TemplateNode(Node):
def __repr__(self):
return "TemplateNode(%s, %r)" % (
util.sorted_dict_repr(self.page_attributes),
- self.nodes)
+ self.nodes,
+ )
class ControlLine(Node):
@@ -74,7 +84,7 @@ class ControlLine(Node):
self.text = text
self.keyword = keyword
self.isend = isend
- self.is_primary = keyword in ['for', 'if', 'while', 'try', 'with']
+ self.is_primary = keyword in ["for", "if", "while", "try", "with"]
self.nodes = []
if self.isend:
self._declared_identifiers = []
@@ -98,9 +108,9 @@ class ControlLine(Node):
for this ControlLine"""
return keyword in {
- 'if': set(['else', 'elif']),
- 'try': set(['except', 'finally']),
- 'for': set(['else'])
+ "if": set(["else", "elif"]),
+ "try": set(["except", "finally"]),
+ "for": set(["else"]),
}.get(self.keyword, [])
def __repr__(self):
@@ -108,7 +118,7 @@ class ControlLine(Node):
self.keyword,
self.text,
self.isend,
- (self.lineno, self.pos)
+ (self.lineno, self.pos),
)
@@ -158,7 +168,7 @@ class Code(Node):
return "Code(%r, %r, %r)" % (
self.text,
self.ismodule,
- (self.lineno, self.pos)
+ (self.lineno, self.pos),
)
@@ -208,7 +218,7 @@ class Expression(Node):
return "Expression(%r, %r, %r)" % (
self.text,
self.escapes_code.args,
- (self.lineno, self.pos)
+ (self.lineno, self.pos),
)
@@ -219,45 +229,55 @@ class _TagMeta(type):
_classmap = {}
- def __init__(cls, clsname, bases, dict):
- if getattr(cls, '__keyword__', None) is not None:
+ def __init__(cls, clsname, bases, dict_):
+ if getattr(cls, "__keyword__", None) is not None:
cls._classmap[cls.__keyword__] = cls
- super(_TagMeta, cls).__init__(clsname, bases, dict)
+ super(_TagMeta, cls).__init__(clsname, bases, dict_)
def __call__(cls, keyword, attributes, **kwargs):
if ":" in keyword:
- ns, defname = keyword.split(':')
- return type.__call__(CallNamespaceTag, ns, defname,
- attributes, **kwargs)
+ ns, defname = keyword.split(":")
+ return type.__call__(
+ CallNamespaceTag, ns, defname, attributes, **kwargs
+ )
try:
cls = _TagMeta._classmap[keyword]
except KeyError:
raise exceptions.CompileException(
"No such tag: '%s'" % keyword,
- source=kwargs['source'],
- lineno=kwargs['lineno'],
- pos=kwargs['pos'],
- filename=kwargs['filename']
+ source=kwargs["source"],
+ lineno=kwargs["lineno"],
+ pos=kwargs["pos"],
+ filename=kwargs["filename"],
)
return type.__call__(cls, keyword, attributes, **kwargs)
class Tag(compat.with_metaclass(_TagMeta, Node)):
-
"""abstract base class for tags.
- <%sometag/>
+ e.g.::
+
+ <%sometag/>
- <%someothertag>
- stuff
- </%someothertag>
+ <%someothertag>
+ stuff
+ </%someothertag>
"""
+
__keyword__ = None
- def __init__(self, keyword, attributes, expressions,
- nonexpressions, required, **kwargs):
+ def __init__(
+ self,
+ keyword,
+ attributes,
+ expressions,
+ nonexpressions,
+ required,
+ **kwargs
+ ):
r"""construct a new Tag instance.
this constructor not called directly, and is only called
@@ -284,9 +304,10 @@ class Tag(compat.with_metaclass(_TagMeta, Node)):
missing = [r for r in required if r not in self.parsed_attributes]
if len(missing):
raise exceptions.CompileException(
- "Missing attribute(s): %s" %
- ",".join([repr(m) for m in missing]),
- **self.exception_kwargs)
+ "Missing attribute(s): %s"
+ % ",".join([repr(m) for m in missing]),
+ **self.exception_kwargs
+ )
self.parent = None
self.nodes = []
@@ -302,36 +323,40 @@ class Tag(compat.with_metaclass(_TagMeta, Node)):
for key in self.attributes:
if key in expressions:
expr = []
- for x in re.compile(r'(\${.+?})',
- re.S).split(self.attributes[key]):
- m = re.compile(r'^\${(.+?)}$', re.S).match(x)
+ for x in re.compile(r"(\${.+?})", re.S).split(
+ self.attributes[key]
+ ):
+ m = re.compile(r"^\${(.+?)}$", re.S).match(x)
if m:
- code = ast.PythonCode(m.group(1).rstrip(),
- **self.exception_kwargs)
+ code = ast.PythonCode(
+ m.group(1).rstrip(), **self.exception_kwargs
+ )
# we aren't discarding "declared_identifiers" here,
# which we do so that list comprehension-declared
# variables aren't counted. As yet can't find a
# condition that requires it here.
- undeclared_identifiers = \
- undeclared_identifiers.union(
- code.undeclared_identifiers)
- expr.append('(%s)' % m.group(1))
+ undeclared_identifiers = undeclared_identifiers.union(
+ code.undeclared_identifiers
+ )
+ expr.append("(%s)" % m.group(1))
else:
if x:
expr.append(repr(x))
- self.parsed_attributes[key] = " + ".join(expr) or repr('')
+ self.parsed_attributes[key] = " + ".join(expr) or repr("")
elif key in nonexpressions:
- if re.search(r'\${.+?}', self.attributes[key]):
+ if re.search(r"\${.+?}", self.attributes[key]):
raise exceptions.CompileException(
"Attibute '%s' in tag '%s' does not allow embedded "
"expressions" % (key, self.keyword),
- **self.exception_kwargs)
+ **self.exception_kwargs
+ )
self.parsed_attributes[key] = repr(self.attributes[key])
else:
raise exceptions.CompileException(
- "Invalid attribute for tag '%s': '%s'" %
- (self.keyword, key),
- **self.exception_kwargs)
+ "Invalid attribute for tag '%s': '%s'"
+ % (self.keyword, key),
+ **self.exception_kwargs
+ )
self.expression_undeclared_identifiers = undeclared_identifiers
def declared_identifiers(self):
@@ -341,56 +366,64 @@ class Tag(compat.with_metaclass(_TagMeta, Node)):
return self.expression_undeclared_identifiers
def __repr__(self):
- return "%s(%r, %s, %r, %r)" % (self.__class__.__name__,
- self.keyword,
- util.sorted_dict_repr(self.attributes),
- (self.lineno, self.pos),
- self.nodes
- )
+ return "%s(%r, %s, %r, %r)" % (
+ self.__class__.__name__,
+ self.keyword,
+ util.sorted_dict_repr(self.attributes),
+ (self.lineno, self.pos),
+ self.nodes,
+ )
class IncludeTag(Tag):
- __keyword__ = 'include'
+ __keyword__ = "include"
def __init__(self, keyword, attributes, **kwargs):
super(IncludeTag, self).__init__(
keyword,
attributes,
- ('file', 'import', 'args'),
- (), ('file',), **kwargs)
+ ("file", "import", "args"),
+ (),
+ ("file",),
+ **kwargs
+ )
self.page_args = ast.PythonCode(
- "__DUMMY(%s)" % attributes.get('args', ''),
- **self.exception_kwargs)
+ "__DUMMY(%s)" % attributes.get("args", ""), **self.exception_kwargs
+ )
def declared_identifiers(self):
return []
def undeclared_identifiers(self):
- identifiers = self.page_args.undeclared_identifiers.\
- difference(set(["__DUMMY"])).\
- difference(self.page_args.declared_identifiers)
- return identifiers.union(super(IncludeTag, self).
- undeclared_identifiers())
+ identifiers = self.page_args.undeclared_identifiers.difference(
+ set(["__DUMMY"])
+ ).difference(self.page_args.declared_identifiers)
+ return identifiers.union(
+ super(IncludeTag, self).undeclared_identifiers()
+ )
class NamespaceTag(Tag):
- __keyword__ = 'namespace'
+ __keyword__ = "namespace"
def __init__(self, keyword, attributes, **kwargs):
super(NamespaceTag, self).__init__(
- keyword, attributes,
- ('file',),
- ('name', 'inheritable',
- 'import', 'module'),
- (), **kwargs)
-
- self.name = attributes.get('name', '__anon_%s' % hex(abs(id(self))))
- if 'name' not in attributes and 'import' not in attributes:
+ keyword,
+ attributes,
+ ("file",),
+ ("name", "inheritable", "import", "module"),
+ (),
+ **kwargs
+ )
+
+ self.name = attributes.get("name", "__anon_%s" % hex(abs(id(self))))
+ if "name" not in attributes and "import" not in attributes:
raise exceptions.CompileException(
"'name' and/or 'import' attributes are required "
"for <%namespace>",
- **self.exception_kwargs)
- if 'file' in attributes and 'module' in attributes:
+ **self.exception_kwargs
+ )
+ if "file" in attributes and "module" in attributes:
raise exceptions.CompileException(
"<%namespace> may only have one of 'file' or 'module'",
**self.exception_kwargs
@@ -401,51 +434,51 @@ class NamespaceTag(Tag):
class TextTag(Tag):
- __keyword__ = 'text'
+ __keyword__ = "text"
def __init__(self, keyword, attributes, **kwargs):
super(TextTag, self).__init__(
- keyword,
- attributes, (),
- ('filter'), (), **kwargs)
+ keyword, attributes, (), ("filter"), (), **kwargs
+ )
self.filter_args = ast.ArgumentList(
- attributes.get('filter', ''),
- **self.exception_kwargs)
+ attributes.get("filter", ""), **self.exception_kwargs
+ )
def undeclared_identifiers(self):
- return self.filter_args.\
- undeclared_identifiers.\
- difference(filters.DEFAULT_ESCAPES.keys()).union(
- self.expression_undeclared_identifiers
- )
+ return self.filter_args.undeclared_identifiers.difference(
+ filters.DEFAULT_ESCAPES.keys()
+ ).union(self.expression_undeclared_identifiers)
class DefTag(Tag):
- __keyword__ = 'def'
+ __keyword__ = "def"
def __init__(self, keyword, attributes, **kwargs):
- expressions = ['buffered', 'cached'] + [
- c for c in attributes if c.startswith('cache_')]
+ expressions = ["buffered", "cached"] + [
+ c for c in attributes if c.startswith("cache_")
+ ]
super(DefTag, self).__init__(
keyword,
attributes,
expressions,
- ('name', 'filter', 'decorator'),
- ('name',),
- **kwargs)
- name = attributes['name']
- if re.match(r'^[\w_]+$', name):
+ ("name", "filter", "decorator"),
+ ("name",),
+ **kwargs
+ )
+ name = attributes["name"]
+ if re.match(r"^[\w_]+$", name):
raise exceptions.CompileException(
- "Missing parenthesis in %def",
- **self.exception_kwargs)
- self.function_decl = ast.FunctionDecl("def " + name + ":pass",
- **self.exception_kwargs)
+ "Missing parenthesis in %def", **self.exception_kwargs
+ )
+ self.function_decl = ast.FunctionDecl(
+ "def " + name + ":pass", **self.exception_kwargs
+ )
self.name = self.function_decl.funcname
- self.decorator = attributes.get('decorator', '')
+ self.decorator = attributes.get("decorator", "")
self.filter_args = ast.ArgumentList(
- attributes.get('filter', ''),
- **self.exception_kwargs)
+ attributes.get("filter", ""), **self.exception_kwargs
+ )
is_anonymous = False
is_block = False
@@ -463,51 +496,58 @@ class DefTag(Tag):
def undeclared_identifiers(self):
res = []
for c in self.function_decl.defaults:
- res += list(ast.PythonCode(c, **self.exception_kwargs).
- undeclared_identifiers)
- return set(res).union(
- self.filter_args.
- undeclared_identifiers.
- difference(filters.DEFAULT_ESCAPES.keys())
- ).union(
- self.expression_undeclared_identifiers
- ).difference(
- self.function_decl.allargnames
+ res += list(
+ ast.PythonCode(
+ c, **self.exception_kwargs
+ ).undeclared_identifiers
+ )
+ return (
+ set(res)
+ .union(
+ self.filter_args.undeclared_identifiers.difference(
+ filters.DEFAULT_ESCAPES.keys()
+ )
+ )
+ .union(self.expression_undeclared_identifiers)
+ .difference(self.function_decl.allargnames)
)
class BlockTag(Tag):
- __keyword__ = 'block'
+ __keyword__ = "block"
def __init__(self, keyword, attributes, **kwargs):
- expressions = ['buffered', 'cached', 'args'] + [
- c for c in attributes if c.startswith('cache_')]
+ expressions = ["buffered", "cached", "args"] + [
+ c for c in attributes if c.startswith("cache_")
+ ]
super(BlockTag, self).__init__(
keyword,
attributes,
expressions,
- ('name', 'filter', 'decorator'),
+ ("name", "filter", "decorator"),
(),
- **kwargs)
- name = attributes.get('name')
- if name and not re.match(r'^[\w_]+$', name):
+ **kwargs
+ )
+ name = attributes.get("name")
+ if name and not re.match(r"^[\w_]+$", name):
raise exceptions.CompileException(
"%block may not specify an argument signature",
- **self.exception_kwargs)
- if not name and attributes.get('args', None):
- raise exceptions.CompileException(
- "Only named %blocks may specify args",
**self.exception_kwargs
)
- self.body_decl = ast.FunctionArgs(attributes.get('args', ''),
- **self.exception_kwargs)
+ if not name and attributes.get("args", None):
+ raise exceptions.CompileException(
+ "Only named %blocks may specify args", **self.exception_kwargs
+ )
+ self.body_decl = ast.FunctionArgs(
+ attributes.get("args", ""), **self.exception_kwargs
+ )
self.name = name
- self.decorator = attributes.get('decorator', '')
+ self.decorator = attributes.get("decorator", "")
self.filter_args = ast.ArgumentList(
- attributes.get('filter', ''),
- **self.exception_kwargs)
+ attributes.get("filter", ""), **self.exception_kwargs
+ )
is_block = True
@@ -517,7 +557,7 @@ class BlockTag(Tag):
@property
def funcname(self):
- return self.name or "__M_anon_%d" % (self.lineno, )
+ return self.name or "__M_anon_%d" % (self.lineno,)
def get_argument_expressions(self, **kw):
return self.body_decl.get_argument_expressions(**kw)
@@ -526,91 +566,100 @@ class BlockTag(Tag):
return self.body_decl.allargnames
def undeclared_identifiers(self):
- return (self.filter_args.
- undeclared_identifiers.
- difference(filters.DEFAULT_ESCAPES.keys())
- ).union(self.expression_undeclared_identifiers)
+ return (
+ self.filter_args.undeclared_identifiers.difference(
+ filters.DEFAULT_ESCAPES.keys()
+ )
+ ).union(self.expression_undeclared_identifiers)
class CallTag(Tag):
- __keyword__ = 'call'
+ __keyword__ = "call"
def __init__(self, keyword, attributes, **kwargs):
- super(CallTag, self).__init__(keyword, attributes,
- ('args'), ('expr',), ('expr',), **kwargs)
- self.expression = attributes['expr']
+ super(CallTag, self).__init__(
+ keyword, attributes, ("args"), ("expr",), ("expr",), **kwargs
+ )
+ self.expression = attributes["expr"]
self.code = ast.PythonCode(self.expression, **self.exception_kwargs)
- self.body_decl = ast.FunctionArgs(attributes.get('args', ''),
- **self.exception_kwargs)
+ self.body_decl = ast.FunctionArgs(
+ attributes.get("args", ""), **self.exception_kwargs
+ )
def declared_identifiers(self):
return self.code.declared_identifiers.union(self.body_decl.allargnames)
def undeclared_identifiers(self):
- return self.code.undeclared_identifiers.\
- difference(self.code.declared_identifiers)
+ return self.code.undeclared_identifiers.difference(
+ self.code.declared_identifiers
+ )
class CallNamespaceTag(Tag):
-
def __init__(self, namespace, defname, attributes, **kwargs):
super(CallNamespaceTag, self).__init__(
namespace + ":" + defname,
attributes,
- tuple(attributes.keys()) + ('args', ),
+ tuple(attributes.keys()) + ("args",),
(),
(),
- **kwargs)
+ **kwargs
+ )
self.expression = "%s.%s(%s)" % (
namespace,
defname,
- ",".join(["%s=%s" % (k, v) for k, v in
- self.parsed_attributes.items()
- if k != 'args'])
+ ",".join(
+ [
+ "%s=%s" % (k, v)
+ for k, v in self.parsed_attributes.items()
+ if k != "args"
+ ]
+ ),
)
self.code = ast.PythonCode(self.expression, **self.exception_kwargs)
self.body_decl = ast.FunctionArgs(
- attributes.get('args', ''),
- **self.exception_kwargs)
+ attributes.get("args", ""), **self.exception_kwargs
+ )
def declared_identifiers(self):
return self.code.declared_identifiers.union(self.body_decl.allargnames)
def undeclared_identifiers(self):
- return self.code.undeclared_identifiers.\
- difference(self.code.declared_identifiers)
+ return self.code.undeclared_identifiers.difference(
+ self.code.declared_identifiers
+ )
class InheritTag(Tag):
- __keyword__ = 'inherit'
+ __keyword__ = "inherit"
def __init__(self, keyword, attributes, **kwargs):
super(InheritTag, self).__init__(
- keyword, attributes,
- ('file',), (), ('file',), **kwargs)
+ keyword, attributes, ("file",), (), ("file",), **kwargs
+ )
class PageTag(Tag):
- __keyword__ = 'page'
+ __keyword__ = "page"
def __init__(self, keyword, attributes, **kwargs):
- expressions = \
- ['cached', 'args', 'expression_filter', 'enable_loop'] + \
- [c for c in attributes if c.startswith('cache_')]
+ expressions = [
+ "cached",
+ "args",
+ "expression_filter",
+ "enable_loop",
+ ] + [c for c in attributes if c.startswith("cache_")]
super(PageTag, self).__init__(
- keyword,
- attributes,
- expressions,
- (),
- (),
- **kwargs)
- self.body_decl = ast.FunctionArgs(attributes.get('args', ''),
- **self.exception_kwargs)
+ keyword, attributes, expressions, (), (), **kwargs
+ )
+ self.body_decl = ast.FunctionArgs(
+ attributes.get("args", ""), **self.exception_kwargs
+ )
self.filter_args = ast.ArgumentList(
- attributes.get('expression_filter', ''),
- **self.exception_kwargs)
+ attributes.get("expression_filter", ""), **self.exception_kwargs
+ )
def declared_identifiers(self):
return self.body_decl.allargnames
diff --git a/mako/pygen.py b/mako/pygen.py
index 8514e02..70665f6 100644
--- a/mako/pygen.py
+++ b/mako/pygen.py
@@ -7,11 +7,11 @@
"""utilities for generating and formatting literal Python code."""
import re
+
from mako import exceptions
class PythonPrinter(object):
-
def __init__(self, stream):
# indentation counter
self.indent = 0
@@ -60,7 +60,7 @@ class PythonPrinter(object):
The indentation of the total block of lines will be adjusted to that of
the current indent level."""
self.in_indent_lines = False
- for l in re.split(r'\r?\n', block):
+ for l in re.split(r"\r?\n", block):
self.line_buffer.append(l)
self._update_lineno(1)
@@ -83,21 +83,18 @@ class PythonPrinter(object):
self.in_indent_lines = True
if (
- line is None or
- re.match(r"^\s*#", line) or
- re.match(r"^\s*$", line)
+ line is None
+ or re.match(r"^\s*#", line)
+ or re.match(r"^\s*$", line)
):
hastext = False
else:
hastext = True
- is_comment = line and len(line) and line[0] == '#'
+ is_comment = line and len(line) and line[0] == "#"
# see if this line should decrease the indentation level
- if (
- not is_comment and
- (not hastext or self._is_unindentor(line))
- ):
+ if not is_comment and (not hastext or self._is_unindentor(line)):
if self.indent > 0:
self.indent -= 1
@@ -106,7 +103,8 @@ class PythonPrinter(object):
# module wont compile.
if len(self.indent_detail) == 0:
raise exceptions.SyntaxException(
- "Too many whitespace closures")
+ "Too many whitespace closures"
+ )
self.indent_detail.pop()
if line is None:
@@ -136,8 +134,9 @@ class PythonPrinter(object):
# its not a "compound" keyword. but lets also
# test for valid Python keywords that might be indenting us,
# else assume its a non-indenting line
- m2 = re.match(r"^\s*(def|class|else|elif|except|finally)",
- line)
+ m2 = re.match(
+ r"^\s*(def|class|else|elif|except|finally)", line
+ )
if m2:
self.indent += 1
self.indent_detail.append(indentor)
@@ -189,14 +188,15 @@ class PythonPrinter(object):
# return False
- def _indent_line(self, line, stripspace=''):
+ def _indent_line(self, line, stripspace=""):
"""indent the given line according to the current indent level.
stripspace is a string of space that will be truncated from the
start of the line before indenting."""
- return re.sub(r"^%s" % stripspace, self.indentstring
- * self.indent, line)
+ return re.sub(
+ r"^%s" % stripspace, self.indentstring * self.indent, line
+ )
def _reset_multi_line_flags(self):
"""reset the flags which would indicate we are in a backslashed
@@ -214,7 +214,7 @@ class PythonPrinter(object):
# a literal multiline string with unfortunately placed
# whitespace
- current_state = (self.backslashed or self.triplequoted)
+ current_state = self.backslashed or self.triplequoted
if re.search(r"\\$", line):
self.backslashed = True
@@ -251,7 +251,7 @@ def adjust_whitespace(text):
(backslashed, triplequoted) = (0, 1)
def in_multi_line(line):
- start_state = (state[backslashed] or state[triplequoted])
+ start_state = state[backslashed] or state[triplequoted]
if re.search(r"\\$", line):
state[backslashed] = True
@@ -261,7 +261,7 @@ def adjust_whitespace(text):
def match(reg, t):
m = re.match(reg, t)
if m:
- return m, t[len(m.group(0)):]
+ return m, t[len(m.group(0)) :]
else:
return None, t
@@ -273,7 +273,7 @@ def adjust_whitespace(text):
else:
m, line = match(r".*?(?=%s|$)" % state[triplequoted], line)
else:
- m, line = match(r'#', line)
+ m, line = match(r"#", line)
if m:
return start_state
@@ -286,13 +286,13 @@ def adjust_whitespace(text):
return start_state
- def _indent_line(line, stripspace=''):
- return re.sub(r"^%s" % stripspace, '', line)
+ def _indent_line(line, stripspace=""):
+ return re.sub(r"^%s" % stripspace, "", line)
lines = []
stripspace = None
- for line in re.split(r'\r?\n', text):
+ for line in re.split(r"\r?\n", text):
if in_multi_line(line):
lines.append(line)
else:
diff --git a/mako/pyparser.py b/mako/pyparser.py
index 15d0da6..c171897 100644
--- a/mako/pyparser.py
+++ b/mako/pyparser.py
@@ -10,46 +10,52 @@ Parsing to AST is done via _ast on Python > 2.5, otherwise the compiler
module is used.
"""
-from mako import exceptions, util, compat
-from mako.compat import arg_stringname
import operator
+import _ast
+
+from mako import _ast_util
+from mako import compat
+from mako import exceptions
+from mako import util
+from mako.compat import arg_stringname
+
if compat.py3k:
# words that cannot be assigned to (notably
# smaller than the total keys in __builtins__)
- reserved = set(['True', 'False', 'None', 'print'])
+ reserved = set(["True", "False", "None", "print"])
# the "id" attribute on a function node
- arg_id = operator.attrgetter('arg')
+ arg_id = operator.attrgetter("arg")
else:
# words that cannot be assigned to (notably
# smaller than the total keys in __builtins__)
- reserved = set(['True', 'False', 'None'])
+ reserved = set(["True", "False", "None"])
# the "id" attribute on a function node
- arg_id = operator.attrgetter('id')
+ arg_id = operator.attrgetter("id")
-import _ast
util.restore__ast(_ast)
-from mako import _ast_util
-def parse(code, mode='exec', **exception_kwargs):
+def parse(code, mode="exec", **exception_kwargs):
"""Parse an expression into AST"""
try:
- return _ast_util.parse(code, '<unknown>', mode)
+ return _ast_util.parse(code, "<unknown>", mode)
except Exception:
raise exceptions.SyntaxException(
- "(%s) %s (%r)" % (
+ "(%s) %s (%r)"
+ % (
compat.exception_as().__class__.__name__,
compat.exception_as(),
- code[0:50]
- ), **exception_kwargs)
+ code[0:50],
+ ),
+ **exception_kwargs
+ )
class FindIdentifiers(_ast_util.NodeVisitor):
-
def __init__(self, listener, **exception_kwargs):
self.in_function = False
self.in_assign_targets = False
@@ -119,9 +125,9 @@ class FindIdentifiers(_ast_util.NodeVisitor):
self.in_function = True
local_ident_stack = self.local_ident_stack
- self.local_ident_stack = local_ident_stack.union([
- arg_id(arg) for arg in self._expand_tuples(node.args.args)
- ])
+ self.local_ident_stack = local_ident_stack.union(
+ [arg_id(arg) for arg in self._expand_tuples(node.args.args)]
+ )
if islambda:
self.visit(node.body)
else:
@@ -146,9 +152,11 @@ class FindIdentifiers(_ast_util.NodeVisitor):
# this is eqiuvalent to visit_AssName in
# compiler
self._add_declared(node.id)
- elif node.id not in reserved and node.id \
- not in self.listener.declared_identifiers and node.id \
- not in self.local_ident_stack:
+ elif (
+ node.id not in reserved
+ and node.id not in self.listener.declared_identifiers
+ and node.id not in self.local_ident_stack
+ ):
self.listener.undeclared_identifiers.add(node.id)
def visit_Import(self, node):
@@ -156,24 +164,25 @@ class FindIdentifiers(_ast_util.NodeVisitor):
if name.asname is not None:
self._add_declared(name.asname)
else:
- self._add_declared(name.name.split('.')[0])
+ self._add_declared(name.name.split(".")[0])
def visit_ImportFrom(self, node):
for name in node.names:
if name.asname is not None:
self._add_declared(name.asname)
else:
- if name.name == '*':
+ if name.name == "*":
raise exceptions.CompileException(
"'import *' is not supported, since all identifier "
"names must be explicitly declared. Please use the "
"form 'from <modulename> import <name1>, <name2>, "
- "...' instead.", **self.exception_kwargs)
+ "...' instead.",
+ **self.exception_kwargs
+ )
self._add_declared(name.name)
class FindTuple(_ast_util.NodeVisitor):
-
def __init__(self, listener, code_factory, **exception_kwargs):
self.listener = listener
self.exception_kwargs = exception_kwargs
@@ -184,16 +193,17 @@ class FindTuple(_ast_util.NodeVisitor):
p = self.code_factory(n, **self.exception_kwargs)
self.listener.codeargs.append(p)
self.listener.args.append(ExpressionGenerator(n).value())
- self.listener.declared_identifiers = \
- self.listener.declared_identifiers.union(
- p.declared_identifiers)
- self.listener.undeclared_identifiers = \
- self.listener.undeclared_identifiers.union(
- p.undeclared_identifiers)
+ ldi = self.listener.declared_identifiers
+ self.listener.declared_identifiers = ldi.union(
+ p.declared_identifiers
+ )
+ lui = self.listener.undeclared_identifiers
+ self.listener.undeclared_identifiers = lui.union(
+ p.undeclared_identifiers
+ )
class ParseFunc(_ast_util.NodeVisitor):
-
def __init__(self, listener, **exception_kwargs):
self.listener = listener
self.exception_kwargs = exception_kwargs
@@ -224,10 +234,9 @@ class ParseFunc(_ast_util.NodeVisitor):
class ExpressionGenerator(object):
-
def __init__(self, astnode):
- self.generator = _ast_util.SourceGenerator(' ' * 4)
+ self.generator = _ast_util.SourceGenerator(" " * 4)
self.generator.visit(astnode)
def value(self):
- return ''.join(self.generator.result)
+ return "".join(self.generator.result)
diff --git a/mako/runtime.py b/mako/runtime.py
index 769541c..8c4f78c 100644
--- a/mako/runtime.py
+++ b/mako/runtime.py
@@ -7,10 +7,13 @@
"""provides runtime services for templates, including Context,
Namespace, and various helper functions."""
-from mako import exceptions, util, compat
-from mako.compat import compat_builtins
import sys
+from mako import compat
+from mako import exceptions
+from mako import util
+from mako.compat import compat_builtins
+
class Context(object):
@@ -34,18 +37,19 @@ class Context(object):
# "capture" function which proxies to the
# generic "capture" function
- self._data['capture'] = compat.partial(capture, self)
+ self._data["capture"] = compat.partial(capture, self)
# "caller" stack used by def calls with content
- self.caller_stack = self._data['caller'] = CallerStack()
+ self.caller_stack = self._data["caller"] = CallerStack()
def _set_with_template(self, t):
self._with_template = t
illegal_names = t.reserved_names.intersection(self._data)
if illegal_names:
raise exceptions.NameConflictError(
- "Reserved words passed to render(): %s" %
- ", ".join(illegal_names))
+ "Reserved words passed to render(): %s"
+ % ", ".join(illegal_names)
+ )
@property
def lookup(self):
@@ -177,14 +181,13 @@ class Context(object):
c = self._copy()
x = c._data
- x.pop('self', None)
- x.pop('parent', None)
- x.pop('next', None)
+ x.pop("self", None)
+ x.pop("parent", None)
+ x.pop("next", None)
return c
class CallerStack(list):
-
def __init__(self):
self.nextcaller = None
@@ -231,6 +234,7 @@ class Undefined(object):
def __bool__(self):
return False
+
UNDEFINED = Undefined()
STOP_RENDERING = ""
@@ -342,7 +346,6 @@ class LoopContext(object):
class _NSAttr(object):
-
def __init__(self, parent):
self.__parent = parent
@@ -373,9 +376,15 @@ class Namespace(object):
"""
- def __init__(self, name, context,
- callables=None, inherits=None,
- populate_self=True, calling_uri=None):
+ def __init__(
+ self,
+ name,
+ context,
+ callables=None,
+ inherits=None,
+ populate_self=True,
+ calling_uri=None,
+ ):
self.name = name
self.context = context
self.inherits = inherits
@@ -473,9 +482,12 @@ class Namespace(object):
if key in self.context.namespaces:
return self.context.namespaces[key]
else:
- ns = TemplateNamespace(uri, self.context._copy(),
- templateuri=uri,
- calling_uri=self._templateuri)
+ ns = TemplateNamespace(
+ uri,
+ self.context._copy(),
+ templateuri=uri,
+ calling_uri=self._templateuri,
+ )
self.context.namespaces[key] = ns
return ns
@@ -518,7 +530,7 @@ class Namespace(object):
def _populate(self, d, l):
for ident in l:
- if ident == '*':
+ if ident == "*":
for (k, v) in self._get_star():
d[k] = v
else:
@@ -536,8 +548,8 @@ class Namespace(object):
val = getattr(self.inherits, key)
else:
raise AttributeError(
- "Namespace '%s' has no member '%s'" %
- (self.name, key))
+ "Namespace '%s' has no member '%s'" % (self.name, key)
+ )
setattr(self, key, val)
return val
@@ -546,9 +558,17 @@ class TemplateNamespace(Namespace):
"""A :class:`.Namespace` specific to a :class:`.Template` instance."""
- def __init__(self, name, context, template=None, templateuri=None,
- callables=None, inherits=None,
- populate_self=True, calling_uri=None):
+ def __init__(
+ self,
+ name,
+ context,
+ template=None,
+ templateuri=None,
+ callables=None,
+ inherits=None,
+ populate_self=True,
+ calling_uri=None,
+ ):
self.name = name
self.context = context
self.inherits = inherits
@@ -556,8 +576,7 @@ class TemplateNamespace(Namespace):
self.callables = dict([(c.__name__, c) for c in callables])
if templateuri is not None:
- self.template = _lookup_template(context, templateuri,
- calling_uri)
+ self.template = _lookup_template(context, templateuri, calling_uri)
self._templateuri = self.template.module._template_uri
elif template is not None:
self.template = template
@@ -566,9 +585,9 @@ class TemplateNamespace(Namespace):
raise TypeError("'template' argument is required.")
if populate_self:
- lclcallable, lclcontext = \
- _populate_self_namespace(context, self.template,
- self_ns=self)
+ lclcallable, lclcontext = _populate_self_namespace(
+ context, self.template, self_ns=self
+ )
@property
def module(self):
@@ -607,6 +626,7 @@ class TemplateNamespace(Namespace):
def get(key):
callable_ = self.template._get_def_callable(key)
return compat.partial(callable_, self.context)
+
for k in self.template.module._exports:
yield (k, get(k))
@@ -621,8 +641,8 @@ class TemplateNamespace(Namespace):
else:
raise AttributeError(
- "Namespace '%s' has no member '%s'" %
- (self.name, key))
+ "Namespace '%s' has no member '%s'" % (self.name, key)
+ )
setattr(self, key, val)
return val
@@ -631,9 +651,16 @@ class ModuleNamespace(Namespace):
"""A :class:`.Namespace` specific to a Python module instance."""
- def __init__(self, name, context, module,
- callables=None, inherits=None,
- populate_self=True, calling_uri=None):
+ def __init__(
+ self,
+ name,
+ context,
+ module,
+ callables=None,
+ inherits=None,
+ populate_self=True,
+ calling_uri=None,
+ ):
self.name = name
self.context = context
self.inherits = inherits
@@ -641,7 +668,7 @@ class ModuleNamespace(Namespace):
self.callables = dict([(c.__name__, c) for c in callables])
mod = __import__(module)
- for token in module.split('.')[1:]:
+ for token in module.split(".")[1:]:
mod = getattr(mod, token)
self.module = mod
@@ -657,7 +684,7 @@ class ModuleNamespace(Namespace):
for key in self.callables:
yield (key, self.callables[key])
for key in dir(self.module):
- if key[0] != '_':
+ if key[0] != "_":
callable_ = getattr(self.module, key)
if compat.callable(callable_):
yield key, compat.partial(callable_, self.context)
@@ -672,8 +699,8 @@ class ModuleNamespace(Namespace):
val = getattr(self.inherits, key)
else:
raise AttributeError(
- "Namespace '%s' has no member '%s'" %
- (self.name, key))
+ "Namespace '%s' has no member '%s'" % (self.name, key)
+ )
setattr(self, key, val)
return val
@@ -692,6 +719,7 @@ def supports_caller(func):
return func(context, *args, **kwargs)
finally:
context.caller_stack._pop_frame()
+
return wrap_stackframe
@@ -721,13 +749,16 @@ def _decorate_toplevel(fn):
def go(context, *args, **kw):
def y(*args, **kw):
return render_fn(context, *args, **kw)
+
try:
y.__name__ = render_fn.__name__[7:]
except TypeError:
# < Python 2.4
pass
return fn(y)(context, *args, **kw)
+
return go
+
return decorate_render
@@ -737,7 +768,9 @@ def _decorate_inline(context, fn):
def go(*args, **kw):
return dec(context, *args, **kw)
+
return go
+
return decorate_render
@@ -747,8 +780,8 @@ def _include_file(context, uri, calling_uri, **kwargs):
template = _lookup_template(context, uri, calling_uri)
(callable_, ctx) = _populate_self_namespace(
- context._clean_inheritance_tokens(),
- template)
+ context._clean_inheritance_tokens(), template
+ )
kwargs = _kwargs_for_include(callable_, context._data, **kwargs)
if template.include_error_handler:
try:
@@ -769,23 +802,25 @@ def _inherit_from(context, uri, calling_uri):
if uri is None:
return None
template = _lookup_template(context, uri, calling_uri)
- self_ns = context['self']
+ self_ns = context["self"]
ih = self_ns
while ih.inherits is not None:
ih = ih.inherits
- lclcontext = context._locals({'next': ih})
- ih.inherits = TemplateNamespace("self:%s" % template.uri,
- lclcontext,
- template=template,
- populate_self=False)
- context._data['parent'] = lclcontext._data['local'] = ih.inherits
- callable_ = getattr(template.module, '_mako_inherit', None)
+ lclcontext = context._locals({"next": ih})
+ ih.inherits = TemplateNamespace(
+ "self:%s" % template.uri,
+ lclcontext,
+ template=template,
+ populate_self=False,
+ )
+ context._data["parent"] = lclcontext._data["local"] = ih.inherits
+ callable_ = getattr(template.module, "_mako_inherit", None)
if callable_ is not None:
ret = callable_(template, lclcontext)
if ret:
return ret
- gen_ns = getattr(template.module, '_mako_generate_namespaces', None)
+ gen_ns = getattr(template.module, "_mako_generate_namespaces", None)
if gen_ns is not None:
gen_ns(context)
return (template.callable_, lclcontext)
@@ -795,8 +830,9 @@ def _lookup_template(context, uri, relativeto):
lookup = context._with_template.lookup
if lookup is None:
raise exceptions.TemplateLookupException(
- "Template '%s' has no TemplateLookup associated" %
- context._with_template.uri)
+ "Template '%s' has no TemplateLookup associated"
+ % context._with_template.uri
+ )
uri = lookup.adjust_uri(uri, relativeto)
try:
return lookup.get_template(uri)
@@ -806,11 +842,14 @@ def _lookup_template(context, uri, relativeto):
def _populate_self_namespace(context, template, self_ns=None):
if self_ns is None:
- self_ns = TemplateNamespace('self:%s' % template.uri,
- context, template=template,
- populate_self=False)
- context._data['self'] = context._data['local'] = self_ns
- if hasattr(template.module, '_mako_inherit'):
+ self_ns = TemplateNamespace(
+ "self:%s" % template.uri,
+ context,
+ template=template,
+ populate_self=False,
+ )
+ context._data["self"] = context._data["local"] = self_ns
+ if hasattr(template.module, "_mako_inherit"):
ret = template.module._mako_inherit(template, context)
if ret:
return ret
@@ -829,13 +868,19 @@ def _render(template, callable_, args, data, as_unicode=False):
buf = util.FastEncodingBuffer(
as_unicode=as_unicode,
encoding=template.output_encoding,
- errors=template.encoding_errors)
+ errors=template.encoding_errors,
+ )
context = Context(buf, **data)
context._outputting_as_unicode = as_unicode
context._set_with_template(template)
- _render_context(template, callable_, context, *args,
- **_kwargs_for_callable(callable_, data))
+ _render_context(
+ template,
+ callable_,
+ context,
+ *args,
+ **_kwargs_for_callable(callable_, data)
+ )
return context._pop_buffer().getvalue()
@@ -849,7 +894,7 @@ def _kwargs_for_callable(callable_, data):
namedargs = argspec[0] + [v for v in argspec[1:3] if v is not None]
kwargs = {}
for arg in namedargs:
- if arg != 'context' and arg in data and arg not in kwargs:
+ if arg != "context" and arg in data and arg not in kwargs:
kwargs[arg] = data[arg]
return kwargs
@@ -858,13 +903,14 @@ def _kwargs_for_include(callable_, data, **kwargs):
argspec = compat.inspect_func_args(callable_)
namedargs = argspec[0] + [v for v in argspec[1:3] if v is not None]
for arg in namedargs:
- if arg != 'context' and arg in data and arg not in kwargs:
+ if arg != "context" and arg in data and arg not in kwargs:
kwargs[arg] = data[arg]
return kwargs
def _render_context(tmpl, callable_, context, *args, **kwargs):
import mako.template as template
+
# create polymorphic 'self' namespace for this
# template with possibly updated context
if not isinstance(tmpl, template.DefTemplate):
@@ -886,8 +932,9 @@ def _exec_template(callable_, context, args=None, kwargs=None):
be interpreted here.
"""
template = context._with_template
- if template is not None and \
- (template.format_exceptions or template.error_handler):
+ if template is not None and (
+ template.format_exceptions or template.error_handler
+ ):
try:
callable_(context, *args, **kwargs)
except Exception:
@@ -908,11 +955,15 @@ def _render_error(template, context, error):
error_template = exceptions.html_error_template()
if context._outputting_as_unicode:
context._buffer_stack[:] = [
- util.FastEncodingBuffer(as_unicode=True)]
+ util.FastEncodingBuffer(as_unicode=True)
+ ]
else:
- context._buffer_stack[:] = [util.FastEncodingBuffer(
- error_template.output_encoding,
- error_template.encoding_errors)]
+ context._buffer_stack[:] = [
+ util.FastEncodingBuffer(
+ error_template.output_encoding,
+ error_template.encoding_errors,
+ )
+ ]
context._set_with_template(error_template)
error_template.render_context(context, error=error)
diff --git a/mako/template.py b/mako/template.py
index 329632c..89d2105 100644
--- a/mako/template.py
+++ b/mako/template.py
@@ -7,8 +7,6 @@
"""Provides the Template class, a facade for parsing, generating and executing
template strings, as well as template runtime operations."""
-from mako.lexer import Lexer
-from mako import runtime, util, exceptions, codegen, cache, compat
import os
import re
import shutil
@@ -18,6 +16,14 @@ import tempfile
import types
import weakref
+from mako import cache
+from mako import codegen
+from mako import compat
+from mako import exceptions
+from mako import runtime
+from mako import util
+from mako.lexer import Lexer
+
class Template(object):
@@ -230,41 +236,43 @@ class Template(object):
lexer_cls = Lexer
- def __init__(self,
- text=None,
- filename=None,
- uri=None,
- format_exceptions=False,
- error_handler=None,
- lookup=None,
- output_encoding=None,
- encoding_errors='strict',
- module_directory=None,
- cache_args=None,
- cache_impl='beaker',
- cache_enabled=True,
- cache_type=None,
- cache_dir=None,
- cache_url=None,
- module_filename=None,
- input_encoding=None,
- disable_unicode=False,
- module_writer=None,
- bytestring_passthrough=False,
- default_filters=None,
- buffer_filters=(),
- strict_undefined=False,
- imports=None,
- future_imports=None,
- enable_loop=True,
- preprocessor=None,
- lexer_cls=None,
- include_error_handler=None):
+ def __init__(
+ self,
+ text=None,
+ filename=None,
+ uri=None,
+ format_exceptions=False,
+ error_handler=None,
+ lookup=None,
+ output_encoding=None,
+ encoding_errors="strict",
+ module_directory=None,
+ cache_args=None,
+ cache_impl="beaker",
+ cache_enabled=True,
+ cache_type=None,
+ cache_dir=None,
+ cache_url=None,
+ module_filename=None,
+ input_encoding=None,
+ disable_unicode=False,
+ module_writer=None,
+ bytestring_passthrough=False,
+ default_filters=None,
+ buffer_filters=(),
+ strict_undefined=False,
+ imports=None,
+ future_imports=None,
+ enable_loop=True,
+ preprocessor=None,
+ lexer_cls=None,
+ include_error_handler=None,
+ ):
if uri:
- self.module_id = re.sub(r'\W', "_", uri)
+ self.module_id = re.sub(r"\W", "_", uri)
self.uri = uri
elif filename:
- self.module_id = re.sub(r'\W', "_", filename)
+ self.module_id = re.sub(r"\W", "_", filename)
drive, path = os.path.splitdrive(filename)
path = os.path.normpath(path).replace(os.path.sep, "/")
self.uri = path
@@ -278,9 +286,10 @@ class Template(object):
u_norm = os.path.normpath(u_norm)
if u_norm.startswith(".."):
raise exceptions.TemplateLookupException(
- "Template uri \"%s\" is invalid - "
+ 'Template uri "%s" is invalid - '
"it cannot be relative outside "
- "of the root path." % self.uri)
+ "of the root path." % self.uri
+ )
self.input_encoding = input_encoding
self.output_encoding = output_encoding
@@ -293,17 +302,18 @@ class Template(object):
if compat.py3k and disable_unicode:
raise exceptions.UnsupportedError(
- "Mako for Python 3 does not "
- "support disabling Unicode")
+ "Mako for Python 3 does not " "support disabling Unicode"
+ )
elif output_encoding and disable_unicode:
raise exceptions.UnsupportedError(
"output_encoding must be set to "
- "None when disable_unicode is used.")
+ "None when disable_unicode is used."
+ )
if default_filters is None:
if compat.py3k or self.disable_unicode:
- self.default_filters = ['str']
+ self.default_filters = ["str"]
else:
- self.default_filters = ['unicode']
+ self.default_filters = ["unicode"]
else:
self.default_filters = default_filters
self.buffer_filters = buffer_filters
@@ -329,8 +339,7 @@ class Template(object):
elif module_directory is not None:
path = os.path.abspath(
os.path.join(
- os.path.normpath(module_directory),
- u_norm + ".py"
+ os.path.normpath(module_directory), u_norm + ".py"
)
)
else:
@@ -338,7 +347,8 @@ class Template(object):
module = self._compile_from_file(path, filename)
else:
raise exceptions.RuntimeException(
- "Template requires text or filename")
+ "Template requires text or filename"
+ )
self.module = module
self.filename = filename
@@ -351,8 +361,12 @@ class Template(object):
self.module_directory = module_directory
self._setup_cache_args(
- cache_impl, cache_enabled, cache_args,
- cache_type, cache_dir, cache_url
+ cache_impl,
+ cache_enabled,
+ cache_args,
+ cache_type,
+ cache_dir,
+ cache_url,
)
@util.memoized_property
@@ -360,11 +374,17 @@ class Template(object):
if self.enable_loop:
return codegen.RESERVED_NAMES
else:
- return codegen.RESERVED_NAMES.difference(['loop'])
-
- def _setup_cache_args(self,
- cache_impl, cache_enabled, cache_args,
- cache_type, cache_dir, cache_url):
+ return codegen.RESERVED_NAMES.difference(["loop"])
+
+ def _setup_cache_args(
+ self,
+ cache_impl,
+ cache_enabled,
+ cache_args,
+ cache_type,
+ cache_dir,
+ cache_url,
+ ):
self.cache_impl = cache_impl
self.cache_enabled = cache_enabled
if cache_args:
@@ -374,35 +394,31 @@ class Template(object):
# transfer deprecated cache_* args
if cache_type:
- self.cache_args['type'] = cache_type
+ self.cache_args["type"] = cache_type
if cache_dir:
- self.cache_args['dir'] = cache_dir
+ self.cache_args["dir"] = cache_dir
if cache_url:
- self.cache_args['url'] = cache_url
+ self.cache_args["url"] = cache_url
def _compile_from_file(self, path, filename):
if path is not None:
util.verify_directory(os.path.dirname(path))
filemtime = os.stat(filename)[stat.ST_MTIME]
- if not os.path.exists(path) or \
- os.stat(path)[stat.ST_MTIME] < filemtime:
+ if (
+ not os.path.exists(path)
+ or os.stat(path)[stat.ST_MTIME] < filemtime
+ ):
data = util.read_file(filename)
_compile_module_file(
- self,
- data,
- filename,
- path,
- self.module_writer)
+ self, data, filename, path, self.module_writer
+ )
module = compat.load_module(self.module_id, path)
del sys.modules[self.module_id]
if module._magic_number != codegen.MAGIC_NUMBER:
data = util.read_file(filename)
_compile_module_file(
- self,
- data,
- filename,
- path,
- self.module_writer)
+ self, data, filename, path, self.module_writer
+ )
module = compat.load_module(self.module_id, path)
del sys.modules[self.module_id]
ModuleInfo(module, path, self, filename, None, None)
@@ -410,10 +426,7 @@ class Template(object):
# template filename and no module directory, compile code
# in memory
data = util.read_file(filename)
- code, module = _compile_text(
- self,
- data,
- filename)
+ code, module = _compile_text(self, data, filename)
self._source = None
self._code = code
ModuleInfo(module, None, self, filename, code, None)
@@ -437,15 +450,15 @@ class Template(object):
@property
def cache_dir(self):
- return self.cache_args['dir']
+ return self.cache_args["dir"]
@property
def cache_url(self):
- return self.cache_args['url']
+ return self.cache_args["url"]
@property
def cache_type(self):
- return self.cache_args['type']
+ return self.cache_args["type"]
def render(self, *args, **data):
"""Render the output of this template as a string.
@@ -464,11 +477,9 @@ class Template(object):
def render_unicode(self, *args, **data):
"""Render the output of this template as a unicode object."""
- return runtime._render(self,
- self.callable_,
- args,
- data,
- as_unicode=True)
+ return runtime._render(
+ self, self.callable_, args, data, as_unicode=True
+ )
def render_context(self, context, *args, **kwargs):
"""Render this :class:`.Template` with the given context.
@@ -476,13 +487,9 @@ class Template(object):
The data is written to the context's buffer.
"""
- if getattr(context, '_with_template', None) is None:
+ if getattr(context, "_with_template", None) is None:
context._set_with_template(self)
- runtime._render_context(self,
- self.callable_,
- context,
- *args,
- **kwargs)
+ runtime._render_context(self, self.callable_, context, *args, **kwargs)
def has_def(self, name):
return hasattr(self.module, "render_%s" % name)
@@ -498,7 +505,7 @@ class Template(object):
.. versionadded:: 1.0.4
"""
- return [i[7:] for i in dir(self.module) if i[:7] == 'render_']
+ return [i[7:] for i in dir(self.module) if i[:7] == "render_"]
def _get_def_callable(self, name):
return getattr(self.module, "render_%s" % name)
@@ -526,28 +533,30 @@ class ModuleTemplate(Template):
"""
- def __init__(self, module,
- module_filename=None,
- template=None,
- template_filename=None,
- module_source=None,
- template_source=None,
- output_encoding=None,
- encoding_errors='strict',
- disable_unicode=False,
- bytestring_passthrough=False,
- format_exceptions=False,
- error_handler=None,
- lookup=None,
- cache_args=None,
- cache_impl='beaker',
- cache_enabled=True,
- cache_type=None,
- cache_dir=None,
- cache_url=None,
- include_error_handler=None,
- ):
- self.module_id = re.sub(r'\W', "_", module._template_uri)
+ def __init__(
+ self,
+ module,
+ module_filename=None,
+ template=None,
+ template_filename=None,
+ module_source=None,
+ template_source=None,
+ output_encoding=None,
+ encoding_errors="strict",
+ disable_unicode=False,
+ bytestring_passthrough=False,
+ format_exceptions=False,
+ error_handler=None,
+ lookup=None,
+ cache_args=None,
+ cache_impl="beaker",
+ cache_enabled=True,
+ cache_type=None,
+ cache_dir=None,
+ cache_url=None,
+ include_error_handler=None,
+ ):
+ self.module_id = re.sub(r"\W", "_", module._template_uri)
self.uri = module._template_uri
self.input_encoding = module._source_encoding
self.output_encoding = output_encoding
@@ -558,21 +567,24 @@ class ModuleTemplate(Template):
if compat.py3k and disable_unicode:
raise exceptions.UnsupportedError(
- "Mako for Python 3 does not "
- "support disabling Unicode")
+ "Mako for Python 3 does not " "support disabling Unicode"
+ )
elif output_encoding and disable_unicode:
raise exceptions.UnsupportedError(
"output_encoding must be set to "
- "None when disable_unicode is used.")
+ "None when disable_unicode is used."
+ )
self.module = module
self.filename = template_filename
- ModuleInfo(module,
- module_filename,
- self,
- template_filename,
- module_source,
- template_source)
+ ModuleInfo(
+ module,
+ module_filename,
+ self,
+ template_filename,
+ module_source,
+ template_source,
+ )
self.callable_ = self.module.render_body
self.format_exceptions = format_exceptions
@@ -580,8 +592,12 @@ class ModuleTemplate(Template):
self.include_error_handler = include_error_handler
self.lookup = lookup
self._setup_cache_args(
- cache_impl, cache_enabled, cache_args,
- cache_type, cache_dir, cache_url
+ cache_impl,
+ cache_enabled,
+ cache_args,
+ cache_type,
+ cache_dir,
+ cache_url,
)
@@ -614,15 +630,18 @@ class ModuleInfo(object):
source code based on a module's identifier.
"""
+
_modules = weakref.WeakValueDictionary()
- def __init__(self,
- module,
- module_filename,
- template,
- template_filename,
- module_source,
- template_source):
+ def __init__(
+ self,
+ module,
+ module_filename,
+ template,
+ template_filename,
+ module_source,
+ template_source,
+ ):
self.module = module
self.module_filename = module_filename
self.template_filename = template_filename
@@ -635,15 +654,15 @@ class ModuleInfo(object):
@classmethod
def get_module_source_metadata(cls, module_source, full_line_map=False):
source_map = re.search(
- r"__M_BEGIN_METADATA(.+?)__M_END_METADATA",
- module_source, re.S).group(1)
+ r"__M_BEGIN_METADATA(.+?)__M_END_METADATA", module_source, re.S
+ ).group(1)
source_map = compat.json.loads(source_map)
- source_map['line_map'] = dict(
- (int(k), int(v))
- for k, v in source_map['line_map'].items())
+ source_map["line_map"] = dict(
+ (int(k), int(v)) for k, v in source_map["line_map"].items()
+ )
if full_line_map:
- f_line_map = source_map['full_line_map'] = []
- line_map = source_map['line_map']
+ f_line_map = source_map["full_line_map"] = []
+ line_map = source_map["line_map"]
curr_templ_line = 1
for mod_line in range(1, max(line_map)):
@@ -662,10 +681,12 @@ class ModuleInfo(object):
@property
def source(self):
if self.template_source is not None:
- if self.module._source_encoding and \
- not isinstance(self.template_source, compat.text_type):
+ if self.module._source_encoding and not isinstance(
+ self.template_source, compat.text_type
+ ):
return self.template_source.decode(
- self.module._source_encoding)
+ self.module._source_encoding
+ )
else:
return self.template_source
else:
@@ -677,38 +698,46 @@ class ModuleInfo(object):
def _compile(template, text, filename, generate_magic_comment):
- lexer = template.lexer_cls(text,
- filename,
- disable_unicode=template.disable_unicode,
- input_encoding=template.input_encoding,
- preprocessor=template.preprocessor)
+ lexer = template.lexer_cls(
+ text,
+ filename,
+ disable_unicode=template.disable_unicode,
+ input_encoding=template.input_encoding,
+ preprocessor=template.preprocessor,
+ )
node = lexer.parse()
- source = codegen.compile(node,
- template.uri,
- filename,
- default_filters=template.default_filters,
- buffer_filters=template.buffer_filters,
- imports=template.imports,
- future_imports=template.future_imports,
- source_encoding=lexer.encoding,
- generate_magic_comment=generate_magic_comment,
- disable_unicode=template.disable_unicode,
- strict_undefined=template.strict_undefined,
- enable_loop=template.enable_loop,
- reserved_names=template.reserved_names)
+ source = codegen.compile(
+ node,
+ template.uri,
+ filename,
+ default_filters=template.default_filters,
+ buffer_filters=template.buffer_filters,
+ imports=template.imports,
+ future_imports=template.future_imports,
+ source_encoding=lexer.encoding,
+ generate_magic_comment=generate_magic_comment,
+ disable_unicode=template.disable_unicode,
+ strict_undefined=template.strict_undefined,
+ enable_loop=template.enable_loop,
+ reserved_names=template.reserved_names,
+ )
return source, lexer
def _compile_text(template, text, filename):
identifier = template.module_id
- source, lexer = _compile(template, text, filename,
- generate_magic_comment=template.disable_unicode)
+ source, lexer = _compile(
+ template,
+ text,
+ filename,
+ generate_magic_comment=template.disable_unicode,
+ )
cid = identifier
if not compat.py3k and isinstance(cid, compat.text_type):
cid = cid.encode()
module = types.ModuleType(cid)
- code = compile(source, cid, 'exec')
+ code = compile(source, cid, "exec")
# this exec() works for 2.4->3.3.
exec(code, module.__dict__, module.__dict__)
@@ -716,11 +745,12 @@ def _compile_text(template, text, filename):
def _compile_module_file(template, text, filename, outputpath, module_writer):
- source, lexer = _compile(template, text, filename,
- generate_magic_comment=True)
+ source, lexer = _compile(
+ template, text, filename, generate_magic_comment=True
+ )
if isinstance(source, compat.text_type):
- source = source.encode(lexer.encoding or 'ascii')
+ source = source.encode(lexer.encoding or "ascii")
if module_writer:
module_writer(source, outputpath)
@@ -737,9 +767,9 @@ def _compile_module_file(template, text, filename, outputpath, module_writer):
def _get_module_info_from_callable(callable_):
if compat.py3k:
- return _get_module_info(callable_.__globals__['__name__'])
+ return _get_module_info(callable_.__globals__["__name__"])
else:
- return _get_module_info(callable_.func_globals['__name__'])
+ return _get_module_info(callable_.func_globals["__name__"])
def _get_module_info(filename):
diff --git a/mako/util.py b/mako/util.py
index 2f089ff..cee911b 100644
--- a/mako/util.py
+++ b/mako/util.py
@@ -4,12 +4,13 @@
# This module is part of Mako and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php
-import re
-import collections
import codecs
+import collections
+import operator
import os
+import re
+
from mako import compat
-import operator
def update_wrapper(decorated, fn):
@@ -19,7 +20,6 @@ def update_wrapper(decorated, fn):
class PluginLoader(object):
-
def __init__(self, group):
self.group = group
self.impls = {}
@@ -29,16 +29,16 @@ class PluginLoader(object):
return self.impls[name]()
else:
import pkg_resources
- for impl in pkg_resources.iter_entry_points(
- self.group,
- name):
+
+ for impl in pkg_resources.iter_entry_points(self.group, name):
self.impls[name] = impl.load
return impl.load()
else:
from mako import exceptions
+
raise exceptions.RuntimeException(
- "Can't load plugin %s %s" %
- (self.group, name))
+ "Can't load plugin %s %s" % (self.group, name)
+ )
def register(self, name, modulepath, objname):
def load():
@@ -46,18 +46,19 @@ class PluginLoader(object):
for token in modulepath.split(".")[1:]:
mod = getattr(mod, token)
return getattr(mod, objname)
+
self.impls[name] = load
-def verify_directory(dir):
+def verify_directory(dir_):
"""create and/or verify a filesystem directory."""
tries = 0
- while not os.path.exists(dir):
+ while not os.path.exists(dir_):
try:
tries += 1
- os.makedirs(dir, compat.octal("0775"))
+ os.makedirs(dir_, compat.octal("0775"))
except:
if tries > 5:
raise
@@ -109,11 +110,15 @@ class memoized_instancemethod(object):
def oneshot(*args, **kw):
result = self.fget(obj, *args, **kw)
- memo = lambda *a, **kw: result
+
+ def memo(*a, **kw):
+ return result
+
memo.__name__ = self.__name__
memo.__doc__ = self.__doc__
obj.__dict__[self.__name__] = memo
return result
+
oneshot.__name__ = self.__name__
oneshot.__doc__ = self.__doc__
return oneshot
@@ -137,13 +142,13 @@ class FastEncodingBuffer(object):
"""a very rudimentary buffer that is faster than StringIO,
but doesn't crash on unicode data like cStringIO."""
- def __init__(self, encoding=None, errors='strict', as_unicode=False):
+ def __init__(self, encoding=None, errors="strict", as_unicode=False):
self.data = collections.deque()
self.encoding = encoding
if as_unicode:
- self.delim = compat.u('')
+ self.delim = compat.u("")
else:
- self.delim = ''
+ self.delim = ""
self.as_unicode = as_unicode
self.errors = errors
self.write = self.data.append
@@ -154,8 +159,9 @@ class FastEncodingBuffer(object):
def getvalue(self):
if self.encoding:
- return self.delim.join(self.data).encode(self.encoding,
- self.errors)
+ return self.delim.join(self.data).encode(
+ self.encoding, self.errors
+ )
else:
return self.delim.join(self.data)
@@ -171,7 +177,6 @@ class LRUCache(dict):
"""
class _Item(object):
-
def __init__(self, key, value):
self.key = key
self.value = value
@@ -180,7 +185,7 @@ class LRUCache(dict):
def __repr__(self):
return repr(self.value)
- def __init__(self, capacity, threshold=.5):
+ def __init__(self, capacity, threshold=0.5):
self.capacity = capacity
self.threshold = threshold
@@ -210,9 +215,12 @@ class LRUCache(dict):
def _manage_size(self):
while len(self) > self.capacity + self.capacity * self.threshold:
- bytime = sorted(dict.values(self),
- key=operator.attrgetter('timestamp'), reverse=True)
- for item in bytime[self.capacity:]:
+ bytime = sorted(
+ dict.values(self),
+ key=operator.attrgetter("timestamp"),
+ reverse=True,
+ )
+ for item in bytime[self.capacity :]:
try:
del self[item.key]
except KeyError:
@@ -220,10 +228,11 @@ class LRUCache(dict):
# broke in on us. loop around and try again
break
+
# Regexp to match python magic encoding line
_PYTHON_MAGIC_COMMENT_re = re.compile(
- r'[ \t\f]* \# .* coding[=:][ \t]*([-\w.]+)',
- re.VERBOSE)
+ r"[ \t\f]* \# .* coding[=:][ \t]*([-\w.]+)", re.VERBOSE
+)
def parse_encoding(fp):
@@ -242,13 +251,14 @@ def parse_encoding(fp):
line1 = fp.readline()
has_bom = line1.startswith(codecs.BOM_UTF8)
if has_bom:
- line1 = line1[len(codecs.BOM_UTF8):]
+ line1 = line1[len(codecs.BOM_UTF8) :]
- m = _PYTHON_MAGIC_COMMENT_re.match(line1.decode('ascii', 'ignore'))
+ m = _PYTHON_MAGIC_COMMENT_re.match(line1.decode("ascii", "ignore"))
if not m:
try:
import parser
- parser.suite(line1.decode('ascii', 'ignore'))
+
+ parser.suite(line1.decode("ascii", "ignore"))
except (ImportError, SyntaxError):
# Either it's a real syntax error, in which case the source
# is not valid python source, or line2 is a continuation of
@@ -258,14 +268,16 @@ def parse_encoding(fp):
else:
line2 = fp.readline()
m = _PYTHON_MAGIC_COMMENT_re.match(
- line2.decode('ascii', 'ignore'))
+ line2.decode("ascii", "ignore")
+ )
if has_bom:
if m:
raise SyntaxError(
"python refuses to compile code with both a UTF8"
- " byte-order-mark and a magic encoding comment")
- return 'utf_8'
+ " byte-order-mark and a magic encoding comment"
+ )
+ return "utf_8"
elif m:
return m.group(1)
else:
@@ -289,10 +301,11 @@ def restore__ast(_ast):
"""Attempt to restore the required classes to the _ast module if it
appears to be missing them
"""
- if hasattr(_ast, 'AST'):
+ if hasattr(_ast, "AST"):
return
_ast.PyCF_ONLY_AST = 2 << 9
- m = compile("""\
+ m = compile(
+ """\
def foo(): pass
class Bar(object): pass
if False: pass
@@ -305,13 +318,17 @@ baz = 'mako'
baz and 'foo' or 'bar'
(mako is baz == baz) is not baz != mako
mako > baz < mako >= baz <= mako
-mako in baz not in mako""", '<unknown>', 'exec', _ast.PyCF_ONLY_AST)
+mako in baz not in mako""",
+ "<unknown>",
+ "exec",
+ _ast.PyCF_ONLY_AST,
+ )
_ast.Module = type(m)
for cls in _ast.Module.__mro__:
- if cls.__name__ == 'mod':
+ if cls.__name__ == "mod":
_ast.mod = cls
- elif cls.__name__ == 'AST':
+ elif cls.__name__ == "AST":
_ast.AST = cls
_ast.FunctionDef = type(m.body[0])
@@ -361,7 +378,7 @@ mako in baz not in mako""", '<unknown>', 'exec', _ast.PyCF_ONLY_AST)
_ast.NotIn = type(m.body[12].value.ops[1])
-def read_file(path, mode='rb'):
+def read_file(path, mode="rb"):
fp = open(path, mode)
try:
data = fp.read()
diff --git a/setup.cfg b/setup.cfg
index 02c9d45..59bac7f 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -11,3 +11,17 @@ python_files=test/*test_*.py
[upload]
sign = 1
identity = C4DAFEE1
+
+[flake8]
+enable-extensions = G
+# E203 is due to https://github.com/PyCQA/pycodestyle/issues/373
+ignore =
+ A003,
+ D,
+ E203,E305,E711,E712,E721,E722,E741,
+ N801,N802,N806,
+ RST304,RST303,RST299,RST399,
+ W503,W504
+exclude = .venv,.git,.tox,dist,docs/*,*egg,build
+import-order-style = google
+application-import-names = mako,test
diff --git a/setup.py b/setup.py
index a5bf468..3cb0559 100644
--- a/setup.py
+++ b/setup.py
@@ -1,14 +1,20 @@
-from setuptools import setup, find_packages
-from setuptools.command.test import test as TestCommand
import os
import re
import sys
-v = open(os.path.join(os.path.dirname(__file__), 'mako', '__init__.py'))
-VERSION = re.compile(r".*__version__ = '(.*?)'", re.S).match(v.read()).group(1)
+from setuptools import find_packages
+from setuptools import setup
+from setuptools.command.test import test as TestCommand
+
+v = open(os.path.join(os.path.dirname(__file__), "mako", "__init__.py"))
+VERSION = (
+ re.compile(r".*__version__ = [\"'](.*?)[\"']", re.S)
+ .match(v.read())
+ .group(1)
+)
v.close()
-readme = open(os.path.join(os.path.dirname(__file__), 'README.rst')).read()
+readme = open(os.path.join(os.path.dirname(__file__), "README.rst")).read()
if sys.version_info < (2, 6):
raise Exception("Mako requires Python 2.6 or higher.")
@@ -20,16 +26,16 @@ markupsafe_installs = (
install_requires = []
if markupsafe_installs:
- install_requires.append('MarkupSafe>=0.9.2')
+ install_requires.append("MarkupSafe>=0.9.2")
try:
- import argparse
+ import argparse # noqa
except ImportError:
- install_requires.append('argparse')
+ install_requires.append("argparse")
class PyTest(TestCommand):
- user_options = [('pytest-args=', 'a', "Arguments to pass to py.test")]
+ user_options = [("pytest-args=", "a", "Arguments to pass to py.test")]
def initialize_options(self):
TestCommand.initialize_options(self)
@@ -43,39 +49,41 @@ class PyTest(TestCommand):
def run_tests(self):
# import here, cause outside the eggs aren't loaded
import pytest
+
errno = pytest.main(self.pytest_args)
sys.exit(errno)
-setup(name='Mako',
- version=VERSION,
- description="A super-fast templating language that borrows the \
+setup(
+ name="Mako",
+ version=VERSION,
+ description="A super-fast templating language that borrows the \
best ideas from the existing templating languages.",
- long_description=readme,
- classifiers=[
- 'Development Status :: 5 - Production/Stable',
- 'License :: OSI Approved :: MIT License',
- 'Environment :: Web Environment',
- 'Intended Audience :: Developers',
- 'Programming Language :: Python',
- 'Programming Language :: Python :: 3',
- "Programming Language :: Python :: Implementation :: CPython",
- "Programming Language :: Python :: Implementation :: PyPy",
- 'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
- ],
- keywords='templates',
- author='Mike Bayer',
- author_email='mike@zzzcomputing.com',
- url='https://www.makotemplates.org/',
- license='MIT',
- packages=find_packages('.', exclude=['examples*', 'test*']),
- tests_require=['pytest', 'mock'],
- cmdclass={'test': PyTest},
- zip_safe=False,
- python_requires='>=2.6',
- install_requires=install_requires,
- extras_require={},
- entry_points="""
+ long_description=readme,
+ classifiers=[
+ "Development Status :: 5 - Production/Stable",
+ "License :: OSI Approved :: MIT License",
+ "Environment :: Web Environment",
+ "Intended Audience :: Developers",
+ "Programming Language :: Python",
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: Implementation :: CPython",
+ "Programming Language :: Python :: Implementation :: PyPy",
+ "Topic :: Internet :: WWW/HTTP :: Dynamic Content",
+ ],
+ keywords="templates",
+ author="Mike Bayer",
+ author_email="mike@zzzcomputing.com",
+ url="https://www.makotemplates.org/",
+ license="MIT",
+ packages=find_packages(".", exclude=["examples*", "test*"]),
+ tests_require=["pytest", "mock"],
+ cmdclass={"test": PyTest},
+ zip_safe=False,
+ python_requires=">=2.6",
+ install_requires=install_requires,
+ extras_require={},
+ entry_points="""
[python.templating.engines]
mako = mako.ext.turbogears:TGPlugin
@@ -94,5 +102,5 @@ setup(name='Mako',
[console_scripts]
mako-render = mako.cmd:cmdline
- """
+ """,
)
diff --git a/test/__init__.py b/test/__init__.py
index 186ec04..b91e709 100644
--- a/test/__init__.py
+++ b/test/__init__.py
@@ -1,11 +1,15 @@
-from mako.template import Template
-import unittest
+import contextlib
import os
-from mako.compat import py3k, py33
+import re
+import unittest
+
from mako import compat
+from mako.cache import CacheImpl
+from mako.cache import register_plugin
+from mako.compat import py33
+from mako.compat import py3k
+from mako.template import Template
from mako.util import update_wrapper
-import re
-from mako.cache import CacheImpl, register_plugin
try:
# unitttest has a SkipTest also but pytest doesn't
@@ -14,17 +18,16 @@ try:
except ImportError:
from _pytest.runner import Skipped as SkipTest
-import contextlib
+template_base = os.path.join(os.path.dirname(__file__), "templates")
+module_base = os.path.join(template_base, "modules")
-template_base = os.path.join(os.path.dirname(__file__), 'templates')
-module_base = os.path.join(template_base, 'modules')
class TemplateTest(unittest.TestCase):
-
def _file_template(self, filename, **kw):
filepath = self._file_path(filename)
- return Template(uri=filename, filename=filepath,
- module_directory=module_base, **kw)
+ return Template(
+ uri=filename, filename=filepath, module_directory=module_base, **kw
+ )
def _file_path(self, filename):
name, ext = os.path.splitext(filename)
@@ -36,20 +39,50 @@ class TemplateTest(unittest.TestCase):
return os.path.join(template_base, filename)
- def _do_file_test(self, filename, expected, filters=None,
- unicode_=True, template_args=None, **kw):
+ def _do_file_test(
+ self,
+ filename,
+ expected,
+ filters=None,
+ unicode_=True,
+ template_args=None,
+ **kw
+ ):
t1 = self._file_template(filename, **kw)
- self._do_test(t1, expected, filters=filters,
- unicode_=unicode_, template_args=template_args)
-
- def _do_memory_test(self, source, expected, filters=None,
- unicode_=True, template_args=None, **kw):
+ self._do_test(
+ t1,
+ expected,
+ filters=filters,
+ unicode_=unicode_,
+ template_args=template_args,
+ )
+
+ def _do_memory_test(
+ self,
+ source,
+ expected,
+ filters=None,
+ unicode_=True,
+ template_args=None,
+ **kw
+ ):
t1 = Template(text=source, **kw)
- self._do_test(t1, expected, filters=filters,
- unicode_=unicode_, template_args=template_args)
-
- def _do_test(self, template, expected, filters=None, template_args=None,
- unicode_=True):
+ self._do_test(
+ t1,
+ expected,
+ filters=filters,
+ unicode_=unicode_,
+ template_args=template_args,
+ )
+
+ def _do_test(
+ self,
+ template,
+ expected,
+ filters=None,
+ template_args=None,
+ unicode_=True,
+ ):
if template_args is None:
template_args = {}
if unicode_:
@@ -61,18 +94,23 @@ class TemplateTest(unittest.TestCase):
output = filters(output)
eq_(output, expected)
+
def eq_(a, b, msg=None):
"""Assert a == b, with repr messaging on failure."""
assert a == b, msg or "%r != %r" % (a, b)
+
def teardown():
import shutil
+
shutil.rmtree(module_base, True)
+
if py33:
- from unittest import mock
+ from unittest import mock # noqa
else:
- import mock
+ import mock # noqa
+
@contextlib.contextmanager
def raises(except_cls, message=None):
@@ -81,9 +119,10 @@ def raises(except_cls, message=None):
success = False
except except_cls as e:
if message:
- assert re.search(message, compat.text_type(e), re.UNICODE), \
- "%r !~ %s" % (message, e)
- print(compat.text_type(e).encode('utf-8'))
+ assert re.search(
+ message, compat.text_type(e), re.UNICODE
+ ), "%r !~ %s" % (message, e)
+ print(compat.text_type(e).encode("utf-8"))
success = True
# assert outside the block so it works for AssertionError too !
@@ -94,50 +133,64 @@ def assert_raises(except_cls, callable_, *args, **kw):
with raises(except_cls):
return callable_(*args, **kw)
+
def assert_raises_message(except_cls, msg, callable_, *args, **kwargs):
with raises(except_cls, msg):
return callable_(*args, **kwargs)
+
def skip_if(predicate, reason=None):
"""Skip a test if predicate is true."""
reason = reason or predicate.__name__
def decorate(fn):
fn_name = fn.__name__
+
def maybe(*args, **kw):
if predicate():
- msg = "'%s' skipped: %s" % (
- fn_name, reason)
+ msg = "'%s' skipped: %s" % (fn_name, reason)
raise SkipTest(msg)
else:
return fn(*args, **kw)
+
return update_wrapper(maybe, fn)
+
return decorate
+
def requires_python_3(fn):
return skip_if(lambda: not py3k, "Requires Python 3.xx")(fn)
+
def requires_python_2(fn):
return skip_if(lambda: py3k, "Requires Python 2.xx")(fn)
+
def requires_pygments_14(fn):
try:
import pygments
+
version = pygments.__version__
except:
version = "0"
- return skip_if(lambda: version < "1.4", "Requires pygments 1.4 or greater")(fn)
+ return skip_if(
+ lambda: version < "1.4", "Requires pygments 1.4 or greater"
+ )(fn)
+
def requires_no_pygments_exceptions(fn):
def go(*arg, **kw):
from mako import exceptions
+
exceptions._install_fallback()
try:
return fn(*arg, **kw)
finally:
exceptions._install_highlighting()
+
return update_wrapper(go, fn)
+
class PlainCacheImpl(CacheImpl):
"""Simple memory cache impl so that tests which
use caching can run without beaker. """
@@ -162,4 +215,5 @@ class PlainCacheImpl(CacheImpl):
def invalidate(self, key, **kw):
del self.data[key]
+
register_plugin("plain", __name__, "PlainCacheImpl")
diff --git a/test/ext/test_babelplugin.py b/test/ext/test_babelplugin.py
index 3658c50..5f25a6a 100644
--- a/test/ext/test_babelplugin.py
+++ b/test/ext/test_babelplugin.py
@@ -1,93 +1,120 @@
import io
import os
import unittest
-from .. import TemplateTest, template_base, skip_if
+
from mako import compat
+from .. import skip_if
+from .. import template_base
+from .. import TemplateTest
try:
import babel.messages.extract as babel
from mako.ext.babelplugin import extract
-
+
except ImportError:
babel = None
def skip():
return skip_if(
- lambda: not babel,
- 'babel not installed: skipping babelplugin test')
+ lambda: not babel, "babel not installed: skipping babelplugin test"
+ )
class Test_extract(unittest.TestCase):
@skip()
def test_parse_python_expression(self):
- input = io.BytesIO(compat.b('<p>${_("Message")}</p>'))
- messages = list(extract(input, ['_'], [], {}))
- self.assertEqual(messages, [(1, '_', compat.u('Message'), [])])
+ input_ = io.BytesIO(compat.b('<p>${_("Message")}</p>'))
+ messages = list(extract(input_, ["_"], [], {}))
+ self.assertEqual(messages, [(1, "_", compat.u("Message"), [])])
@skip()
def test_python_gettext_call(self):
- input = io.BytesIO(compat.b('<p>${_("Message")}</p>'))
- messages = list(extract(input, ['_'], [], {}))
- self.assertEqual(messages, [(1, '_', compat.u('Message'), [])])
+ input_ = io.BytesIO(compat.b('<p>${_("Message")}</p>'))
+ messages = list(extract(input_, ["_"], [], {}))
+ self.assertEqual(messages, [(1, "_", compat.u("Message"), [])])
@skip()
def test_translator_comment(self):
- input = io.BytesIO(compat.b('''
+ input_ = io.BytesIO(
+ compat.b(
+ """
<p>
## TRANSLATORS: This is a comment.
${_("Message")}
- </p>'''))
- messages = list(extract(input, ['_'], ['TRANSLATORS:'], {}))
+ </p>"""
+ )
+ )
+ messages = list(extract(input_, ["_"], ["TRANSLATORS:"], {}))
self.assertEqual(
messages,
- [(4, '_', compat.u('Message'),
- [compat.u('TRANSLATORS: This is a comment.')])])
+ [
+ (
+ 4,
+ "_",
+ compat.u("Message"),
+ [compat.u("TRANSLATORS: This is a comment.")],
+ )
+ ],
+ )
class ExtractMakoTestCase(TemplateTest):
@skip()
def test_extract(self):
- mako_tmpl = open(os.path.join(template_base, 'gettext.mako'))
- messages = list(extract(mako_tmpl, {'_': None, 'gettext': None,
- 'ungettext': (1, 2)},
- ['TRANSLATOR:'], {}))
- expected = \
- [(1, '_', 'Page arg 1', []),
- (1, '_', 'Page arg 2', []),
- (10, 'gettext', 'Begin', []),
- (14, '_', 'Hi there!', ['TRANSLATOR: Hi there!']),
- (19, '_', 'Hello', []),
- (22, '_', 'Welcome', []),
- (25, '_', 'Yo', []),
- (36, '_', 'The', ['TRANSLATOR: Ensure so and', 'so, thanks']),
- (36, 'ungettext', ('bunny', 'bunnies', None), []),
- (41, '_', 'Goodbye', ['TRANSLATOR: Good bye']),
- (44, '_', 'Babel', []),
- (45, 'ungettext', ('hella', 'hellas', None), []),
- (62, '_', 'The', ['TRANSLATOR: Ensure so and', 'so, thanks']),
- (62, 'ungettext', ('bunny', 'bunnies', None), []),
- (68, '_', 'Goodbye, really!', ['TRANSLATOR: HTML comment']),
- (71, '_', 'P.S. byebye', []),
- (77, '_', 'Top', []),
- (83, '_', 'foo', []),
- (83, '_', 'hoho', []),
- (85, '_', 'bar', []),
- (92, '_', 'Inside a p tag', ['TRANSLATOR: <p> tag is ok?']),
- (95, '_', 'Later in a p tag', ['TRANSLATOR: also this']),
- (99, '_', 'No action at a distance.', []),
- ]
+ mako_tmpl = open(os.path.join(template_base, "gettext.mako"))
+ messages = list(
+ extract(
+ mako_tmpl,
+ {"_": None, "gettext": None, "ungettext": (1, 2)},
+ ["TRANSLATOR:"],
+ {},
+ )
+ )
+ expected = [
+ (1, "_", "Page arg 1", []),
+ (1, "_", "Page arg 2", []),
+ (10, "gettext", "Begin", []),
+ (14, "_", "Hi there!", ["TRANSLATOR: Hi there!"]),
+ (19, "_", "Hello", []),
+ (22, "_", "Welcome", []),
+ (25, "_", "Yo", []),
+ (36, "_", "The", ["TRANSLATOR: Ensure so and", "so, thanks"]),
+ (36, "ungettext", ("bunny", "bunnies", None), []),
+ (41, "_", "Goodbye", ["TRANSLATOR: Good bye"]),
+ (44, "_", "Babel", []),
+ (45, "ungettext", ("hella", "hellas", None), []),
+ (62, "_", "The", ["TRANSLATOR: Ensure so and", "so, thanks"]),
+ (62, "ungettext", ("bunny", "bunnies", None), []),
+ (68, "_", "Goodbye, really!", ["TRANSLATOR: HTML comment"]),
+ (71, "_", "P.S. byebye", []),
+ (77, "_", "Top", []),
+ (83, "_", "foo", []),
+ (83, "_", "hoho", []),
+ (85, "_", "bar", []),
+ (92, "_", "Inside a p tag", ["TRANSLATOR: <p> tag is ok?"]),
+ (95, "_", "Later in a p tag", ["TRANSLATOR: also this"]),
+ (99, "_", "No action at a distance.", []),
+ ]
self.assertEqual(expected, messages)
@skip()
def test_extract_utf8(self):
- mako_tmpl = open(os.path.join(template_base, 'gettext_utf8.mako'), 'rb')
- message = next(extract(mako_tmpl, set(['_', None]), [], {'encoding': 'utf-8'}))
- assert message == (1, '_', u'K\xf6ln', [])
+ mako_tmpl = open(
+ os.path.join(template_base, "gettext_utf8.mako"), "rb"
+ )
+ message = next(
+ extract(mako_tmpl, set(["_", None]), [], {"encoding": "utf-8"})
+ )
+ assert message == (1, "_", u"K\xf6ln", [])
@skip()
def test_extract_cp1251(self):
- mako_tmpl = open(os.path.join(template_base, 'gettext_cp1251.mako'), 'rb')
- message = next(extract(mako_tmpl, set(['_', None]), [], {'encoding': 'cp1251'}))
+ mako_tmpl = open(
+ os.path.join(template_base, "gettext_cp1251.mako"), "rb"
+ )
+ message = next(
+ extract(mako_tmpl, set(["_", None]), [], {"encoding": "cp1251"})
+ )
# "test" in Rusian. File encoding is cp1251 (aka "windows-1251")
- assert message == (1, '_', u'\u0442\u0435\u0441\u0442', [])
+ assert message == (1, "_", u"\u0442\u0435\u0441\u0442", [])
diff --git a/test/ext/test_linguaplugin.py b/test/ext/test_linguaplugin.py
index 9c46271..a563969 100644
--- a/test/ext/test_linguaplugin.py
+++ b/test/ext/test_linguaplugin.py
@@ -1,5 +1,8 @@
import os
-from .. import TemplateTest, template_base, skip_if
+
+from .. import skip_if
+from .. import template_base
+from .. import TemplateTest
try:
import lingua
@@ -18,40 +21,44 @@ class MockOptions:
def skip():
return skip_if(
- lambda: not lingua, 'lingua not installed: skipping linguaplugin test')
+ lambda: not lingua, "lingua not installed: skipping linguaplugin test"
+ )
class ExtractMakoTestCase(TemplateTest):
@skip()
def test_extract(self):
register_extractors()
- plugin = LinguaMakoExtractor({'comment-tags': 'TRANSLATOR'})
+ plugin = LinguaMakoExtractor({"comment-tags": "TRANSLATOR"})
messages = list(
- plugin(os.path.join(template_base, 'gettext.mako'), MockOptions()))
+ plugin(os.path.join(template_base, "gettext.mako"), MockOptions())
+ )
msgids = [(m.msgid, m.msgid_plural) for m in messages]
self.assertEqual(
msgids,
[
- ('Page arg 1', None),
- ('Page arg 2', None),
- ('Begin', None),
- ('Hi there!', None),
- ('Hello', None),
- ('Welcome', None),
- ('Yo', None),
- ('The', None),
- ('bunny', 'bunnies'),
- ('Goodbye', None),
- ('Babel', None),
- ('hella', 'hellas'),
- ('The', None),
- ('bunny', 'bunnies'),
- ('Goodbye, really!', None),
- ('P.S. byebye', None),
- ('Top', None),
- (u'foo', None),
- ('hoho', None),
- (u'bar', None),
- ('Inside a p tag', None),
- ('Later in a p tag', None),
- ('No action at a distance.', None)])
+ ("Page arg 1", None),
+ ("Page arg 2", None),
+ ("Begin", None),
+ ("Hi there!", None),
+ ("Hello", None),
+ ("Welcome", None),
+ ("Yo", None),
+ ("The", None),
+ ("bunny", "bunnies"),
+ ("Goodbye", None),
+ ("Babel", None),
+ ("hella", "hellas"),
+ ("The", None),
+ ("bunny", "bunnies"),
+ ("Goodbye, really!", None),
+ ("P.S. byebye", None),
+ ("Top", None),
+ (u"foo", None),
+ ("hoho", None),
+ (u"bar", None),
+ ("Inside a p tag", None),
+ ("Later in a p tag", None),
+ ("No action at a distance.", None),
+ ],
+ )
diff --git a/test/foo/mod_no_encoding.py b/test/foo/mod_no_encoding.py
index 2ba6746..004cc44 100644
--- a/test/foo/mod_no_encoding.py
+++ b/test/foo/mod_no_encoding.py
@@ -1,8 +1,7 @@
-
from mako.lookup import TemplateLookup
-from mako.exceptions import MakoException, html_error_template
template_lookup = TemplateLookup()
-def run():
- tpl = template_lookup.get_template('not_found.html')
+
+def run():
+ tpl = template_lookup.get_template("not_found.html")
diff --git a/test/foo/test_ns.py b/test/foo/test_ns.py
index 282447a..f67e22e 100644
--- a/test/foo/test_ns.py
+++ b/test/foo/test_ns.py
@@ -1,10 +1,11 @@
def foo1(context):
context.write("this is foo1.")
- return ''
+ return ""
+
def foo2(context, x):
context.write("this is foo2, x is " + x)
- return ''
+ return ""
-foo3 = "I'm not a callable" \ No newline at end of file
+foo3 = "I'm not a callable"
diff --git a/test/sample_module_namespace.py b/test/sample_module_namespace.py
index 7a2425d..886e8dd 100644
--- a/test/sample_module_namespace.py
+++ b/test/sample_module_namespace.py
@@ -1,7 +1,8 @@
def foo1(context):
context.write("this is foo1.")
- return ''
-
+ return ""
+
+
def foo2(context, x):
context.write("this is foo2, x is " + x)
- return '' \ No newline at end of file
+ return ""
diff --git a/test/test_ast.py b/test/test_ast.py
index 24ba0c3..ce6c082 100644
--- a/test/test_ast.py
+++ b/test/test_ast.py
@@ -1,16 +1,17 @@
import unittest
-from mako import ast, exceptions, pyparser, util, compat
-from test import eq_, requires_python_2, requires_python_3
+from mako import ast
+from mako import compat
+from mako import exceptions
+from mako import pyparser
+from test import eq_
+from test import requires_python_2
+from test import requires_python_3
-exception_kwargs = {
- 'source': '',
- 'lineno': 0,
- 'pos': 0,
- 'filename': ''}
+exception_kwargs = {"source": "", "lineno": 0, "pos": 0, "filename": ""}
-class AstParseTest(unittest.TestCase):
+class AstParseTest(unittest.TestCase):
def test_locate_identifiers(self):
"""test the location of identifiers in a python code string"""
code = """
@@ -29,16 +30,17 @@ for lar in (1,2,3):
parsed = ast.PythonCode(code, **exception_kwargs)
eq_(
parsed.declared_identifiers,
- set(['a', 'b', 'c', 'g', 'h', 'i', 'u',
- 'k', 'j', 'gh', 'lar', 'x'])
+ set(
+ ["a", "b", "c", "g", "h", "i", "u", "k", "j", "gh", "lar", "x"]
+ ),
)
eq_(
parsed.undeclared_identifiers,
- set(['x', 'q', 'foo', 'gah', 'blah'])
+ set(["x", "q", "foo", "gah", "blah"]),
)
parsed = ast.PythonCode("x + 5 * (y-z)", **exception_kwargs)
- assert parsed.undeclared_identifiers == set(['x', 'y', 'z'])
+ assert parsed.undeclared_identifiers == set(["x", "y", "z"])
assert parsed.declared_identifiers == set()
def test_locate_identifiers_2(self):
@@ -52,10 +54,10 @@ for x in data:
result.append(x+7)
"""
parsed = ast.PythonCode(code, **exception_kwargs)
- eq_(parsed.undeclared_identifiers, set(['get_data']))
+ eq_(parsed.undeclared_identifiers, set(["get_data"]))
eq_(
parsed.declared_identifiers,
- set(['result', 'data', 'x', 'hoho', 'foobar', 'foo', 'yaya'])
+ set(["result", "data", "x", "hoho", "foobar", "foo", "yaya"]),
)
def test_locate_identifiers_3(self):
@@ -69,10 +71,7 @@ for y in range(1, y):
(q for q in range (1, q))
"""
parsed = ast.PythonCode(code, **exception_kwargs)
- eq_(
- parsed.undeclared_identifiers,
- set(['x', 'y', 'z', 'q', 'range'])
- )
+ eq_(parsed.undeclared_identifiers, set(["x", "y", "z", "q", "range"]))
def test_locate_identifiers_4(self):
code = """
@@ -82,8 +81,8 @@ def mydef(mydefarg):
print("mda is", mydefarg)
"""
parsed = ast.PythonCode(code, **exception_kwargs)
- eq_(parsed.undeclared_identifiers, set(['y']))
- eq_(parsed.declared_identifiers, set(['mydef', 'x']))
+ eq_(parsed.undeclared_identifiers, set(["y"]))
+ eq_(parsed.declared_identifiers, set(["mydef", "x"]))
def test_locate_identifiers_5(self):
code = """
@@ -93,7 +92,7 @@ except:
print(y)
"""
parsed = ast.PythonCode(code, **exception_kwargs)
- eq_(parsed.undeclared_identifiers, set(['x', 'y']))
+ eq_(parsed.undeclared_identifiers, set(["x", "y"]))
def test_locate_identifiers_6(self):
code = """
@@ -101,7 +100,7 @@ def foo():
return bar()
"""
parsed = ast.PythonCode(code, **exception_kwargs)
- eq_(parsed.undeclared_identifiers, set(['bar']))
+ eq_(parsed.undeclared_identifiers, set(["bar"]))
code = """
def lala(x, y):
@@ -109,8 +108,8 @@ def lala(x, y):
print(x)
"""
parsed = ast.PythonCode(code, **exception_kwargs)
- eq_(parsed.undeclared_identifiers, set(['z', 'x']))
- eq_(parsed.declared_identifiers, set(['lala']))
+ eq_(parsed.undeclared_identifiers, set(["z", "x"]))
+ eq_(parsed.declared_identifiers, set(["lala"]))
code = """
def lala(x, y):
@@ -120,15 +119,15 @@ def lala(x, y):
print(z)
"""
parsed = ast.PythonCode(code, **exception_kwargs)
- eq_(parsed.undeclared_identifiers, set(['z']))
- eq_(parsed.declared_identifiers, set(['lala']))
+ eq_(parsed.undeclared_identifiers, set(["z"]))
+ eq_(parsed.declared_identifiers, set(["lala"]))
def test_locate_identifiers_7(self):
code = """
import foo.bar
"""
parsed = ast.PythonCode(code, **exception_kwargs)
- eq_(parsed.declared_identifiers, set(['foo']))
+ eq_(parsed.declared_identifiers, set(["foo"]))
eq_(parsed.undeclared_identifiers, set())
def test_locate_identifiers_8(self):
@@ -139,7 +138,7 @@ class Hi(object):
x = 5
"""
parsed = ast.PythonCode(code, **exception_kwargs)
- eq_(parsed.declared_identifiers, set(['Hi']))
+ eq_(parsed.declared_identifiers, set(["Hi"]))
eq_(parsed.undeclared_identifiers, set())
def test_locate_identifiers_9(self):
@@ -147,15 +146,15 @@ class Hi(object):
",".join([t for t in ("a", "b", "c")])
"""
parsed = ast.PythonCode(code, **exception_kwargs)
- eq_(parsed.declared_identifiers, set(['t']))
- eq_(parsed.undeclared_identifiers, set(['t']))
+ eq_(parsed.declared_identifiers, set(["t"]))
+ eq_(parsed.undeclared_identifiers, set(["t"]))
code = """
[(val, name) for val, name in x]
"""
parsed = ast.PythonCode(code, **exception_kwargs)
- eq_(parsed.declared_identifiers, set(['val', 'name']))
- eq_(parsed.undeclared_identifiers, set(['val', 'name', 'x']))
+ eq_(parsed.declared_identifiers, set(["val", "name"]))
+ eq_(parsed.undeclared_identifiers, set(["val", "name", "x"]))
def test_locate_identifiers_10(self):
code = """
@@ -171,10 +170,9 @@ def x(q):
return q + 5
"""
parsed = ast.PythonCode(code, **exception_kwargs)
- eq_(parsed.declared_identifiers, set(['x']))
+ eq_(parsed.declared_identifiers, set(["x"]))
eq_(parsed.undeclared_identifiers, set())
-
def test_locate_identifiers_12(self):
code = """
def foo():
@@ -183,7 +181,7 @@ def foo():
t = s
"""
parsed = ast.PythonCode(code, **exception_kwargs)
- eq_(parsed.declared_identifiers, set(['foo']))
+ eq_(parsed.declared_identifiers, set(["foo"]))
eq_(parsed.undeclared_identifiers, set())
def test_locate_identifiers_13(self):
@@ -194,7 +192,7 @@ def foo():
Bat
"""
parsed = ast.PythonCode(code, **exception_kwargs)
- eq_(parsed.declared_identifiers, set(['foo']))
+ eq_(parsed.declared_identifiers, set(["foo"]))
eq_(parsed.undeclared_identifiers, set())
def test_locate_identifiers_14(self):
@@ -207,8 +205,8 @@ def foo():
print(Bat)
"""
parsed = ast.PythonCode(code, **exception_kwargs)
- eq_(parsed.declared_identifiers, set(['foo']))
- eq_(parsed.undeclared_identifiers, set(['Bat']))
+ eq_(parsed.declared_identifiers, set(["foo"]))
+ eq_(parsed.undeclared_identifiers, set(["Bat"]))
@requires_python_2
def test_locate_identifiers_15(self):
@@ -219,7 +217,7 @@ def t1((x,y)):
t2 = lambda (x,y):(x+5, y+4)
"""
parsed = ast.PythonCode(code, **exception_kwargs)
- eq_(parsed.declared_identifiers, set(['t1', 't2']))
+ eq_(parsed.declared_identifiers, set(["t1", "t2"]))
eq_(parsed.undeclared_identifiers, set())
def test_locate_identifiers_16(self):
@@ -230,7 +228,7 @@ except Exception as e:
print(y)
"""
parsed = ast.PythonCode(code, **exception_kwargs)
- eq_(parsed.undeclared_identifiers, set(['x', 'y', 'Exception']))
+ eq_(parsed.undeclared_identifiers, set(["x", "y", "Exception"]))
def test_locate_identifiers_17(self):
code = """
@@ -240,38 +238,47 @@ except (Foo, Bar) as e:
print(y)
"""
parsed = ast.PythonCode(code, **exception_kwargs)
- eq_(parsed.undeclared_identifiers, set(['x', 'y', 'Foo', 'Bar']))
+ eq_(parsed.undeclared_identifiers, set(["x", "y", "Foo", "Bar"]))
def test_no_global_imports(self):
code = """
from foo import *
import x as bar
"""
- self.assertRaises(exceptions.CompileException,
- ast.PythonCode, code, **exception_kwargs)
+ self.assertRaises(
+ exceptions.CompileException,
+ ast.PythonCode,
+ code,
+ **exception_kwargs
+ )
def test_python_fragment(self):
parsed = ast.PythonFragment("for x in foo:", **exception_kwargs)
- eq_(parsed.declared_identifiers, set(['x']))
- eq_(parsed.undeclared_identifiers, set(['foo']))
+ eq_(parsed.declared_identifiers, set(["x"]))
+ eq_(parsed.undeclared_identifiers, set(["foo"]))
parsed = ast.PythonFragment("try:", **exception_kwargs)
if compat.py3k:
parsed = ast.PythonFragment(
- "except MyException as e:", **exception_kwargs)
+ "except MyException as e:", **exception_kwargs
+ )
else:
parsed = ast.PythonFragment(
- "except MyException, e:", **exception_kwargs)
- eq_(parsed.declared_identifiers, set(['e']))
- eq_(parsed.undeclared_identifiers, set(['MyException']))
+ "except MyException, e:", **exception_kwargs
+ )
+ eq_(parsed.declared_identifiers, set(["e"]))
+ eq_(parsed.undeclared_identifiers, set(["MyException"]))
def test_argument_list(self):
- parsed = ast.ArgumentList("3, 5, 'hi', x+5, "
- "context.get('lala')", **exception_kwargs)
- eq_(parsed.undeclared_identifiers, set(['x', 'context']))
- eq_([x for x in parsed.args],
- ["3", "5", "'hi'", "(x + 5)", "context.get('lala')"])
+ parsed = ast.ArgumentList(
+ "3, 5, 'hi', x+5, " "context.get('lala')", **exception_kwargs
+ )
+ eq_(parsed.undeclared_identifiers, set(["x", "context"]))
+ eq_(
+ [x for x in parsed.args],
+ ["3", "5", "'hi'", "(x + 5)", "context.get('lala')"],
+ )
parsed = ast.ArgumentList("h", **exception_kwargs)
eq_(parsed.args, ["h"])
@@ -280,32 +287,26 @@ import x as bar
"""test getting the arguments from a function"""
code = "def foo(a, b, c=None, d='hi', e=x, f=y+7):pass"
parsed = ast.FunctionDecl(code, **exception_kwargs)
- eq_(parsed.funcname, 'foo')
- eq_(parsed.argnames,
- ['a', 'b', 'c', 'd', 'e', 'f'])
- eq_(parsed.kwargnames,
- [])
+ eq_(parsed.funcname, "foo")
+ eq_(parsed.argnames, ["a", "b", "c", "d", "e", "f"])
+ eq_(parsed.kwargnames, [])
def test_function_decl_2(self):
"""test getting the arguments from a function"""
code = "def foo(a, b, c=None, *args, **kwargs):pass"
parsed = ast.FunctionDecl(code, **exception_kwargs)
- eq_(parsed.funcname, 'foo')
- eq_(parsed.argnames,
- ['a', 'b', 'c', 'args'])
- eq_(parsed.kwargnames,
- ['kwargs'])
+ eq_(parsed.funcname, "foo")
+ eq_(parsed.argnames, ["a", "b", "c", "args"])
+ eq_(parsed.kwargnames, ["kwargs"])
@requires_python_3
def test_function_decl_3(self):
"""test getting the arguments from a fancy py3k function"""
code = "def foo(a, b, *c, d, e, **f):pass"
parsed = ast.FunctionDecl(code, **exception_kwargs)
- eq_(parsed.funcname, 'foo')
- eq_(parsed.argnames,
- ['a', 'b', 'c'])
- eq_(parsed.kwargnames,
- ['d', 'e', 'f'])
+ eq_(parsed.funcname, "foo")
+ eq_(parsed.argnames, ["a", "b", "c"])
+ eq_(parsed.kwargnames, ["d", "e", "f"])
def test_expr_generate(self):
"""test the round trip of expressions to AST back to python source"""
@@ -313,7 +314,7 @@ import x as bar
y = 2
class F(object):
- def bar(self, a,b):
+ def bar(self, a, b):
return a + b
def lala(arg):
@@ -327,48 +328,47 @@ import x as bar
eq_(eval(code, local_dict), eval(newcode, local_dict))
a = ["one", "two", "three"]
- hoho = {'somevalue': "asdf"}
+ hoho = {"somevalue": "asdf"}
g = [1, 2, 3, 4, 5]
local_dict = dict(a=a, hoho=hoho, g=g)
- code = "a[2] + hoho['somevalue'] + "\
- "repr(g[3:5]) + repr(g[3:]) + repr(g[:5])"
+ code = (
+ "a[2] + hoho['somevalue'] + "
+ "repr(g[3:5]) + repr(g[3:]) + repr(g[:5])"
+ )
astnode = pyparser.parse(code)
newcode = pyparser.ExpressionGenerator(astnode).value()
eq_(eval(code, local_dict), eval(newcode, local_dict))
- local_dict = {'f': lambda: 9, 'x': 7}
+ local_dict = {"f": lambda: 9, "x": 7}
code = "x+f()"
astnode = pyparser.parse(code)
newcode = pyparser.ExpressionGenerator(astnode).value()
eq_(eval(code, local_dict), eval(newcode, local_dict))
- for code in ["repr({'x':7,'y':18})",
- "repr([])",
- "repr({})",
- "repr([{3:[]}])",
- "repr({'x':37*2 + len([6,7,8])})",
- "repr([1, 2, {}, {'x':'7'}])",
- "repr({'x':-1})", "repr(((1,2,3), (4,5,6)))",
- "repr(1 and 2 and 3 and 4)",
- "repr(True and False or 55)",
- "repr(lambda x, y: (x + y))",
- "repr(lambda *arg, **kw: arg, kw)",
- "repr(1 & 2 | 3)",
- "repr(3//5)",
- "repr(3^5)",
- "repr([q.endswith('e') for q in "
- "['one', 'two', 'three']])",
- "repr([x for x in (5,6,7) if x == 6])",
- "repr(not False)"]:
+ for code in [
+ "repr({'x':7,'y':18})",
+ "repr([])",
+ "repr({})",
+ "repr([{3:[]}])",
+ "repr({'x':37*2 + len([6,7,8])})",
+ "repr([1, 2, {}, {'x':'7'}])",
+ "repr({'x':-1})",
+ "repr(((1,2,3), (4,5,6)))",
+ "repr(1 and 2 and 3 and 4)",
+ "repr(True and False or 55)",
+ "repr(lambda x, y: (x + y))",
+ "repr(lambda *arg, **kw: arg, kw)",
+ "repr(1 & 2 | 3)",
+ "repr(3//5)",
+ "repr(3^5)",
+ "repr([q.endswith('e') for q in " "['one', 'two', 'three']])",
+ "repr([x for x in (5,6,7) if x == 6])",
+ "repr(not False)",
+ ]:
local_dict = {}
astnode = pyparser.parse(code)
newcode = pyparser.ExpressionGenerator(astnode).value()
if "lambda" in code:
eq_(code, newcode)
else:
- eq_(eval(code, local_dict),
- eval(newcode, local_dict)
- )
-
-
-
+ eq_(eval(code, local_dict), eval(newcode, local_dict))
diff --git a/test/test_block.py b/test/test_block.py
index da3de15..0cbe347 100644
--- a/test/test_block.py
+++ b/test/test_block.py
@@ -1,9 +1,9 @@
-from mako.template import Template
-from mako.lookup import TemplateLookup
from mako import exceptions
-from test import TemplateTest, assert_raises, assert_raises_message
-from test.util import flatten_result, result_lines
-
+from mako.lookup import TemplateLookup
+from mako.template import Template
+from test import assert_raises_message
+from test import TemplateTest
+from test.util import result_lines
class BlockTest(TemplateTest):
@@ -11,17 +11,19 @@ class BlockTest(TemplateTest):
assert_raises_message(
exceptions.CompileException,
"Can't put anonymous blocks inside <%namespace>",
- Template, """
+ Template,
+ """
<%namespace name="foo">
<%block>
block
</%block>
</%namespace>
- """
+ """,
)
def test_anonymous_block_in_call(self):
- template = Template("""
+ template = Template(
+ """
<%self:foo x="5">
<%block>
@@ -33,18 +35,18 @@ class BlockTest(TemplateTest):
foo:
${caller.body()}
</%def>
- """)
+ """
+ )
self._do_test(
- template,
- ["foo:", "this is the block x"],
- filters=result_lines
+ template, ["foo:", "this is the block x"], filters=result_lines
)
def test_named_block_in_call(self):
assert_raises_message(
exceptions.CompileException,
"Named block 'y' not allowed inside of <%call> tag",
- Template,"""
+ Template,
+ """
<%self:foo x="5">
<%block name="y">
@@ -57,7 +59,8 @@ class BlockTest(TemplateTest):
${caller.body()}
${caller.y()}
</%def>
- """)
+ """,
+ )
def test_name_collision_blocks_toplevel(self):
assert_raises_message(
@@ -74,7 +77,7 @@ class BlockTest(TemplateTest):
<%block name="x">
block
</%block>
- """
+ """,
)
def test_name_collision_blocks_nested_block(self):
@@ -94,7 +97,7 @@ class BlockTest(TemplateTest):
block
</%block>
</%block>
- """
+ """,
)
def test_name_collision_blocks_nested_def(self):
@@ -114,7 +117,7 @@ class BlockTest(TemplateTest):
block
</%block>
</%def>
- """
+ """,
)
def test_name_collision_block_def_toplevel(self):
@@ -132,7 +135,7 @@ class BlockTest(TemplateTest):
<%def name="x()">
block
</%def>
- """
+ """,
)
def test_name_collision_def_block_toplevel(self):
@@ -151,31 +154,37 @@ class BlockTest(TemplateTest):
block
</%block>
- """
+ """,
)
def test_named_block_renders(self):
- template = Template("""
+ template = Template(
+ """
above
<%block name="header">
the header
</%block>
below
- """)
- self._do_test(template, ["above", "the header", "below"],
- filters=result_lines)
+ """
+ )
+ self._do_test(
+ template, ["above", "the header", "below"], filters=result_lines
+ )
def test_inherited_block_no_render(self):
l = TemplateLookup()
- l.put_string("index",
+ l.put_string(
+ "index",
"""
<%inherit file="base"/>
<%block name="header">
index header
</%block>
- """
+ """,
)
- l.put_string("base","""
+ l.put_string(
+ "base",
+ """
above
<%block name="header">
the header
@@ -183,10 +192,13 @@ class BlockTest(TemplateTest):
${next.body()}
below
- """)
- self._do_test(l.get_template("index"),
- ["above", "index header", "below"],
- filters=result_lines)
+ """,
+ )
+ self._do_test(
+ l.get_template("index"),
+ ["above", "index header", "below"],
+ filters=result_lines,
+ )
def test_no_named_in_def(self):
assert_raises_message(
@@ -198,11 +210,13 @@ class BlockTest(TemplateTest):
<%block name="y">
</%block>
</%def>
- """)
+ """,
+ )
def test_inherited_block_nested_both(self):
l = TemplateLookup()
- l.put_string("index",
+ l.put_string(
+ "index",
"""
<%inherit file="base"/>
<%block name="title">
@@ -213,9 +227,11 @@ class BlockTest(TemplateTest):
index header
${parent.header()}
</%block>
- """
+ """,
)
- l.put_string("base","""
+ l.put_string(
+ "base",
+ """
above
<%block name="header">
base header
@@ -226,23 +242,29 @@ class BlockTest(TemplateTest):
${next.body()}
below
- """)
- self._do_test(l.get_template("index"),
- ["above", "index header", "base header", "index title", "below"],
- filters=result_lines)
+ """,
+ )
+ self._do_test(
+ l.get_template("index"),
+ ["above", "index header", "base header", "index title", "below"],
+ filters=result_lines,
+ )
def test_inherited_block_nested_inner_only(self):
l = TemplateLookup()
- l.put_string("index",
+ l.put_string(
+ "index",
"""
<%inherit file="base"/>
<%block name="title">
index title
</%block>
- """
+ """,
)
- l.put_string("base","""
+ l.put_string(
+ "base",
+ """
above
<%block name="header">
base header
@@ -253,22 +275,28 @@ class BlockTest(TemplateTest):
${next.body()}
below
- """)
- self._do_test(l.get_template("index"),
- ["above", "base header", "index title", "below"],
- filters=result_lines)
+ """,
+ )
+ self._do_test(
+ l.get_template("index"),
+ ["above", "base header", "index title", "below"],
+ filters=result_lines,
+ )
def test_noninherited_block_no_render(self):
l = TemplateLookup()
- l.put_string("index",
+ l.put_string(
+ "index",
"""
<%inherit file="base"/>
<%block name="some_thing">
some thing
</%block>
- """
+ """,
)
- l.put_string("base","""
+ l.put_string(
+ "base",
+ """
above
<%block name="header">
the header
@@ -276,14 +304,18 @@ class BlockTest(TemplateTest):
${next.body()}
below
- """)
- self._do_test(l.get_template("index"),
- ["above", "the header", "some thing", "below"],
- filters=result_lines)
+ """,
+ )
+ self._do_test(
+ l.get_template("index"),
+ ["above", "the header", "some thing", "below"],
+ filters=result_lines,
+ )
def test_no_conflict_nested_one(self):
l = TemplateLookup()
- l.put_string("index",
+ l.put_string(
+ "index",
"""
<%inherit file="base"/>
<%block>
@@ -291,9 +323,11 @@ class BlockTest(TemplateTest):
inner header
</%block>
</%block>
- """
+ """,
)
- l.put_string("base","""
+ l.put_string(
+ "base",
+ """
above
<%block name="header">
the header
@@ -301,10 +335,13 @@ class BlockTest(TemplateTest):
${next.body()}
below
- """)
- self._do_test(l.get_template("index"),
- ["above", "inner header", "below"],
- filters=result_lines)
+ """,
+ )
+ self._do_test(
+ l.get_template("index"),
+ ["above", "inner header", "below"],
+ filters=result_lines,
+ )
def test_nested_dupe_names_raise(self):
assert_raises_message(
@@ -318,12 +355,13 @@ class BlockTest(TemplateTest):
inner header
</%block>
</%block>
- """
+ """,
)
def test_two_levels_one(self):
l = TemplateLookup()
- l.put_string("index",
+ l.put_string(
+ "index",
"""
<%inherit file="middle"/>
<%block name="header">
@@ -332,16 +370,21 @@ class BlockTest(TemplateTest):
<%block>
index anon
</%block>
- """
+ """,
)
- l.put_string("middle", """
+ l.put_string(
+ "middle",
+ """
<%inherit file="base"/>
<%block>
middle anon
</%block>
${next.body()}
- """)
- l.put_string("base","""
+ """,
+ )
+ l.put_string(
+ "base",
+ """
above
<%block name="header">
the header
@@ -349,23 +392,27 @@ class BlockTest(TemplateTest):
${next.body()}
below
- """)
- self._do_test(l.get_template("index"),
- ["above", "index header", "middle anon",
- "index anon", "below"],
- filters=result_lines)
+ """,
+ )
+ self._do_test(
+ l.get_template("index"),
+ ["above", "index header", "middle anon", "index anon", "below"],
+ filters=result_lines,
+ )
def test_filter(self):
- template = Template("""
+ template = Template(
+ """
<%block filter="h">
<html>
</%block>
- """)
- self._do_test(template, ['&lt;html&gt;'],
- filters=result_lines)
+ """
+ )
+ self._do_test(template, ["&lt;html&gt;"], filters=result_lines)
def test_anon_in_named(self):
- template = Template("""
+ template = Template(
+ """
<%block name="x">
outer above
<%block>
@@ -373,11 +420,13 @@ class BlockTest(TemplateTest):
</%block>
outer below
</%block>
- """)
+ """
+ )
self._test_block_in_block(template)
def test_named_in_anon(self):
- template = Template("""
+ template = Template(
+ """
<%block>
outer above
<%block name="x">
@@ -385,11 +434,13 @@ class BlockTest(TemplateTest):
</%block>
outer below
</%block>
- """)
+ """
+ )
self._test_block_in_block(template)
def test_anon_in_anon(self):
- template = Template("""
+ template = Template(
+ """
<%block>
outer above
<%block>
@@ -397,11 +448,13 @@ class BlockTest(TemplateTest):
</%block>
outer below
</%block>
- """)
+ """
+ )
self._test_block_in_block(template)
def test_named_in_named(self):
- template = Template("""
+ template = Template(
+ """
<%block name="x">
outer above
<%block name="y">
@@ -409,28 +462,30 @@ class BlockTest(TemplateTest):
</%block>
outer below
</%block>
- """)
+ """
+ )
self._test_block_in_block(template)
def _test_block_in_block(self, template):
- self._do_test(template,
+ self._do_test(
+ template,
["outer above", "inner", "outer below"],
- filters=result_lines
+ filters=result_lines,
)
def test_iteration(self):
- t = Template("""
+ t = Template(
+ """
% for i in (1, 2, 3):
<%block>${i}</%block>
% endfor
- """)
- self._do_test(t,
- ["1", "2", "3"],
- filters=result_lines
+ """
)
+ self._do_test(t, ["1", "2", "3"], filters=result_lines)
def test_conditional(self):
- t = Template("""
+ t = Template(
+ """
% if True:
<%block>true</%block>
% endif
@@ -438,23 +493,24 @@ class BlockTest(TemplateTest):
% if False:
<%block>false</%block>
% endif
- """)
- self._do_test(t,
- ["true"],
- filters=result_lines
+ """
)
+ self._do_test(t, ["true"], filters=result_lines)
def test_block_overridden_by_def(self):
l = TemplateLookup()
- l.put_string("index",
+ l.put_string(
+ "index",
"""
<%inherit file="base"/>
<%def name="header()">
inner header
</%def>
- """
+ """,
)
- l.put_string("base","""
+ l.put_string(
+ "base",
+ """
above
<%block name="header">
the header
@@ -462,22 +518,28 @@ class BlockTest(TemplateTest):
${next.body()}
below
- """)
- self._do_test(l.get_template("index"),
- ["above", "inner header", "below"],
- filters=result_lines)
+ """,
+ )
+ self._do_test(
+ l.get_template("index"),
+ ["above", "inner header", "below"],
+ filters=result_lines,
+ )
def test_def_overridden_by_block(self):
l = TemplateLookup()
- l.put_string("index",
+ l.put_string(
+ "index",
"""
<%inherit file="base"/>
<%block name="header">
inner header
</%block>
- """
+ """,
)
- l.put_string("base","""
+ l.put_string(
+ "base",
+ """
above
${self.header()}
<%def name="header()">
@@ -486,84 +548,101 @@ class BlockTest(TemplateTest):
${next.body()}
below
- """)
- self._do_test(l.get_template("index"),
- ["above", "inner header", "below"],
- filters=result_lines)
+ """,
+ )
+ self._do_test(
+ l.get_template("index"),
+ ["above", "inner header", "below"],
+ filters=result_lines,
+ )
def test_block_args(self):
l = TemplateLookup()
- l.put_string("caller", """
+ l.put_string(
+ "caller",
+ """
<%include file="callee" args="val1='3', val2='4'"/>
- """)
- l.put_string("callee", """
+ """,
+ )
+ l.put_string(
+ "callee",
+ """
<%page args="val1, val2"/>
<%block name="foob" args="val1, val2">
foob, ${val1}, ${val2}
</%block>
- """)
+ """,
+ )
self._do_test(
- l.get_template("caller"),
- ['foob, 3, 4'],
- filters=result_lines
+ l.get_template("caller"), ["foob, 3, 4"], filters=result_lines
)
def test_block_variables_contextual(self):
- t = Template("""
+ t = Template(
+ """
<%block name="foob" >
foob, ${val1}, ${val2}
</%block>
- """)
+ """
+ )
self._do_test(
t,
- ['foob, 3, 4'],
- template_args={'val1':3, 'val2':4},
- filters=result_lines
+ ["foob, 3, 4"],
+ template_args={"val1": 3, "val2": 4},
+ filters=result_lines,
)
def test_block_args_contextual(self):
- t = Template("""
+ t = Template(
+ """
<%page args="val1"/>
<%block name="foob" args="val1">
foob, ${val1}, ${val2}
</%block>
- """)
+ """
+ )
self._do_test(
t,
- ['foob, 3, 4'],
- template_args={'val1':3, 'val2':4},
- filters=result_lines
+ ["foob, 3, 4"],
+ template_args={"val1": 3, "val2": 4},
+ filters=result_lines,
)
def test_block_pageargs_contextual(self):
- t = Template("""
+ t = Template(
+ """
<%block name="foob">
foob, ${pageargs['val1']}, ${pageargs['val2']}
</%block>
- """)
+ """
+ )
self._do_test(
t,
- ['foob, 3, 4'],
- template_args={'val1':3, 'val2':4},
- filters=result_lines
+ ["foob, 3, 4"],
+ template_args={"val1": 3, "val2": 4},
+ filters=result_lines,
)
def test_block_pageargs(self):
l = TemplateLookup()
- l.put_string("caller", """
+ l.put_string(
+ "caller",
+ """
<%include file="callee" args="val1='3', val2='4'"/>
- """)
- l.put_string("callee", """
+ """,
+ )
+ l.put_string(
+ "callee",
+ """
<%block name="foob">
foob, ${pageargs['val1']}, ${pageargs['val2']}
</%block>
- """)
+ """,
+ )
self._do_test(
- l.get_template("caller"),
- ['foob, 3, 4'],
- filters=result_lines
- ) \ No newline at end of file
+ l.get_template("caller"), ["foob, 3, 4"], filters=result_lines
+ )
diff --git a/test/test_cache.py b/test/test_cache.py
index 990a088..7fe9350 100644
--- a/test/test_cache.py
+++ b/test/test_cache.py
@@ -1,19 +1,21 @@
-from mako.template import Template
-from mako.lookup import TemplateLookup
-from mako import lookup
import time
-from test.util import result_lines
-from test import TemplateTest, module_base
-from test import eq_, SkipTest
-from mako.compat import py27
+from mako import lookup
+from mako.cache import CacheImpl
+from mako.cache import register_plugin
+from mako.compat import py27
from mako.ext import beaker_cache
+from mako.lookup import TemplateLookup
+from mako.template import Template
+from test import eq_
+from test import module_base
+from test import SkipTest
+from test import TemplateTest
+from test.util import result_lines
if beaker_cache.has_beaker:
import beaker
-from mako.cache import register_plugin, CacheImpl
-
class SimpleBackend(object):
def __init__(self):
@@ -43,23 +45,22 @@ class MockCacheImpl(CacheImpl):
self.cache = cache
def set_backend(self, cache, backend):
- if backend == 'simple':
+ if backend == "simple":
self.realcacheimpl = SimpleBackend()
else:
self.realcacheimpl = cache._load_impl(backend)
def _setup_kwargs(self, kw):
self.kwargs = kw.copy()
- self.kwargs.pop('regions', None)
- self.kwargs.pop('manager', None)
- if self.kwargs.get('region') != 'myregion':
- self.kwargs.pop('region', None)
+ self.kwargs.pop("regions", None)
+ self.kwargs.pop("manager", None)
+ if self.kwargs.get("region") != "myregion":
+ self.kwargs.pop("region", None)
def get_or_create(self, key, creation_function, **kw):
self.key = key
self._setup_kwargs(kw)
- return self.realcacheimpl.\
- get_or_create(key, creation_function, **kw)
+ return self.realcacheimpl.get_or_create(key, creation_function, **kw)
def put(self, key, value, **kw):
self.key = key
@@ -82,16 +83,17 @@ register_plugin("mock", __name__, "MockCacheImpl")
class CacheTest(TemplateTest):
- real_backend = 'simple'
+ real_backend = "simple"
def _install_mock_cache(self, template, implname=None):
- template.cache_impl = 'mock'
+ template.cache_impl = "mock"
impl = template.cache.impl
impl.set_backend(template.cache, implname or self.real_backend)
return impl
def test_def(self):
- t = Template("""
+ t = Template(
+ """
<%!
callcount = [0]
%>
@@ -106,18 +108,20 @@ class CacheTest(TemplateTest):
${foo()}
${foo()}
callcount: ${callcount}
-""")
+"""
+ )
m = self._install_mock_cache(t)
assert result_lines(t.render()) == [
- 'this is foo',
- 'this is foo',
- 'this is foo',
- 'callcount: [1]',
+ "this is foo",
+ "this is foo",
+ "this is foo",
+ "callcount: [1]",
]
assert m.kwargs == {}
def test_cache_enable(self):
- t = Template("""
+ t = Template(
+ """
<%!
callcount = [0]
%>
@@ -127,13 +131,16 @@ class CacheTest(TemplateTest):
${foo()}
${foo()}
callcount: ${callcount}
- """, cache_enabled=False)
+ """,
+ cache_enabled=False,
+ )
self._install_mock_cache(t)
eq_(t.render().strip(), "callcount: [2]")
def test_nested_def(self):
- t = Template("""
+ t = Template(
+ """
<%!
callcount = [0]
%>
@@ -151,18 +158,20 @@ class CacheTest(TemplateTest):
${foo()}
${foo()}
callcount: ${callcount}
-""")
+"""
+ )
m = self._install_mock_cache(t)
assert result_lines(t.render()) == [
- 'this is foo',
- 'this is foo',
- 'this is foo',
- 'callcount: [1]',
+ "this is foo",
+ "this is foo",
+ "this is foo",
+ "callcount: [1]",
]
assert m.kwargs == {}
def test_page(self):
- t = Template("""
+ t = Template(
+ """
<%!
callcount = [0]
%>
@@ -172,85 +181,89 @@ class CacheTest(TemplateTest):
callcount[0] += 1
%>
callcount: ${callcount}
-""")
+"""
+ )
m = self._install_mock_cache(t)
t.render()
t.render()
- assert result_lines(t.render()) == [
- "this is foo",
- "callcount: [1]"
- ]
+ assert result_lines(t.render()) == ["this is foo", "callcount: [1]"]
assert m.kwargs == {}
def test_dynamic_key_with_context(self):
- t = Template("""
+ t = Template(
+ """
<%block name="foo" cached="True" cache_key="${mykey}">
some block
</%block>
- """)
+ """
+ )
m = self._install_mock_cache(t)
t.render(mykey="thekey")
t.render(mykey="thekey")
- eq_(
- result_lines(t.render(mykey="thekey")),
- ["some block"]
- )
+ eq_(result_lines(t.render(mykey="thekey")), ["some block"])
eq_(m.key, "thekey")
- t = Template("""
+ t = Template(
+ """
<%def name="foo()" cached="True" cache_key="${mykey}">
some def
</%def>
${foo()}
- """)
+ """
+ )
m = self._install_mock_cache(t)
t.render(mykey="thekey")
t.render(mykey="thekey")
- eq_(
- result_lines(t.render(mykey="thekey")),
- ["some def"]
- )
+ eq_(result_lines(t.render(mykey="thekey")), ["some def"])
eq_(m.key, "thekey")
def test_dynamic_key_with_funcargs(self):
- t = Template("""
+ t = Template(
+ """
<%def name="foo(num=5)" cached="True" cache_key="foo_${str(num)}">
hi
</%def>
${foo()}
- """)
+ """
+ )
m = self._install_mock_cache(t)
t.render()
t.render()
- assert result_lines(t.render()) == ['hi']
+ assert result_lines(t.render()) == ["hi"]
assert m.key == "foo_5"
- t = Template("""
+ t = Template(
+ """
<%def name="foo(*args, **kwargs)" cached="True"
cache_key="foo_${kwargs['bar']}">
hi
</%def>
${foo(1, 2, bar='lala')}
- """)
+ """
+ )
m = self._install_mock_cache(t)
t.render()
- assert result_lines(t.render()) == ['hi']
+ assert result_lines(t.render()) == ["hi"]
assert m.key == "foo_lala"
- t = Template('''
+ t = Template(
+ """
<%page args="bar='hi'" cache_key="foo_${bar}" cached="True"/>
hi
- ''')
+ """
+ )
m = self._install_mock_cache(t)
t.render()
- assert result_lines(t.render()) == ['hi']
+ assert result_lines(t.render()) == ["hi"]
assert m.key == "foo_hi"
def test_dynamic_key_with_imports(self):
lookup = TemplateLookup()
- lookup.put_string("foo.html", """
+ lookup.put_string(
+ "foo.html",
+ """
<%!
callcount = [0]
%>
@@ -261,21 +274,24 @@ class CacheTest(TemplateTest):
callcount[0] += 1
%>
callcount: ${callcount}
-""")
+""",
+ )
lookup.put_string("ns.html", """""")
t = lookup.get_template("foo.html")
m = self._install_mock_cache(t)
- t.render(foo='somekey')
- t.render(foo='somekey')
- assert result_lines(t.render(foo='somekey')) == [
+ t.render(foo="somekey")
+ t.render(foo="somekey")
+ assert result_lines(t.render(foo="somekey")) == [
"this is foo",
- "callcount: [1]"
+ "callcount: [1]",
]
assert m.kwargs == {}
def test_fileargs_implicit(self):
l = lookup.TemplateLookup(module_directory=module_base)
- l.put_string("test", """
+ l.put_string(
+ "test",
+ """
<%!
callcount = [0]
%>
@@ -290,19 +306,21 @@ class CacheTest(TemplateTest):
${foo()}
${foo()}
callcount: ${callcount}
- """)
-
- m = self._install_mock_cache(l.get_template('test'))
- assert result_lines(l.get_template('test').render()) == [
- 'this is foo',
- 'this is foo',
- 'this is foo',
- 'callcount: [1]',
+ """,
+ )
+
+ m = self._install_mock_cache(l.get_template("test"))
+ assert result_lines(l.get_template("test").render()) == [
+ "this is foo",
+ "this is foo",
+ "this is foo",
+ "callcount: [1]",
]
- eq_(m.kwargs, {'type': 'dbm'})
+ eq_(m.kwargs, {"type": "dbm"})
def test_fileargs_deftag(self):
- t = Template("""
+ t = Template(
+ """
<%%!
callcount = [0]
%%>
@@ -317,18 +335,21 @@ class CacheTest(TemplateTest):
${foo()}
${foo()}
callcount: ${callcount}
-""" % module_base)
+"""
+ % module_base
+ )
m = self._install_mock_cache(t)
assert result_lines(t.render()) == [
- 'this is foo',
- 'this is foo',
- 'this is foo',
- 'callcount: [1]',
+ "this is foo",
+ "this is foo",
+ "this is foo",
+ "callcount: [1]",
]
- assert m.kwargs == {'type': 'file', 'dir': module_base}
+ assert m.kwargs == {"type": "file", "dir": module_base}
def test_fileargs_pagetag(self):
- t = Template("""
+ t = Template(
+ """
<%%page cache_dir='%s' cache_type='dbm'/>
<%%!
callcount = [0]
@@ -344,41 +365,51 @@ class CacheTest(TemplateTest):
${foo()}
${foo()}
callcount: ${callcount}
-""" % module_base)
+"""
+ % module_base
+ )
m = self._install_mock_cache(t)
assert result_lines(t.render()) == [
- 'this is foo',
- 'this is foo',
- 'this is foo',
- 'callcount: [1]',
+ "this is foo",
+ "this is foo",
+ "this is foo",
+ "callcount: [1]",
]
- eq_(m.kwargs, {'dir': module_base, 'type': 'dbm'})
+ eq_(m.kwargs, {"dir": module_base, "type": "dbm"})
def test_args_complete(self):
- t = Template("""
+ t = Template(
+ """
<%%def name="foo()" cached="True" cache_timeout="30" cache_dir="%s"
cache_type="file" cache_key='somekey'>
this is foo
</%%def>
${foo()}
-""" % module_base)
+"""
+ % module_base
+ )
m = self._install_mock_cache(t)
t.render()
- eq_(m.kwargs, {'dir': module_base, 'type': 'file', 'timeout': 30})
+ eq_(m.kwargs, {"dir": module_base, "type": "file", "timeout": 30})
- t2 = Template("""
+ t2 = Template(
+ """
<%%page cached="True" cache_timeout="30" cache_dir="%s"
cache_type="file" cache_key='somekey'/>
hi
- """ % module_base)
+ """
+ % module_base
+ )
m = self._install_mock_cache(t2)
t2.render()
- eq_(m.kwargs, {'dir': module_base, 'type': 'file', 'timeout': 30})
+ eq_(m.kwargs, {"dir": module_base, "type": "file", "timeout": 30})
def test_fileargs_lookup(self):
- l = lookup.TemplateLookup(cache_dir=module_base, cache_type='file')
- l.put_string("test", """
+ l = lookup.TemplateLookup(cache_dir=module_base, cache_type="file")
+ l.put_string(
+ "test",
+ """
<%!
callcount = [0]
%>
@@ -393,20 +424,22 @@ class CacheTest(TemplateTest):
${foo()}
${foo()}
callcount: ${callcount}
- """)
+ """,
+ )
- t = l.get_template('test')
+ t = l.get_template("test")
m = self._install_mock_cache(t)
- assert result_lines(l.get_template('test').render()) == [
- 'this is foo',
- 'this is foo',
- 'this is foo',
- 'callcount: [1]',
+ assert result_lines(l.get_template("test").render()) == [
+ "this is foo",
+ "this is foo",
+ "this is foo",
+ "callcount: [1]",
]
- eq_(m.kwargs, {'dir': module_base, 'type': 'file'})
+ eq_(m.kwargs, {"dir": module_base, "type": "file"})
def test_buffered(self):
- t = Template("""
+ t = Template(
+ """
<%!
def a(text):
return "this is a " + text.strip()
@@ -416,11 +449,13 @@ class CacheTest(TemplateTest):
<%def name="foo()" cached="True" buffered="True">
this is a test
</%def>
- """, buffer_filters=["a"])
+ """,
+ buffer_filters=["a"],
+ )
self._install_mock_cache(t)
eq_(
result_lines(t.render()),
- ["this is a this is a test", "this is a this is a test"]
+ ["this is a this is a test", "this is a this is a test"],
)
def test_load_from_expired(self):
@@ -428,12 +463,14 @@ class CacheTest(TemplateTest):
originating template has completed rendering.
"""
- t = Template("""
+ t = Template(
+ """
${foo()}
<%def name="foo()" cached="True" cache_timeout="1">
foo
</%def>
- """)
+ """
+ )
self._install_mock_cache(t)
x1 = t.render()
@@ -442,7 +479,8 @@ class CacheTest(TemplateTest):
assert x1.strip() == x2.strip() == "foo"
def test_namespace_access(self):
- t = Template("""
+ t = Template(
+ """
<%def name="foo(x)" cached="True">
foo: ${x}
</%def>
@@ -454,19 +492,20 @@ class CacheTest(TemplateTest):
foo(3)
foo(4)
%>
- """)
- self._install_mock_cache(t)
- eq_(
- result_lines(t.render()),
- ['foo: 1', 'foo: 1', 'foo: 3', 'foo: 3']
+ """
)
+ self._install_mock_cache(t)
+ eq_(result_lines(t.render()), ["foo: 1", "foo: 1", "foo: 3", "foo: 3"])
def test_lookup(self):
- l = TemplateLookup(cache_impl='mock')
- l.put_string("x", """
+ l = TemplateLookup(cache_impl="mock")
+ l.put_string(
+ "x",
+ """
<%page cached="True" />
${y}
- """)
+ """,
+ )
t = l.get_template("x")
self._install_mock_cache(t)
assert result_lines(t.render(y=5)) == ["5"]
@@ -474,7 +513,8 @@ class CacheTest(TemplateTest):
assert isinstance(t.cache.impl, MockCacheImpl)
def test_invalidate(self):
- t = Template("""
+ t = Template(
+ """
<%%def name="foo()" cached="True">
foo: ${x}
</%%def>
@@ -483,20 +523,25 @@ class CacheTest(TemplateTest):
bar: ${x}
</%%def>
${foo()} ${bar()}
- """ % module_base)
+ """
+ % module_base
+ )
self._install_mock_cache(t)
assert result_lines(t.render(x=1)) == ["foo: 1", "bar: 1"]
assert result_lines(t.render(x=2)) == ["foo: 1", "bar: 1"]
- t.cache.invalidate_def('foo')
+ t.cache.invalidate_def("foo")
assert result_lines(t.render(x=3)) == ["foo: 3", "bar: 1"]
- t.cache.invalidate_def('bar')
+ t.cache.invalidate_def("bar")
assert result_lines(t.render(x=4)) == ["foo: 3", "bar: 4"]
- t = Template("""
+ t = Template(
+ """
<%%page cached="True" cache_type="dbm" cache_dir="%s"/>
page: ${x}
- """ % module_base)
+ """
+ % module_base
+ )
self._install_mock_cache(t)
assert result_lines(t.render(x=1)) == ["page: 1"]
assert result_lines(t.render(x=2)) == ["page: 1"]
@@ -505,66 +550,67 @@ class CacheTest(TemplateTest):
assert result_lines(t.render(x=4)) == ["page: 3"]
def test_custom_args_def(self):
- t = Template("""
+ t = Template(
+ """
<%def name="foo()" cached="True" cache_region="myregion"
cache_timeout="50" cache_foo="foob">
</%def>
${foo()}
- """)
- m = self._install_mock_cache(t, 'simple')
+ """
+ )
+ m = self._install_mock_cache(t, "simple")
t.render()
- eq_(
- m.kwargs,
- {'region': 'myregion',
- 'timeout': 50, 'foo': 'foob'})
+ eq_(m.kwargs, {"region": "myregion", "timeout": 50, "foo": "foob"})
def test_custom_args_block(self):
- t = Template("""
+ t = Template(
+ """
<%block name="foo" cached="True" cache_region="myregion"
cache_timeout="50" cache_foo="foob">
</%block>
- """)
+ """
+ )
m = self._install_mock_cache(t, "simple")
t.render()
- eq_(
- m.kwargs,
- {'region': 'myregion',
- 'timeout': 50, 'foo': 'foob'})
+ eq_(m.kwargs, {"region": "myregion", "timeout": 50, "foo": "foob"})
def test_custom_args_page(self):
- t = Template("""
+ t = Template(
+ """
<%page cached="True" cache_region="myregion"
cache_timeout="50" cache_foo="foob"/>
- """)
+ """
+ )
m = self._install_mock_cache(t, "simple")
t.render()
- eq_(
- m.kwargs,
- {'region': 'myregion',
- 'timeout': 50, 'foo': 'foob'})
+ eq_(m.kwargs, {"region": "myregion", "timeout": 50, "foo": "foob"})
def test_pass_context(self):
- t = Template("""
+ t = Template(
+ """
<%page cached="True"/>
- """)
+ """
+ )
m = self._install_mock_cache(t)
t.render()
- assert 'context' not in m.kwargs
+ assert "context" not in m.kwargs
m.pass_context = True
t.render(x="bar")
- assert 'context' in m.kwargs
- assert m.kwargs['context'].get('x') == 'bar'
+ assert "context" in m.kwargs
+ assert m.kwargs["context"].get("x") == "bar"
class RealBackendTest(object):
def test_cache_uses_current_context(self):
- t = Template("""
+ t = Template(
+ """
${foo()}
<%def name="foo()" cached="True" cache_timeout="1">
foo: ${x}
</%def>
- """)
+ """
+ )
self._install_mock_cache(t)
x1 = t.render(x=1)
@@ -585,7 +631,8 @@ class RealBackendTest(object):
<%block name="lala">
none ${x}
</%block>
- """)
+ """
+ )
self._install_mock_cache(t)
r1 = result_lines(t.render(x=5))
@@ -598,7 +645,7 @@ class RealBackendTest(object):
class BeakerCacheTest(RealBackendTest, CacheTest):
- real_backend = 'beaker'
+ real_backend = "beaker"
def setUp(self):
if not beaker_cache.has_beaker:
@@ -607,28 +654,23 @@ class BeakerCacheTest(RealBackendTest, CacheTest):
raise SkipTest("newer beakers not working w/ py26")
def _install_mock_cache(self, template, implname=None):
- template.cache_args['manager'] = self._regions()
+ template.cache_args["manager"] = self._regions()
impl = super(BeakerCacheTest, self)._install_mock_cache(
- template, implname)
+ template, implname
+ )
return impl
def _regions(self):
return beaker.cache.CacheManager(
cache_regions={
- 'short': {
- 'expire': 1,
- 'type': 'memory'
- },
- 'long': {
- 'expire': 60,
- 'type': 'memory'
- }
+ "short": {"expire": 1, "type": "memory"},
+ "long": {"expire": 60, "type": "memory"},
}
)
class DogpileCacheTest(RealBackendTest, CacheTest):
- real_backend = 'dogpile.cache'
+ real_backend = "dogpile.cache"
def setUp(self):
try:
@@ -637,10 +679,11 @@ class DogpileCacheTest(RealBackendTest, CacheTest):
raise SkipTest("dogpile.cache is required to run these tests")
def _install_mock_cache(self, template, implname=None):
- template.cache_args['regions'] = self._regions()
- template.cache_args.setdefault('region', 'short')
+ template.cache_args["regions"] = self._regions()
+ template.cache_args.setdefault("region", "short")
impl = super(DogpileCacheTest, self)._install_mock_cache(
- template, implname)
+ template, implname
+ )
return impl
def _regions(self):
@@ -648,17 +691,14 @@ class DogpileCacheTest(RealBackendTest, CacheTest):
my_regions = {
"short": make_region().configure(
- "dogpile.cache.memory",
- expiration_time=1
+ "dogpile.cache.memory", expiration_time=1
),
"long": make_region().configure(
- "dogpile.cache.memory",
- expiration_time=60
+ "dogpile.cache.memory", expiration_time=60
),
"myregion": make_region().configure(
- "dogpile.cache.memory",
- expiration_time=60
- )
+ "dogpile.cache.memory", expiration_time=60
+ ),
}
return my_regions
diff --git a/test/test_call.py b/test/test_call.py
index 5071222..36d15dc 100644
--- a/test/test_call.py
+++ b/test/test_call.py
@@ -1,11 +1,14 @@
from mako.template import Template
-from mako import util
-from test.util import result_lines, flatten_result
-from test import TemplateTest, eq_
+from test import eq_
+from test import TemplateTest
+from test.util import flatten_result
+from test.util import result_lines
+
class CallTest(TemplateTest):
def test_call(self):
- t = Template("""
+ t = Template(
+ """
<%def name="foo()">
hi im foo ${caller.body(y=5)}
</%def>
@@ -13,12 +16,16 @@ class CallTest(TemplateTest):
<%call expr="foo()" args="y, **kwargs">
this is the body, y is ${y}
</%call>
-""")
- assert result_lines(t.render()) == ['hi im foo', 'this is the body, y is 5']
-
+"""
+ )
+ assert result_lines(t.render()) == [
+ "hi im foo",
+ "this is the body, y is 5",
+ ]
def test_compound_call(self):
- t = Template("""
+ t = Template(
+ """
<%def name="bar()">
this is bar
@@ -41,16 +48,26 @@ class CallTest(TemplateTest):
</%call>
${bar()}
-""")
- assert result_lines(t.render()) == ['foo calling comp1:', 'this is comp1, 5', 'foo calling body:', 'this is the body,', 'this is comp1, 6', 'this is bar']
+"""
+ )
+ assert result_lines(t.render()) == [
+ "foo calling comp1:",
+ "this is comp1, 5",
+ "foo calling body:",
+ "this is the body,",
+ "this is comp1, 6",
+ "this is bar",
+ ]
def test_new_syntax(self):
- """test foo:bar syntax, including multiline args and expression eval."""
+ """test foo:bar syntax, including multiline args and expression
+ eval."""
# note the trailing whitespace in the bottom ${} expr, need to strip
# that off < python 2.7
- t = Template("""
+ t = Template(
+ """
<%def name="foo(x, y, q, z)">
${x}
${y}
@@ -70,15 +87,17 @@ class CallTest(TemplateTest):
]
}"/>
- """)
+ """
+ )
eq_(
result_lines(t.render()),
- ['this is x', 'some y', 'this', 'is', 'q', '1->2,3->4,5->6']
+ ["this is x", "some y", "this", "is", "q", "1->2,3->4,5->6"],
)
def test_ccall_caller(self):
- t = Template("""
+ t = Template(
+ """
<%def name="outer_func()">
OUTER BEGIN
<%call expr="caller.inner_func()">
@@ -95,8 +114,9 @@ class CallTest(TemplateTest):
</%def>
</%call>
- """)
- #print t.code
+ """
+ )
+ # print t.code
assert result_lines(t.render()) == [
"OUTER BEGIN",
"INNER BEGIN",
@@ -106,7 +126,8 @@ class CallTest(TemplateTest):
]
def test_stack_pop(self):
- t = Template("""
+ t = Template(
+ """
<%def name="links()" buffered="True">
Some links
</%def>
@@ -122,19 +143,22 @@ class CallTest(TemplateTest):
Some title
</%call>
- """)
+ """
+ )
assert result_lines(t.render()) == [
- "<h1>",
- "Some title",
- "</h1>",
- "Some links"
+ "<h1>",
+ "Some title",
+ "</h1>",
+ "Some links",
]
def test_conditional_call(self):
- """test that 'caller' is non-None only if the immediate <%def> was called via <%call>"""
+ """test that 'caller' is non-None only if the immediate <%def> was
+ called via <%call>"""
- t = Template("""
+ t = Template(
+ """
<%def name="a()">
% if caller:
${ caller.body() } \\
@@ -162,17 +186,14 @@ class CallTest(TemplateTest):
CALL
</%call>
- """)
- assert result_lines(t.render()) == [
- "CALL",
- "AAA",
- "BBB",
- "CCC"
- ]
+ """
+ )
+ assert result_lines(t.render()) == ["CALL", "AAA", "BBB", "CCC"]
def test_chained_call(self):
"""test %calls that are chained through their targets"""
- t = Template("""
+ t = Template(
+ """
<%def name="a()">
this is a.
<%call expr="b()">
@@ -189,19 +210,21 @@ class CallTest(TemplateTest):
heres the main templ call
</%call>
-""")
+"""
+ )
assert result_lines(t.render()) == [
- 'this is a.',
- 'this is b. heres my body:',
+ "this is a.",
+ "this is b. heres my body:",
"this is a's ccall. heres my body:",
- 'heres the main templ call',
+ "heres the main templ call",
"whats in the body's caller's body ?",
- 'heres the main templ call'
+ "heres the main templ call",
]
def test_nested_call(self):
"""test %calls that are nested inside each other"""
- t = Template("""
+ t = Template(
+ """
<%def name="foo()">
${caller.body(x=10)}
</%def>
@@ -218,16 +241,18 @@ class CallTest(TemplateTest):
this is bar body: ${x}
</%call>
</%call>
-""")
+"""
+ )
assert result_lines(t.render(x=5)) == [
"x is 5",
"this is foo body: 10",
"bar:",
- "this is bar body: 10"
+ "this is bar body: 10",
]
def test_nested_call_2(self):
- t = Template("""
+ t = Template(
+ """
x is ${x}
<%def name="foo()">
${caller.foosub(x=10)}
@@ -250,16 +275,18 @@ class CallTest(TemplateTest):
</%def>
</%call>
-""")
+"""
+ )
assert result_lines(t.render(x=5)) == [
"x is 5",
"this is foo body: 10",
"bar:",
- "this is bar body: 10"
+ "this is bar body: 10",
]
def test_nested_call_3(self):
- template = Template('''\
+ template = Template(
+ """\
<%def name="A()">
${caller.body()}
</%def>
@@ -276,7 +303,8 @@ class CallTest(TemplateTest):
</%call>
</%call>
- ''')
+ """
+ )
assert flatten_result(template.render()) == "foo"
def test_nested_call_4(self):
@@ -292,7 +320,9 @@ class CallTest(TemplateTest):
</%def>
"""
- template = Template(base + """
+ template = Template(
+ base
+ + """
<%def name="C()">
C_def
<%self:B>
@@ -307,14 +337,17 @@ class CallTest(TemplateTest):
<%self:C>
C_body
</%self:C>
- """)
+ """
+ )
eq_(
flatten_result(template.render()),
- "C_def B_def A_def A_body B_body C_body"
+ "C_def B_def A_def A_body B_body C_body",
)
- template = Template(base + """
+ template = Template(
+ base
+ + """
<%def name="C()">
C_def
<%self:B>
@@ -329,15 +362,17 @@ class CallTest(TemplateTest):
<%self:C>
C_body
</%self:C>
- """)
+ """
+ )
eq_(
flatten_result(template.render()),
- "C_def B_def B_body C_body A_def A_body"
+ "C_def B_def B_body C_body A_def A_body",
)
def test_chained_call_in_nested(self):
- t = Template("""
+ t = Template(
+ """
<%def name="embedded()">
<%def name="a()">
this is a.
@@ -347,7 +382,8 @@ class CallTest(TemplateTest):
</%def>
<%def name="b()">
this is b. heres my body: ${caller.body()}
- whats in the body's caller's body ? ${context.caller_stack[-2].body()}
+ whats in the body's caller's body ? """
+ """${context.caller_stack[-2].body()}
</%def>
<%call expr="a()">
@@ -355,20 +391,22 @@ class CallTest(TemplateTest):
</%call>
</%def>
${embedded()}
-""")
- #print t.code
- #print result_lines(t.render())
+"""
+ )
+ # print t.code
+ # print result_lines(t.render())
assert result_lines(t.render()) == [
- 'this is a.',
- 'this is b. heres my body:',
+ "this is a.",
+ "this is b. heres my body:",
"this is a's ccall. heres my body:",
- 'heres the main templ call',
+ "heres the main templ call",
"whats in the body's caller's body ?",
- 'heres the main templ call'
+ "heres the main templ call",
]
def test_call_in_nested(self):
- t = Template("""
+ t = Template(
+ """
<%def name="a()">
this is a ${b()}
<%def name="b()">
@@ -382,22 +420,31 @@ class CallTest(TemplateTest):
</%def>
</%def>
${a()}
-""")
- assert result_lines(t.render()) == ['this is a', 'this is b', 'this is c:', "this is the body in b's call"]
+"""
+ )
+ assert result_lines(t.render()) == [
+ "this is a",
+ "this is b",
+ "this is c:",
+ "this is the body in b's call",
+ ]
def test_composed_def(self):
- t = Template("""
+ t = Template(
+ """
<%def name="f()"><f>${caller.body()}</f></%def>
<%def name="g()"><g>${caller.body()}</g></%def>
<%def name="fg()">
<%self:f><%self:g>${caller.body()}</%self:g></%self:f>
</%def>
<%self:fg>fgbody</%self:fg>
- """)
- assert result_lines(t.render()) == ['<f><g>fgbody</g></f>']
+ """
+ )
+ assert result_lines(t.render()) == ["<f><g>fgbody</g></f>"]
def test_regular_defs(self):
- t = Template("""
+ t = Template(
+ """
<%!
@runtime.supports_caller
def a(context):
@@ -430,7 +477,8 @@ class CallTest(TemplateTest):
</%call>
- """)
+ """
+ )
assert result_lines(t.render()) == [
"test 1",
"this is a",
@@ -449,11 +497,12 @@ class CallTest(TemplateTest):
"our body:",
"this is the nested body",
"this is aa is done",
- "this is aa is done"
+ "this is aa is done",
]
def test_call_in_nested_2(self):
- t = Template("""
+ t = Template(
+ """
<%def name="a()">
<%def name="d()">
not this d
@@ -477,14 +526,24 @@ class CallTest(TemplateTest):
</%def>
</%def>
${a()}
-""")
- assert result_lines(t.render()) == ['this is a', 'this is b', 'this is c:', "this is the body in b's call", 'the embedded "d" is:', 'this is d']
+"""
+ )
+ assert result_lines(t.render()) == [
+ "this is a",
+ "this is b",
+ "this is c:",
+ "this is the body in b's call",
+ 'the embedded "d" is:',
+ "this is d",
+ ]
+
class SelfCacheTest(TemplateTest):
"""this test uses a now non-public API."""
def test_basic(self):
- t = Template("""
+ t = Template(
+ """
<%!
cached = None
%>
@@ -505,10 +564,10 @@ class SelfCacheTest(TemplateTest):
${foo()}
${foo()}
-""")
+"""
+ )
assert result_lines(t.render()) == [
"this is foo",
"cached:",
- "this is foo"
+ "this is foo",
]
-
diff --git a/test/test_cmd.py b/test/test_cmd.py
index a2adbf9..ac0db25 100644
--- a/test/test_cmd.py
+++ b/test/test_cmd.py
@@ -1,8 +1,15 @@
from __future__ import with_statement
+
from contextlib import contextmanager
-from test import TemplateTest, eq_, raises, template_base, mock
import os
+
from mako.cmd import cmdline
+from test import eq_
+from test import mock
+from test import raises
+from test import template_base
+from test import TemplateTest
+
class CmdTest(TemplateTest):
@contextmanager
@@ -12,27 +19,31 @@ class CmdTest(TemplateTest):
def test_stdin_success(self):
with self._capture_output_fixture() as stdout:
- with mock.patch("sys.stdin", mock.Mock(
- read=mock.Mock(return_value="hello world ${x}"))):
+ with mock.patch(
+ "sys.stdin",
+ mock.Mock(read=mock.Mock(return_value="hello world ${x}")),
+ ):
cmdline(["--var", "x=5", "-"])
eq_(stdout.write.mock_calls[0][1][0], "hello world 5")
def test_stdin_syntax_err(self):
- with mock.patch("sys.stdin", mock.Mock(
- read=mock.Mock(return_value="${x"))):
+ with mock.patch(
+ "sys.stdin", mock.Mock(read=mock.Mock(return_value="${x"))
+ ):
with self._capture_output_fixture("stderr") as stderr:
with raises(SystemExit):
cmdline(["--var", "x=5", "-"])
- assert "SyntaxException: Expected" in \
- stderr.write.mock_calls[0][1][0]
+ assert (
+ "SyntaxException: Expected" in stderr.write.mock_calls[0][1][0]
+ )
assert "Traceback" in stderr.write.mock_calls[0][1][0]
-
def test_stdin_rt_err(self):
- with mock.patch("sys.stdin", mock.Mock(
- read=mock.Mock(return_value="${q}"))):
+ with mock.patch(
+ "sys.stdin", mock.Mock(read=mock.Mock(return_value="${q}"))
+ ):
with self._capture_output_fixture("stderr") as stderr:
with raises(SystemExit):
cmdline(["--var", "x=5", "-"])
@@ -42,16 +53,22 @@ class CmdTest(TemplateTest):
def test_file_success(self):
with self._capture_output_fixture() as stdout:
- cmdline(["--var", "x=5",
- os.path.join(template_base, "cmd_good.mako")])
+ cmdline(
+ ["--var", "x=5", os.path.join(template_base, "cmd_good.mako")]
+ )
eq_(stdout.write.mock_calls[0][1][0], "hello world 5")
def test_file_syntax_err(self):
with self._capture_output_fixture("stderr") as stderr:
with raises(SystemExit):
- cmdline(["--var", "x=5",
- os.path.join(template_base, "cmd_syntax.mako")])
+ cmdline(
+ [
+ "--var",
+ "x=5",
+ os.path.join(template_base, "cmd_syntax.mako"),
+ ]
+ )
assert "SyntaxException: Expected" in stderr.write.mock_calls[0][1][0]
assert "Traceback" in stderr.write.mock_calls[0][1][0]
@@ -59,14 +76,17 @@ class CmdTest(TemplateTest):
def test_file_rt_err(self):
with self._capture_output_fixture("stderr") as stderr:
with raises(SystemExit):
- cmdline(["--var", "x=5",
- os.path.join(template_base, "cmd_runtime.mako")])
+ cmdline(
+ [
+ "--var",
+ "x=5",
+ os.path.join(template_base, "cmd_runtime.mako"),
+ ]
+ )
assert "NameError: Undefined" in stderr.write.mock_calls[0][1][0]
assert "Traceback" in stderr.write.mock_calls[0][1][0]
-
def test_file_notfound(self):
with raises(SystemExit, "error: can't find fake.lalala"):
cmdline(["--var", "x=5", "fake.lalala"])
-
diff --git a/test/test_decorators.py b/test/test_decorators.py
index a3fa8f5..195a636 100644
--- a/test/test_decorators.py
+++ b/test/test_decorators.py
@@ -1,15 +1,18 @@
-from mako.template import Template
-from mako import lookup
import unittest
-from test.util import flatten_result, result_lines
+
+from mako.template import Template
+from test.util import flatten_result
+
class DecoratorTest(unittest.TestCase):
def test_toplevel(self):
- template = Template("""
+ template = Template(
+ """
<%!
def bar(fn):
def decorate(context, *args, **kw):
- return "BAR" + runtime.capture(context, fn, *args, **kw) + "BAR"
+ return "BAR" + runtime.capture"""
+ """(context, fn, *args, **kw) + "BAR"
return decorate
%>
@@ -18,12 +21,14 @@ class DecoratorTest(unittest.TestCase):
</%def>
${foo(1, x=5)}
- """)
+ """
+ )
assert flatten_result(template.render()) == "BAR this is foo 1 5 BAR"
def test_toplevel_contextual(self):
- template = Template("""
+ template = Template(
+ """
<%!
def bar(fn):
def decorate(context):
@@ -39,15 +44,19 @@ class DecoratorTest(unittest.TestCase):
</%def>
${foo()}
- """)
+ """
+ )
assert flatten_result(template.render()) == "BAR this is foo BAR"
- assert flatten_result(template.get_def('foo').render()) == "BAR this is foo BAR"
-
+ assert (
+ flatten_result(template.get_def("foo").render())
+ == "BAR this is foo BAR"
+ )
def test_nested(self):
- template = Template("""
+ template = Template(
+ """
<%!
def bat(fn):
def decorate(context):
@@ -64,16 +73,19 @@ class DecoratorTest(unittest.TestCase):
</%def>
${foo()}
- """)
+ """
+ )
assert flatten_result(template.render()) == "BAT this is bar BAT"
def test_toplevel_decorated_name(self):
- template = Template("""
+ template = Template(
+ """
<%!
def bar(fn):
def decorate(context, *args, **kw):
- return "function " + fn.__name__ + " " + runtime.capture(context, fn, *args, **kw)
+ return "function " + fn.__name__ + """
+ """" " + runtime.capture(context, fn, *args, **kw)
return decorate
%>
@@ -82,16 +94,21 @@ class DecoratorTest(unittest.TestCase):
</%def>
${foo(1, x=5)}
- """)
+ """
+ )
- assert flatten_result(template.render()) == "function foo this is foo 1 5"
+ assert (
+ flatten_result(template.render()) == "function foo this is foo 1 5"
+ )
def test_nested_decorated_name(self):
- template = Template("""
+ template = Template(
+ """
<%!
def bat(fn):
def decorate(context):
- return "function " + fn.__name__ + " " + runtime.capture(context, fn)
+ return "function " + fn.__name__ + " " + """
+ """runtime.capture(context, fn)
return decorate
%>
@@ -104,7 +121,7 @@ class DecoratorTest(unittest.TestCase):
</%def>
${foo()}
- """)
+ """
+ )
assert flatten_result(template.render()) == "function bar this is bar"
-
diff --git a/test/test_def.py b/test/test_def.py
index 19142c8..99b929d 100644
--- a/test/test_def.py
+++ b/test/test_def.py
@@ -1,13 +1,18 @@
-from mako.template import Template
+from mako import compat
from mako import lookup
+from mako.template import Template
+from test import assert_raises
+from test import eq_
+from test import requires_python_3
from test import TemplateTest
-from test.util import flatten_result, result_lines
-from test import eq_, assert_raises, requires_python_3
-from mako import compat
+from test.util import flatten_result
+from test.util import result_lines
+
class DefTest(TemplateTest):
def test_def_noargs(self):
- template = Template("""
+ template = Template(
+ """
${mycomp()}
@@ -15,52 +20,55 @@ class DefTest(TemplateTest):
hello mycomp ${variable}
</%def>
- """)
- eq_(
- template.render(variable='hi').strip(),
- """hello mycomp hi"""
+ """
)
+ eq_(template.render(variable="hi").strip(), """hello mycomp hi""")
def test_def_blankargs(self):
- template = Template("""
+ template = Template(
+ """
<%def name="mycomp()">
hello mycomp ${variable}
</%def>
- ${mycomp()}""")
- eq_(
- template.render(variable='hi').strip(),
- "hello mycomp hi"
+ ${mycomp()}"""
)
+ eq_(template.render(variable="hi").strip(), "hello mycomp hi")
def test_def_args(self):
- template = Template("""
+ template = Template(
+ """
<%def name="mycomp(a, b)">
hello mycomp ${variable}, ${a}, ${b}
</%def>
- ${mycomp(5, 6)}""")
+ ${mycomp(5, 6)}"""
+ )
eq_(
- template.render(variable='hi', a=5, b=6).strip(),
- """hello mycomp hi, 5, 6"""
+ template.render(variable="hi", a=5, b=6).strip(),
+ """hello mycomp hi, 5, 6""",
)
@requires_python_3
def test_def_py3k_args(self):
- template = Template("""
+ template = Template(
+ """
<%def name="kwonly(one, two, *three, four, five=5, **six)">
- look at all these args: ${one} ${two} ${three[0]} ${four} ${five} ${six['seven']}
+ look at all these args: ${one} ${two} ${three[0]} """
+ """${four} ${five} ${six['seven']}
</%def>
- ${kwonly('one', 'two', 'three', four='four', seven='seven')}""")
+ ${kwonly('one', 'two', 'three', four='four', seven='seven')}"""
+ )
eq_(
template.render(one=1, two=2, three=(3,), six=6).strip(),
- """look at all these args: one two three four 5 seven"""
+ """look at all these args: one two three four 5 seven""",
)
def test_inter_def(self):
"""test defs calling each other"""
- template = Template("""
+ template = Template(
+ """
${b()}
<%def name="a()">\
@@ -75,7 +83,8 @@ class DefTest(TemplateTest):
<%def name="c()">
im c
</%def>
-""")
+"""
+ )
# check that "a" is declared in "b", but not in "c"
if compat.py3k:
assert "a" not in template.module.render_c.__code__.co_varnames
@@ -85,15 +94,13 @@ class DefTest(TemplateTest):
assert "a" in template.module.render_b.func_code.co_varnames
# then test output
- eq_(
- flatten_result(template.render()),
- "im b and heres a: im a"
- )
+ eq_(flatten_result(template.render()), "im b and heres a: im a")
def test_toplevel(self):
"""test calling a def from the top level"""
- template = Template("""
+ template = Template(
+ """
this is the body
@@ -105,28 +112,37 @@ class DefTest(TemplateTest):
this is b, ${x} ${y}
</%def>
- """)
+ """
+ )
- self._do_test(template.get_def("a"),
- "this is a",
- filters=flatten_result)
- self._do_test(template.get_def("b"),
- "this is b, 10 15",
- template_args={'x': 10, 'y': 15},
- filters=flatten_result)
- self._do_test(template.get_def("body"),
- "this is the body",
- filters=flatten_result)
+ self._do_test(
+ template.get_def("a"), "this is a", filters=flatten_result
+ )
+ self._do_test(
+ template.get_def("b"),
+ "this is b, 10 15",
+ template_args={"x": 10, "y": 15},
+ filters=flatten_result,
+ )
+ self._do_test(
+ template.get_def("body"),
+ "this is the body",
+ filters=flatten_result,
+ )
# test that args outside of the dict can be used
- self._do_test(template.get_def("a"), "this is a",
- filters=flatten_result,
- template_args={'q': 5, 'zq': 'test'})
+ self._do_test(
+ template.get_def("a"),
+ "this is a",
+ filters=flatten_result,
+ template_args={"q": 5, "zq": "test"},
+ )
def test_def_operations(self):
"""test get/list/has def"""
- template = Template("""
+ template = Template(
+ """
this is the body
@@ -138,14 +154,12 @@ class DefTest(TemplateTest):
this is b, ${x} ${y}
</%def>
- """)
+ """
+ )
assert template.get_def("a")
assert template.get_def("b")
- assert_raises(AttributeError,
- template.get_def,
- ("c")
- )
+ assert_raises(AttributeError, template.get_def, ("c"))
assert template.has_def("a")
assert template.has_def("b")
@@ -163,7 +177,8 @@ class ScopeTest(TemplateTest):
scope always takes precedence over contextual scope."""
def test_scope_one(self):
- self._do_memory_test("""
+ self._do_memory_test(
+ """
<%def name="a()">
this is a, and y is ${y}
</%def>
@@ -179,11 +194,12 @@ class ScopeTest(TemplateTest):
""",
"this is a, and y is None this is a, and y is 7",
filters=flatten_result,
- template_args={'y': None}
+ template_args={"y": None},
)
def test_scope_two(self):
- t = Template("""
+ t = Template(
+ """
y is ${y}
<%
@@ -191,7 +207,8 @@ class ScopeTest(TemplateTest):
%>
y is ${y}
-""")
+"""
+ )
try:
t.render(y=None)
assert False
@@ -201,7 +218,8 @@ class ScopeTest(TemplateTest):
def test_scope_four(self):
"""test that variables are pulled
from 'enclosing' scope before context."""
- t = Template("""
+ t = Template(
+ """
<%
x = 5
%>
@@ -218,17 +236,19 @@ class ScopeTest(TemplateTest):
</%def>
${b()}
-""")
+"""
+ )
eq_(
flatten_result(t.render()),
- "this is b. x is 9. calling a. this is a. x is 5."
+ "this is b. x is 9. calling a. this is a. x is 5.",
)
def test_scope_five(self):
"""test that variables are pulled from
'enclosing' scope before context."""
# same as test four, but adds a scope around it.
- t = Template("""
+ t = Template(
+ """
<%def name="enclosing()">
<%
x = 5
@@ -248,16 +268,18 @@ class ScopeTest(TemplateTest):
${b()}
</%def>
${enclosing()}
-""")
+"""
+ )
eq_(
flatten_result(t.render()),
- "this is b. x is 9. calling a. this is a. x is 5."
+ "this is b. x is 9. calling a. this is a. x is 5.",
)
def test_scope_six(self):
"""test that the initial context counts
as 'enclosing' scope, for plain defs"""
- t = Template("""
+ t = Template(
+ """
<%def name="a()">
a: x is ${x}
@@ -271,16 +293,15 @@ class ScopeTest(TemplateTest):
</%def>
${b()}
- """)
- eq_(
- flatten_result(t.render(x=5)),
- "b. x is 10. a: x is 5"
+ """
)
+ eq_(flatten_result(t.render(x=5)), "b. x is 10. a: x is 5")
def test_scope_seven(self):
"""test that the initial context counts
as 'enclosing' scope, for nested defs"""
- t = Template("""
+ t = Template(
+ """
<%def name="enclosing()">
<%def name="a()">
a: x is ${x}
@@ -296,16 +317,15 @@ class ScopeTest(TemplateTest):
${b()}
</%def>
${enclosing()}
- """)
- eq_(
- flatten_result(t.render(x=5)),
- "b. x is 10. a: x is 5"
+ """
)
+ eq_(flatten_result(t.render(x=5)), "b. x is 10. a: x is 5")
def test_scope_eight(self):
"""test that the initial context counts
as 'enclosing' scope, for nested defs"""
- t = Template("""
+ t = Template(
+ """
<%def name="enclosing()">
<%def name="a()">
a: x is ${x}
@@ -322,35 +342,40 @@ class ScopeTest(TemplateTest):
${b()}
</%def>
${enclosing()}
- """)
- eq_(
- flatten_result(t.render(x=5)),
- "b. x is 10. a: x is 5"
+ """
)
+ eq_(flatten_result(t.render(x=5)), "b. x is 10. a: x is 5")
def test_scope_nine(self):
"""test that 'enclosing scope' doesnt
get exported to other templates"""
l = lookup.TemplateLookup()
- l.put_string('main', """
+ l.put_string(
+ "main",
+ """
<%
x = 5
%>
this is main. <%include file="secondary"/>
-""")
+""",
+ )
- l.put_string('secondary', """
+ l.put_string(
+ "secondary",
+ """
this is secondary. x is ${x}
-""")
+""",
+ )
eq_(
- flatten_result(l.get_template('main').render(x=2)),
- "this is main. this is secondary. x is 2"
+ flatten_result(l.get_template("main").render(x=2)),
+ "this is main. this is secondary. x is 2",
)
def test_scope_ten(self):
- t = Template("""
+ t = Template(
+ """
<%def name="a()">
<%def name="b()">
<%
@@ -378,14 +403,16 @@ class ScopeTest(TemplateTest):
%>
main/a: ${a()}
main/y: ${y}
- """)
+ """
+ )
eq_(
flatten_result(t.render()),
- "main/a: a/y: 10 a/b: b/c: c/y: 10 b/y: 19 main/y: 7"
+ "main/a: a/y: 10 a/b: b/c: c/y: 10 b/y: 19 main/y: 7",
)
def test_scope_eleven(self):
- t = Template("""
+ t = Template(
+ """
x is ${x}
<%def name="a(x)">
this is a, ${b()}
@@ -395,17 +422,16 @@ class ScopeTest(TemplateTest):
</%def>
${a(x=5)}
-""")
+"""
+ )
eq_(
result_lines(t.render(x=10)),
- [
- "x is 10",
- "this is a,",
- "this is b, x is 5"
- ])
+ ["x is 10", "this is a,", "this is b, x is 5"],
+ )
def test_unbound_scope(self):
- t = Template("""
+ t = Template(
+ """
<%
y = 10
%>
@@ -418,14 +444,13 @@ class ScopeTest(TemplateTest):
y is ${y}
</%def>
${a()}
-""")
- assert_raises(
- UnboundLocalError,
- t.render
- )
+"""
+ )
+ assert_raises(UnboundLocalError, t.render)
def test_unbound_scope_two(self):
- t = Template("""
+ t = Template(
+ """
<%def name="enclosing()">
<%
y = 10
@@ -441,7 +466,8 @@ class ScopeTest(TemplateTest):
${a()}
</%def>
${enclosing()}
-""")
+"""
+ )
try:
print(t.render())
assert False
@@ -452,13 +478,18 @@ class ScopeTest(TemplateTest):
"""test that arguments passed to the body()
function are accessible by top-level defs"""
l = lookup.TemplateLookup()
- l.put_string("base", """
+ l.put_string(
+ "base",
+ """
${next.body(x=12)}
- """)
+ """,
+ )
- l.put_string("main", """
+ l.put_string(
+ "main",
+ """
<%inherit file="base"/>
<%page args="x"/>
this is main. x is ${x}
@@ -468,28 +499,28 @@ class ScopeTest(TemplateTest):
<%def name="a(**args)">
this is a, x is ${x}
</%def>
- """)
+ """,
+ )
# test via inheritance
eq_(
result_lines(l.get_template("main").render()),
- [
- "this is main. x is 12",
- "this is a, x is 12"
- ])
+ ["this is main. x is 12", "this is a, x is 12"],
+ )
- l.put_string("another", """
+ l.put_string(
+ "another",
+ """
<%namespace name="ns" file="main"/>
${ns.body(x=15)}
- """)
+ """,
+ )
# test via namespace
eq_(
result_lines(l.get_template("another").render()),
- [
- "this is main. x is 15",
- "this is a, x is 15"
- ])
+ ["this is main. x is 15", "this is a, x is 15"],
+ )
def test_inline_expression_from_arg_one(self):
"""test that cache_key=${foo} gets its value from
@@ -499,20 +530,20 @@ class ScopeTest(TemplateTest):
this is #191.
"""
- t = Template("""
+ t = Template(
+ """
<%def name="layout(foo)" cached="True" cache_key="${foo}">
foo: ${foo}
</%def>
${layout(3)}
- """, strict_undefined=True,
- cache_impl="plain")
-
- eq_(
- result_lines(t.render()),
- ["foo: 3"]
+ """,
+ strict_undefined=True,
+ cache_impl="plain",
)
+ eq_(result_lines(t.render()), ["foo: 3"])
+
def test_interpret_expression_from_arg_two(self):
"""test that cache_key=${foo} gets its value from
the 'foo' argument regardless of it being passed
@@ -522,26 +553,25 @@ class ScopeTest(TemplateTest):
to existing behavior before and after #191.
"""
- t = Template("""
+ t = Template(
+ """
<%def name="layout(foo)" cached="True" cache_key="${foo}">
foo: ${value}
</%def>
${layout(3)}
- """, cache_impl="plain")
-
- eq_(
- result_lines(t.render(foo='foo', value=1)),
- ["foo: 1"]
- )
- eq_(
- result_lines(t.render(foo='bar', value=2)),
- ["foo: 1"]
+ """,
+ cache_impl="plain",
)
+ eq_(result_lines(t.render(foo="foo", value=1)), ["foo: 1"])
+ eq_(result_lines(t.render(foo="bar", value=2)), ["foo: 1"])
+
+
class NestedDefTest(TemplateTest):
def test_nested_def(self):
- t = Template("""
+ t = Template(
+ """
${hi()}
@@ -557,14 +587,16 @@ class NestedDefTest(TemplateTest):
this is bar
</%def>
</%def>
-""")
+"""
+ )
eq_(
flatten_result(t.render()),
- "hey, im hi. and heres this is foo , this is bar"
+ "hey, im hi. and heres this is foo , this is bar",
)
def test_nested_2(self):
- t = Template("""
+ t = Template(
+ """
x is ${x}
<%def name="a()">
this is a, x is ${x}
@@ -574,15 +606,17 @@ class NestedDefTest(TemplateTest):
</%def>
</%def>
${a()}
-""")
+"""
+ )
eq_(
flatten_result(t.render(x=10)),
- "x is 10 this is a, x is 10 this is b: 10"
+ "x is 10 this is a, x is 10 this is b: 10",
)
def test_nested_with_args(self):
- t = Template("""
+ t = Template(
+ """
${a()}
<%def name="a()">
<%def name="b(x, y=2)">
@@ -590,14 +624,13 @@ class NestedDefTest(TemplateTest):
</%def>
a ${b(5)}
</%def>
-""")
- eq_(
- flatten_result(t.render()),
- "a b x is 5 y is 2"
+"""
)
+ eq_(flatten_result(t.render()), "a b x is 5 y is 2")
def test_nested_def_2(self):
- template = Template("""
+ template = Template(
+ """
${a()}
<%def name="a()">
<%def name="b()">
@@ -608,14 +641,13 @@ class NestedDefTest(TemplateTest):
</%def>
${b()}
</%def>
-""")
- eq_(
- flatten_result(template.render()),
- "comp c"
+"""
)
+ eq_(flatten_result(template.render()), "comp c")
def test_nested_nested_def(self):
- t = Template("""
+ t = Template(
+ """
${a()}
<%def name="a()">
@@ -648,16 +680,18 @@ class NestedDefTest(TemplateTest):
${b1()} ${b2()} ${b3()}
</%def>
-""")
+"""
+ )
eq_(
flatten_result(t.render(x=5, y=None)),
"a a_b1 a_b2 a_b2_c1 a_b3 a_b3_c1 "
"heres x: 5 y is 7 a_b3_c2 y is "
- "None c1 is a_b3_c1 heres x: 5 y is 7"
+ "None c1 is a_b3_c1 heres x: 5 y is 7",
)
def test_nested_nested_def_2(self):
- t = Template("""
+ t = Template(
+ """
<%def name="a()">
this is a ${b()}
<%def name="b()">
@@ -670,14 +704,13 @@ class NestedDefTest(TemplateTest):
</%def>
</%def>
${a()}
-""")
- eq_(
- flatten_result(t.render()),
- "this is a this is b this is c"
+"""
)
+ eq_(flatten_result(t.render()), "this is a this is b this is c")
def test_outer_scope(self):
- t = Template("""
+ t = Template(
+ """
<%def name="a()">
a: x is ${x}
</%def>
@@ -696,36 +729,34 @@ class NestedDefTest(TemplateTest):
${b()}
x is ${x}
-""")
- eq_(
- flatten_result(t.render(x=5)),
- "b. c. x is 10. a: x is 5 x is 5"
+"""
)
+ eq_(flatten_result(t.render(x=5)), "b. c. x is 10. a: x is 5 x is 5")
+
class ExceptionTest(TemplateTest):
def test_raise(self):
- template = Template("""
+ template = Template(
+ """
<%
raise Exception("this is a test")
%>
- """, format_exceptions=False)
- assert_raises(
- Exception,
- template.render
- )
+ """,
+ format_exceptions=False,
+ )
+ assert_raises(Exception, template.render)
def test_handler(self):
def handle(context, error):
context.write("error message is " + str(error))
return True
- template = Template("""
+ template = Template(
+ """
<%
raise Exception("this is a test")
%>
- """, error_handler=handle)
- eq_(
- template.render().strip(),
- "error message is this is a test"
+ """,
+ error_handler=handle,
)
-
+ eq_(template.render().strip(), "error message is this is a test")
diff --git a/test/test_exceptions.py b/test/test_exceptions.py
index 242577f..c680591 100644
--- a/test/test_exceptions.py
+++ b/test/test_exceptions.py
@@ -1,13 +1,16 @@
# -*- coding: utf-8 -*-
import sys
-from mako import exceptions, compat
-from mako.template import Template
-from mako.lookup import TemplateLookup
+from mako import compat
+from mako import exceptions
from mako.compat import u
-from test.util import result_lines
+from mako.lookup import TemplateLookup
+from mako.template import Template
+from test import requires_no_pygments_exceptions
+from test import requires_pygments_14
from test import TemplateTest
-from test import requires_pygments_14, requires_no_pygments_exceptions
+from test.util import result_lines
+
class ExceptionsTest(TemplateTest):
def test_html_error_template(self):
@@ -21,24 +24,28 @@ class ExceptionsTest(TemplateTest):
assert False
except exceptions.CompileException:
html_error = exceptions.html_error_template().render_unicode()
- assert ("CompileException: Fragment &#39;i = 0&#39; is not "
- "a partial control statement at line: 2 char: 1") in html_error
- assert '<style>' in html_error
+ assert (
+ "CompileException: Fragment &#39;i = 0&#39; is not "
+ "a partial control statement at line: 2 char: 1"
+ ) in html_error
+ assert "<style>" in html_error
html_error_stripped = html_error.strip()
- assert html_error_stripped.startswith('<html>')
- assert html_error_stripped.endswith('</html>')
+ assert html_error_stripped.startswith("<html>")
+ assert html_error_stripped.endswith("</html>")
- not_full = exceptions.html_error_template().\
- render_unicode(full=False)
- assert '<html>' not in not_full
- assert '<style>' in not_full
+ not_full = exceptions.html_error_template().render_unicode(
+ full=False
+ )
+ assert "<html>" not in not_full
+ assert "<style>" in not_full
- no_css = exceptions.html_error_template().\
- render_unicode(css=False)
- assert '<style>' not in no_css
+ no_css = exceptions.html_error_template().render_unicode(css=False)
+ assert "<style>" not in no_css
else:
- assert False, ("This function should trigger a CompileException, "
- "but didn't")
+ assert False, (
+ "This function should trigger a CompileException, "
+ "but didn't"
+ )
def test_text_error_template(self):
code = """
@@ -50,9 +57,11 @@ class ExceptionsTest(TemplateTest):
assert False
except exceptions.CompileException:
text_error = exceptions.text_error_template().render_unicode()
- assert 'Traceback (most recent call last):' in text_error
- assert ("CompileException: Fragment 'i = 0' is not a partial "
- "control statement") in text_error
+ assert "Traceback (most recent call last):" in text_error
+ assert (
+ "CompileException: Fragment 'i = 0' is not a partial "
+ "control statement"
+ ) in text_error
@requires_pygments_14
def test_utf8_html_error_template_pygments(self):
@@ -77,28 +86,40 @@ ${u'привет'}
except exceptions.CompileException:
html_error = exceptions.html_error_template().render()
if compat.py3k:
- assert ("CompileException: Fragment &#39;if 2 == 2: /an "
- "error&#39; is not a partial control statement "
- "at line: 2 char: 1").encode(sys.getdefaultencoding(), 'htmlentityreplace') in \
- html_error
- else:
- assert ("CompileException: Fragment &#39;if 2 == 2: /an "
+ assert (
+ (
+ "CompileException: Fragment &#39;if 2 == 2: /an "
"error&#39; is not a partial control statement "
- "at line: 2 char: 1") in \
- html_error
+ "at line: 2 char: 1"
+ ).encode(sys.getdefaultencoding(), "htmlentityreplace")
+ in html_error
+ )
+ else:
+ assert (
+ "CompileException: Fragment &#39;if 2 == 2: /an "
+ "error&#39; is not a partial control statement "
+ "at line: 2 char: 1"
+ ) in html_error
if compat.py3k:
- assert "".encode(sys.getdefaultencoding(),
- 'htmlentityreplace') in html_error
+ assert (
+ "".encode(sys.getdefaultencoding(), "htmlentityreplace")
+ in html_error
+ )
else:
- assert '&#39;'\
- '&#x43F;&#x440;&#x438;&#x432;&#x435;&#x442;'\
- '&#39;</span><span class="cp">}</span>'.encode(
- sys.getdefaultencoding(),
- 'htmlentityreplace') in html_error
+ assert (
+ "&#39;"
+ "&#x43F;&#x440;&#x438;&#x432;&#x435;&#x442;"
+ '&#39;</span><span class="cp">}</span>'.encode(
+ sys.getdefaultencoding(), "htmlentityreplace"
+ )
+ in html_error
+ )
else:
- assert False, ("This function should trigger a CompileException, "
- "but didn't")
+ assert False, (
+ "This function should trigger a CompileException, "
+ "but didn't"
+ )
@requires_no_pygments_exceptions
def test_utf8_html_error_template_no_pygments(self):
@@ -123,87 +144,117 @@ ${u'привет'}
except exceptions.CompileException:
html_error = exceptions.html_error_template().render()
if compat.py3k:
- assert ("CompileException: Fragment &#39;if 2 == 2: /an "
- "error&#39; is not a partial control statement "
- "at line: 2 char: 1").encode(sys.getdefaultencoding(),
- 'htmlentityreplace') in \
- html_error
- else:
- assert ("CompileException: Fragment &#39;if 2 == 2: /an "
+ assert (
+ (
+ "CompileException: Fragment &#39;if 2 == 2: /an "
"error&#39; is not a partial control statement "
- "at line: 2 char: 1") in \
- html_error
+ "at line: 2 char: 1"
+ ).encode(sys.getdefaultencoding(), "htmlentityreplace")
+ in html_error
+ )
+ else:
+ assert (
+ "CompileException: Fragment &#39;if 2 == 2: /an "
+ "error&#39; is not a partial control statement "
+ "at line: 2 char: 1"
+ ) in html_error
if compat.py3k:
- assert "${&#39;привет&#39;}".encode(sys.getdefaultencoding(),
- 'htmlentityreplace') in html_error
+ assert (
+ "${&#39;привет&#39;}".encode(
+ sys.getdefaultencoding(), "htmlentityreplace"
+ )
+ in html_error
+ )
else:
- assert u("${u&#39;привет&#39;}").encode(sys.getdefaultencoding(),
- 'htmlentityreplace') in html_error
+ assert (
+ u("${u&#39;привет&#39;}").encode(
+ sys.getdefaultencoding(), "htmlentityreplace"
+ )
+ in html_error
+ )
else:
- assert False, ("This function should trigger a CompileException, "
- "but didn't")
+ assert False, (
+ "This function should trigger a CompileException, "
+ "but didn't"
+ )
def test_format_closures(self):
try:
- exec("def foo():"\
- " raise RuntimeError('test')", locals())
- foo()
+ exec("def foo():" " raise RuntimeError('test')", locals())
+ foo() # noqa
except:
html_error = exceptions.html_error_template().render()
assert "RuntimeError: test" in str(html_error)
def test_py_utf8_html_error_template(self):
try:
- foo = u('日本')
- raise RuntimeError('test')
+ foo = u("日本") # noqa
+ raise RuntimeError("test")
except:
html_error = exceptions.html_error_template().render()
if compat.py3k:
- assert 'RuntimeError: test' in html_error.decode('utf-8')
- assert "foo = u(&#39;日本&#39;)" in html_error.decode('utf-8')
+ assert "RuntimeError: test" in html_error.decode("utf-8")
+ assert "foo = u(&quot;日本&quot;)" in html_error.decode("utf-8")
else:
- assert 'RuntimeError: test' in html_error
- assert "foo = u(&#39;&#x65E5;&#x672C;&#39;)" in html_error
+ assert "RuntimeError: test" in html_error
+ assert "foo = u(&quot;&#x65E5;&#x672C;&quot;)" in html_error
def test_py_unicode_error_html_error_template(self):
try:
- raise RuntimeError(u('日本'))
+ raise RuntimeError(u("日本"))
except:
html_error = exceptions.html_error_template().render()
- assert u("RuntimeError: 日本").encode('ascii', 'ignore') in html_error
+ assert (
+ u("RuntimeError: 日本").encode("ascii", "ignore") in html_error
+ )
@requires_pygments_14
def test_format_exceptions_pygments(self):
l = TemplateLookup(format_exceptions=True)
- l.put_string("foo.html", """
+ l.put_string(
+ "foo.html",
+ """
<%inherit file="base.html"/>
${foobar}
- """)
+ """,
+ )
- l.put_string("base.html", """
+ l.put_string(
+ "base.html",
+ """
${self.body()}
- """)
+ """,
+ )
- assert '<div class="sourceline"><table class="syntax-highlightedtable">' in \
- l.get_template("foo.html").render_unicode()
+ assert (
+ '<div class="sourceline"><table class="syntax-highlightedtable">'
+ in l.get_template("foo.html").render_unicode()
+ )
@requires_no_pygments_exceptions
def test_format_exceptions_no_pygments(self):
l = TemplateLookup(format_exceptions=True)
- l.put_string("foo.html", """
+ l.put_string(
+ "foo.html",
+ """
<%inherit file="base.html"/>
${foobar}
- """)
+ """,
+ )
- l.put_string("base.html", """
+ l.put_string(
+ "base.html",
+ """
${self.body()}
- """)
+ """,
+ )
- assert '<div class="sourceline">${foobar}</div>' in \
- result_lines(l.get_template("foo.html").render_unicode())
+ assert '<div class="sourceline">${foobar}</div>' in result_lines(
+ l.get_template("foo.html").render_unicode()
+ )
@requires_pygments_14
def test_utf8_format_exceptions_pygments(self):
@@ -212,17 +263,24 @@ ${foobar}
l = TemplateLookup(format_exceptions=True)
if compat.py3k:
- l.put_string("foo.html", """# -*- coding: utf-8 -*-\n${'привет' + foobar}""")
+ l.put_string(
+ "foo.html", """# -*- coding: utf-8 -*-\n${'привет' + foobar}"""
+ )
else:
- l.put_string("foo.html", """# -*- coding: utf-8 -*-\n${u'привет' + foobar}""")
+ l.put_string(
+ "foo.html",
+ """# -*- coding: utf-8 -*-\n${u'привет' + foobar}""",
+ )
if compat.py3k:
- assert '&#39;привет&#39;</span>' in \
- l.get_template("foo.html").render().decode('utf-8')
+ assert "&#39;привет&#39;</span>" in l.get_template(
+ "foo.html"
+ ).render().decode("utf-8")
else:
- assert '&#39;&#x43F;&#x440;&#x438;&#x432;'\
- '&#x435;&#x442;&#39;</span>' in \
- l.get_template("foo.html").render().decode('utf-8')
+ assert (
+ "&#39;&#x43F;&#x440;&#x438;&#x432;"
+ "&#x435;&#x442;&#39;</span>"
+ ) in l.get_template("foo.html").render().decode("utf-8")
@requires_no_pygments_exceptions
def test_utf8_format_exceptions_no_pygments(self):
@@ -231,44 +289,59 @@ ${foobar}
l = TemplateLookup(format_exceptions=True)
if compat.py3k:
- l.put_string("foo.html", """# -*- coding: utf-8 -*-\n${'привет' + foobar}""")
+ l.put_string(
+ "foo.html", """# -*- coding: utf-8 -*-\n${'привет' + foobar}"""
+ )
else:
- l.put_string("foo.html", """# -*- coding: utf-8 -*-\n${u'привет' + foobar}""")
+ l.put_string(
+ "foo.html",
+ """# -*- coding: utf-8 -*-\n${u'привет' + foobar}""",
+ )
if compat.py3k:
- assert '<div class="sourceline">${&#39;привет&#39; + foobar}</div>'\
- in result_lines(l.get_template("foo.html").render().decode('utf-8'))
+ assert (
+ '<div class="sourceline">${&#39;привет&#39; + foobar}</div>'
+ in result_lines(
+ l.get_template("foo.html").render().decode("utf-8")
+ )
+ )
else:
- assert '${u&#39;&#x43F;&#x440;&#x438;&#x432;&#x435;'\
- '&#x442;&#39; + foobar}' in \
- result_lines(l.get_template("foo.html").render().decode('utf-8'))
+ assert (
+ "${u&#39;&#x43F;&#x440;&#x438;&#x432;&#x435;"
+ "&#x442;&#39; + foobar}"
+ in result_lines(
+ l.get_template("foo.html").render().decode("utf-8")
+ )
+ )
def test_mod_no_encoding(self):
mod = __import__("test.foo.mod_no_encoding").foo.mod_no_encoding
try:
- mod.run()
+ mod.run()
except:
t, v, tback = sys.exc_info()
- html_error = exceptions.html_error_template().\
- render_unicode(error=v, traceback=tback)
+ exceptions.html_error_template().render_unicode(
+ error=v, traceback=tback
+ )
def test_custom_tback(self):
try:
raise RuntimeError("error 1")
- foo('bar')
+ foo("bar") # noqa
except:
t, v, tback = sys.exc_info()
try:
raise RuntimeError("error 2")
except:
- html_error = exceptions.html_error_template().\
- render_unicode(error=v, traceback=tback)
+ html_error = exceptions.html_error_template().render_unicode(
+ error=v, traceback=tback
+ )
# obfuscate the text so that this text
# isn't in the 'wrong' exception
- assert "".join(reversed(");93#&rab;93#&(oof")) in html_error
+ assert "".join(reversed(");touq&rab;touq&(oof")) in html_error
def test_tback_no_trace_from_py_file(self):
try:
@@ -282,9 +355,13 @@ ${foobar}
sys.exc_clear()
# and don't even send what we have.
- html_error = exceptions.html_error_template().\
- render_unicode(error=v, traceback=None)
- assert "local variable &#39;y&#39; referenced before assignment" in html_error
+ html_error = exceptions.html_error_template().render_unicode(
+ error=v, traceback=None
+ )
+ assert (
+ "local variable &#39;y&#39; referenced before assignment"
+ in html_error
+ )
def test_tback_trace_from_py_file(self):
t = self._file_template("runtimeerr.html")
@@ -292,7 +369,9 @@ ${foobar}
t.render()
assert False
except:
- html_error = exceptions.html_error_template().\
- render_unicode()
+ html_error = exceptions.html_error_template().render_unicode()
- assert "local variable &#39;y&#39; referenced before assignment" in html_error
+ assert (
+ "local variable &#39;y&#39; referenced before assignment"
+ in html_error
+ )
diff --git a/test/test_filters.py b/test/test_filters.py
index 64f36f6..598cb45 100644
--- a/test/test_filters.py
+++ b/test/test_filters.py
@@ -1,228 +1,302 @@
# -*- coding: utf-8 -*-
-from mako.template import Template
import unittest
-from test import TemplateTest, eq_, requires_python_2
-from test.util import result_lines, flatten_result
-from mako.compat import u
+
from mako import compat
+from mako.compat import u
+from mako.template import Template
+from test import eq_
+from test import requires_python_2
+from test import TemplateTest
+from test.util import flatten_result
+from test.util import result_lines
+
class FilterTest(TemplateTest):
def test_basic(self):
- t = Template("""
+ t = Template(
+ """
${x | myfilter}
-""")
- assert flatten_result(t.render(x="this is x", myfilter=lambda t: "MYFILTER->%s<-MYFILTER" % t)) == "MYFILTER->this is x<-MYFILTER"
+"""
+ )
+ assert (
+ flatten_result(
+ t.render(
+ x="this is x",
+ myfilter=lambda t: "MYFILTER->%s<-MYFILTER" % t,
+ )
+ )
+ == "MYFILTER->this is x<-MYFILTER"
+ )
def test_expr(self):
"""test filters that are themselves expressions"""
- t = Template("""
+ t = Template(
+ """
${x | myfilter(y)}
-""")
+"""
+ )
+
def myfilter(y):
return lambda x: "MYFILTER->%s<-%s" % (x, y)
- assert flatten_result(t.render(x="this is x", myfilter=myfilter, y="this is y")) == "MYFILTER->this is x<-this is y"
+
+ assert (
+ flatten_result(
+ t.render(x="this is x", myfilter=myfilter, y="this is y")
+ )
+ == "MYFILTER->this is x<-this is y"
+ )
def test_convert_str(self):
- """test that string conversion happens in expressions before sending to filters"""
- t = Template("""
+ """test that string conversion happens in expressions before
+ sending to filters"""
+ t = Template(
+ """
${x | trim}
- """)
+ """
+ )
assert flatten_result(t.render(x=5)) == "5"
def test_quoting(self):
- t = Template("""
+ t = Template(
+ """
foo ${bar | h}
- """)
+ """
+ )
eq_(
flatten_result(t.render(bar="<'some bar'>")),
- "foo &lt;&#39;some bar&#39;&gt;"
+ "foo &lt;&#39;some bar&#39;&gt;",
)
def test_url_escaping(self):
- t = Template("""
+ t = Template(
+ """
http://example.com/?bar=${bar | u}&v=1
- """)
+ """
+ )
eq_(
flatten_result(t.render(bar=u"酒吧bar")),
- "http://example.com/?bar=%E9%85%92%E5%90%A7bar&v=1"
+ "http://example.com/?bar=%E9%85%92%E5%90%A7bar&v=1",
)
def test_entity(self):
t = Template("foo ${bar | entity}")
eq_(
flatten_result(t.render(bar="<'some bar'>")),
- "foo &lt;'some bar'&gt;"
+ "foo &lt;'some bar'&gt;",
)
@requires_python_2
def test_quoting_non_unicode(self):
- t = Template("""
+ t = Template(
+ """
foo ${bar | h}
- """, disable_unicode=True,
- output_encoding=None)
+ """,
+ disable_unicode=True,
+ output_encoding=None,
+ )
eq_(
flatten_result(t.render(bar="<'привет'>")),
- "foo &lt;&#39;привет&#39;&gt;"
+ "foo &lt;&#39;привет&#39;&gt;",
)
@requires_python_2
def test_url_escaping_non_unicode(self):
- t = Template("""
+ t = Template(
+ """
http://example.com/?bar=${bar | u}&v=1
- """, disable_unicode=True,
- output_encoding=None)
+ """,
+ disable_unicode=True,
+ output_encoding=None,
+ )
eq_(
flatten_result(t.render(bar="酒吧bar")),
- "http://example.com/?bar=%E9%85%92%E5%90%A7bar&v=1"
+ "http://example.com/?bar=%E9%85%92%E5%90%A7bar&v=1",
)
-
def test_def(self):
- t = Template("""
+ t = Template(
+ """
<%def name="foo()" filter="myfilter">
this is foo
</%def>
${foo()}
-""")
+"""
+ )
eq_(
- flatten_result(t.render(x="this is x",
- myfilter=lambda t: "MYFILTER->%s<-MYFILTER" % t)),
- "MYFILTER-> this is foo <-MYFILTER"
+ flatten_result(
+ t.render(
+ x="this is x",
+ myfilter=lambda t: "MYFILTER->%s<-MYFILTER" % t,
+ )
+ ),
+ "MYFILTER-> this is foo <-MYFILTER",
)
def test_import(self):
- t = Template("""
+ t = Template(
+ """
<%!
from mako import filters
%>\
- trim this string: ${" some string to trim " | filters.trim} continue\
- """)
+ trim this string: """
+ """${" some string to trim " | filters.trim} continue\
+ """
+ )
- assert t.render().strip()=="trim this string: some string to trim continue"
+ assert (
+ t.render().strip()
+ == "trim this string: some string to trim continue"
+ )
def test_import_2(self):
- t = Template("""
- trim this string: ${" some string to trim " | filters.trim} continue\
- """, imports=["from mako import filters"])
- #print t.code
- assert t.render().strip()=="trim this string: some string to trim continue"
+ t = Template(
+ """
+ trim this string: """
+ """${" some string to trim " | filters.trim} continue\
+ """,
+ imports=["from mako import filters"],
+ )
+ # print t.code
+ assert (
+ t.render().strip()
+ == "trim this string: some string to trim continue"
+ )
def test_encode_filter(self):
- t = Template("""# coding: utf-8
+ t = Template(
+ """# coding: utf-8
some stuff.... ${x}
- """, default_filters=['decode.utf8'])
+ """,
+ default_filters=["decode.utf8"],
+ )
eq_(
t.render_unicode(x=u("voix m’a réveillé")).strip(),
- u("some stuff.... voix m’a réveillé")
+ u("some stuff.... voix m’a réveillé"),
)
def test_encode_filter_non_str(self):
- t = Template("""# coding: utf-8
+ t = Template(
+ """# coding: utf-8
some stuff.... ${x}
- """, default_filters=['decode.utf8'])
- eq_(
- t.render_unicode(x=3).strip(),
- u("some stuff.... 3")
+ """,
+ default_filters=["decode.utf8"],
)
+ eq_(t.render_unicode(x=3).strip(), u("some stuff.... 3"))
@requires_python_2
def test_encode_filter_non_str_we_return_bytes(self):
class Foo(object):
def __str__(self):
return compat.b("å")
- t = Template("""# coding: utf-8
+
+ t = Template(
+ """# coding: utf-8
some stuff.... ${x}
- """, default_filters=['decode.utf8'])
- eq_(
- t.render_unicode(x=Foo()).strip(),
- u("some stuff.... å")
+ """,
+ default_filters=["decode.utf8"],
)
+ eq_(t.render_unicode(x=Foo()).strip(), u("some stuff.... å"))
def test_custom_default(self):
- t = Template("""
+ t = Template(
+ """
<%!
def myfilter(x):
return "->" + x + "<-"
%>
hi ${'there'}
- """, default_filters=['myfilter'])
- assert t.render().strip()=="hi ->there<-"
+ """,
+ default_filters=["myfilter"],
+ )
+ assert t.render().strip() == "hi ->there<-"
def test_global(self):
- t = Template("""
+ t = Template(
+ """
<%page expression_filter="h"/>
${"<tag>this is html</tag>"}
- """)
- assert t.render().strip() == "&lt;tag&gt;this is html&lt;/tag&gt;"
+ """
+ )
+ assert t.render().strip() == "&lt;tag&gt;this is html&lt;/tag&gt;"
def test_block_via_context(self):
- t = Template("""
+ t = Template(
+ """
<%block name="foo" filter="myfilter">
some text
</%block>
- """)
+ """
+ )
+
def myfilter(text):
return "MYTEXT" + text
- eq_(
- result_lines(t.render(myfilter=myfilter)),
- ["MYTEXT", "some text"]
- )
+
+ eq_(result_lines(t.render(myfilter=myfilter)), ["MYTEXT", "some text"])
def test_def_via_context(self):
- t = Template("""
+ t = Template(
+ """
<%def name="foo()" filter="myfilter">
some text
</%def>
${foo()}
- """)
+ """
+ )
+
def myfilter(text):
return "MYTEXT" + text
- eq_(
- result_lines(t.render(myfilter=myfilter)),
- ["MYTEXT", "some text"]
- )
+
+ eq_(result_lines(t.render(myfilter=myfilter)), ["MYTEXT", "some text"])
def test_text_via_context(self):
- t = Template("""
+ t = Template(
+ """
<%text filter="myfilter">
some text
</%text>
- """)
+ """
+ )
+
def myfilter(text):
return "MYTEXT" + text
- eq_(
- result_lines(t.render(myfilter=myfilter)),
- ["MYTEXT", "some text"]
- )
+ eq_(result_lines(t.render(myfilter=myfilter)), ["MYTEXT", "some text"])
def test_nflag(self):
- t = Template("""
+ t = Template(
+ """
${"<tag>this is html</tag>" | n}
- """, default_filters=['h', 'unicode'])
- assert t.render().strip() == "<tag>this is html</tag>"
+ """,
+ default_filters=["h", "unicode"],
+ )
+ assert t.render().strip() == "<tag>this is html</tag>"
- t = Template("""
+ t = Template(
+ """
<%page expression_filter="h"/>
${"<tag>this is html</tag>" | n}
- """)
- assert t.render().strip() == "<tag>this is html</tag>"
+ """
+ )
+ assert t.render().strip() == "<tag>this is html</tag>"
- t = Template("""
+ t = Template(
+ """
<%page expression_filter="h"/>
${"<tag>this is html</tag>" | n, h}
- """)
- assert t.render().strip() == "&lt;tag&gt;this is html&lt;/tag&gt;"
+ """
+ )
+ assert t.render().strip() == "&lt;tag&gt;this is html&lt;/tag&gt;"
def test_non_expression(self):
- t = Template("""
+ t = Template(
+ """
<%!
def a(text):
return "this is a"
@@ -234,10 +308,13 @@ class FilterTest(TemplateTest):
<%def name="foo()" buffered="True">
this is text
</%def>
- """, buffer_filters=['a'])
+ """,
+ buffer_filters=["a"],
+ )
assert t.render().strip() == "this is a"
- t = Template("""
+ t = Template(
+ """
<%!
def a(text):
return "this is a"
@@ -250,10 +327,14 @@ class FilterTest(TemplateTest):
<%def name="foo()" buffered="True">
this is text
</%def>
- """, buffer_filters=['a'], default_filters=['b'])
+ """,
+ buffer_filters=["a"],
+ default_filters=["b"],
+ )
assert flatten_result(t.render()) == "this is b this is b"
- t = Template("""
+ t = Template(
+ """
<%!
class Foo(object):
foo = True
@@ -273,10 +354,14 @@ class FilterTest(TemplateTest):
<%def name="foo()" buffered="True">
this is text
</%def>
- """, buffer_filters=['a'], default_filters=['b'])
+ """,
+ buffer_filters=["a"],
+ default_filters=["b"],
+ )
assert flatten_result(t.render()) == "this is b this is a"
- t = Template("""
+ t = Template(
+ """
<%!
def a(text):
return "this is a"
@@ -292,51 +377,67 @@ class FilterTest(TemplateTest):
<%def name="bar()" filter="b" buffered="True">
this is text
</%def>
- """, buffer_filters=['a'])
+ """,
+ buffer_filters=["a"],
+ )
assert flatten_result(t.render()) == "this is b this is a"
-
def test_builtins(self):
- t = Template("""
+ t = Template(
+ """
${"this is <text>" | h}
-""")
+"""
+ )
assert flatten_result(t.render()) == "this is &lt;text&gt;"
- t = Template("""
+ t = Template(
+ """
http://foo.com/arg1=${"hi! this is a string." | u}
-""")
- assert flatten_result(t.render()) == "http://foo.com/arg1=hi%21+this+is+a+string."
+"""
+ )
+ assert (
+ flatten_result(t.render())
+ == "http://foo.com/arg1=hi%21+this+is+a+string."
+ )
+
class BufferTest(unittest.TestCase):
def test_buffered_def(self):
- t = Template("""
+ t = Template(
+ """
<%def name="foo()" buffered="True">
this is foo
</%def>
${"hi->" + foo() + "<-hi"}
-""")
+"""
+ )
assert flatten_result(t.render()) == "hi-> this is foo <-hi"
def test_unbuffered_def(self):
- t = Template("""
+ t = Template(
+ """
<%def name="foo()" buffered="False">
this is foo
</%def>
${"hi->" + foo() + "<-hi"}
-""")
+"""
+ )
assert flatten_result(t.render()) == "this is foo hi-><-hi"
def test_capture(self):
- t = Template("""
+ t = Template(
+ """
<%def name="foo()" buffered="False">
this is foo
</%def>
${"hi->" + capture(foo) + "<-hi"}
-""")
+"""
+ )
assert flatten_result(t.render()) == "hi-> this is foo <-hi"
def test_capture_exception(self):
- template = Template("""
+ template = Template(
+ """
<%def name="a()">
this is a
<%
@@ -347,7 +448,8 @@ class BufferTest(unittest.TestCase):
c = capture(a)
%>
a->${c}<-a
- """)
+ """
+ )
try:
template.render()
assert False
@@ -355,7 +457,8 @@ class BufferTest(unittest.TestCase):
assert True
def test_buffered_exception(self):
- template = Template("""
+ template = Template(
+ """
<%def name="a()" buffered="True">
<%
raise TypeError("hi")
@@ -364,7 +467,8 @@ class BufferTest(unittest.TestCase):
${a()}
-""")
+"""
+ )
try:
print(template.render())
assert False
@@ -372,7 +476,8 @@ class BufferTest(unittest.TestCase):
assert True
def test_capture_ccall(self):
- t = Template("""
+ t = Template(
+ """
<%def name="foo()">
<%
x = capture(caller.body)
@@ -383,8 +488,8 @@ class BufferTest(unittest.TestCase):
<%call expr="foo()">
ccall body
</%call>
-""")
+"""
+ )
- #print t.render()
+ # print t.render()
assert flatten_result(t.render()) == "this is foo. body: ccall body"
-
diff --git a/test/test_inheritance.py b/test/test_inheritance.py
index 08a46b3..e8ed74e 100644
--- a/test/test_inheritance.py
+++ b/test/test_inheritance.py
@@ -1,12 +1,17 @@
-from mako import lookup, compat
import unittest
+
+from mako import compat
+from mako import lookup
from test.util import result_lines
+
class InheritanceTest(unittest.TestCase):
def test_basic(self):
collection = lookup.TemplateLookup()
- collection.put_string('main', """
+ collection.put_string(
+ "main",
+ """
<%inherit file="base"/>
<%def name="header()">
@@ -14,9 +19,12 @@ class InheritanceTest(unittest.TestCase):
</%def>
this is the content.
-""")
+""",
+ )
- collection.put_string('base', """
+ collection.put_string(
+ "base",
+ """
This is base.
header: ${self.header()}
@@ -28,31 +36,38 @@ footer: ${self.footer()}
<%def name="footer()">
this is the footer. header again ${next.header()}
</%def>
-""")
-
- assert result_lines(collection.get_template('main').render()) == [
- 'This is base.',
- 'header:',
- 'main header.',
- 'body:',
- 'this is the content.',
- 'footer:',
- 'this is the footer. header again',
- 'main header.'
+""",
+ )
+
+ assert result_lines(collection.get_template("main").render()) == [
+ "This is base.",
+ "header:",
+ "main header.",
+ "body:",
+ "this is the content.",
+ "footer:",
+ "this is the footer. header again",
+ "main header.",
]
def test_multilevel_nesting(self):
collection = lookup.TemplateLookup()
- collection.put_string('main', """
+ collection.put_string(
+ "main",
+ """
<%inherit file="layout"/>
<%def name="d()">main_d</%def>
main_body ${parent.d()}
full stack from the top:
- ${self.name} ${parent.name} ${parent.context['parent'].name} ${parent.context['parent'].context['parent'].name}
-""")
-
- collection.put_string('layout', """
+ ${self.name} ${parent.name} ${parent.context['parent'].name} """
+ """${parent.context['parent'].context['parent'].name}
+""",
+ )
+
+ collection.put_string(
+ "layout",
+ """
<%inherit file="general"/>
<%def name="d()">layout_d</%def>
layout_body
@@ -60,95 +75,122 @@ parent name: ${parent.name}
${parent.d()}
${parent.context['parent'].d()}
${next.body()}
-""")
+""",
+ )
- collection.put_string('general', """
+ collection.put_string(
+ "general",
+ """
<%inherit file="base"/>
<%def name="d()">general_d</%def>
general_body
${next.d()}
${next.context['next'].d()}
${next.body()}
-""")
- collection.put_string('base', """
+""",
+ )
+ collection.put_string(
+ "base",
+ """
base_body
full stack from the base:
- ${self.name} ${self.context['parent'].name} ${self.context['parent'].context['parent'].name} ${self.context['parent'].context['parent'].context['parent'].name}
+ ${self.name} ${self.context['parent'].name} """
+ """${self.context['parent'].context['parent'].name} """
+ """${self.context['parent'].context['parent'].context['parent'].name}
${next.body()}
<%def name="d()">base_d</%def>
-""")
-
- assert result_lines(collection.get_template('main').render()) == [
- 'base_body',
- 'full stack from the base:',
- 'self:main self:layout self:general self:base',
- 'general_body',
- 'layout_d',
- 'main_d',
- 'layout_body',
- 'parent name: self:general',
- 'general_d',
- 'base_d',
- 'main_body layout_d',
- 'full stack from the top:',
- 'self:main self:layout self:general self:base'
+""",
+ )
+
+ assert result_lines(collection.get_template("main").render()) == [
+ "base_body",
+ "full stack from the base:",
+ "self:main self:layout self:general self:base",
+ "general_body",
+ "layout_d",
+ "main_d",
+ "layout_body",
+ "parent name: self:general",
+ "general_d",
+ "base_d",
+ "main_body layout_d",
+ "full stack from the top:",
+ "self:main self:layout self:general self:base",
]
def test_includes(self):
- """test that an included template also has its full hierarchy invoked."""
+ """test that an included template also has its full hierarchy
+ invoked."""
collection = lookup.TemplateLookup()
- collection.put_string("base", """
+ collection.put_string(
+ "base",
+ """
<%def name="a()">base_a</%def>
This is the base.
${next.body()}
End base.
-""")
+""",
+ )
- collection.put_string("index","""
+ collection.put_string(
+ "index",
+ """
<%inherit file="base"/>
this is index.
a is: ${self.a()}
<%include file="secondary"/>
-""")
+""",
+ )
- collection.put_string("secondary","""
+ collection.put_string(
+ "secondary",
+ """
<%inherit file="base"/>
this is secondary.
a is: ${self.a()}
-""")
+""",
+ )
assert result_lines(collection.get_template("index").render()) == [
- 'This is the base.',
- 'this is index.',
- 'a is: base_a',
- 'This is the base.',
- 'this is secondary.',
- 'a is: base_a',
- 'End base.',
- 'End base.'
- ]
+ "This is the base.",
+ "this is index.",
+ "a is: base_a",
+ "This is the base.",
+ "this is secondary.",
+ "a is: base_a",
+ "End base.",
+ "End base.",
+ ]
def test_namespaces(self):
- """test that templates used via <%namespace> have access to an inheriting 'self', and that
- the full 'self' is also exported."""
+ """test that templates used via <%namespace> have access to an
+ inheriting 'self', and that the full 'self' is also exported."""
collection = lookup.TemplateLookup()
- collection.put_string("base", """
+ collection.put_string(
+ "base",
+ """
<%def name="a()">base_a</%def>
<%def name="b()">base_b</%def>
This is the base.
${next.body()}
-""")
+""",
+ )
- collection.put_string("layout", """
+ collection.put_string(
+ "layout",
+ """
<%inherit file="base"/>
<%def name="a()">layout_a</%def>
This is the layout..
${next.body()}
-""")
+""",
+ )
- collection.put_string("index","""
+ collection.put_string(
+ "index",
+ """
<%inherit file="base"/>
<%namespace name="sc" file="secondary"/>
this is index.
@@ -157,32 +199,41 @@ ${next.body()}
sc.b is: ${sc.b()}
sc.c is: ${sc.c()}
sc.body is: ${sc.body()}
-""")
+""",
+ )
- collection.put_string("secondary","""
+ collection.put_string(
+ "secondary",
+ """
<%inherit file="layout"/>
- <%def name="c()">secondary_c. a is ${self.a()} b is ${self.b()} d is ${self.d()}</%def>
+ <%def name="c()">secondary_c. a is ${self.a()} b is ${self.b()} """
+ """d is ${self.d()}</%def>
<%def name="d()">secondary_d.</%def>
this is secondary.
a is: ${self.a()}
c is: ${self.c()}
-""")
-
- assert result_lines(collection.get_template('index').render()) == ['This is the base.',
- 'this is index.',
- 'a is: base_a',
- 'sc.a is: layout_a',
- 'sc.b is: base_b',
- 'sc.c is: secondary_c. a is layout_a b is base_b d is secondary_d.',
- 'sc.body is:',
- 'this is secondary.',
- 'a is: layout_a',
- 'c is: secondary_c. a is layout_a b is base_b d is secondary_d.'
- ]
+""",
+ )
+
+ assert result_lines(collection.get_template("index").render()) == [
+ "This is the base.",
+ "this is index.",
+ "a is: base_a",
+ "sc.a is: layout_a",
+ "sc.b is: base_b",
+ "sc.c is: secondary_c. a is layout_a b is base_b d is "
+ "secondary_d.",
+ "sc.body is:",
+ "this is secondary.",
+ "a is: layout_a",
+ "c is: secondary_c. a is layout_a b is base_b d is secondary_d.",
+ ]
def test_pageargs(self):
collection = lookup.TemplateLookup()
- collection.put_string("base", """
+ collection.put_string(
+ "base",
+ """
this is the base.
<%
@@ -195,29 +246,39 @@ ${next.body()}
</%def>
${foo()}
- """)
- collection.put_string("index", """
+ """,
+ )
+ collection.put_string(
+ "index",
+ """
<%inherit file="base"/>
<%page args="x, y, z=7"/>
print ${x}, ${y}, ${z}
- """)
+ """,
+ )
if compat.py3k:
- assert result_lines(collection.get_template('index').render_unicode(x=5,y=10)) == [
+ assert result_lines(
+ collection.get_template("index").render_unicode(x=5, y=10)
+ ) == [
"this is the base.",
"pageargs: (type: <class 'dict'>) [('x', 5), ('y', 10)]",
- "print 5, 10, 7"
+ "print 5, 10, 7",
]
else:
- assert result_lines(collection.get_template('index').render_unicode(x=5,y=10)) == [
+ assert result_lines(
+ collection.get_template("index").render_unicode(x=5, y=10)
+ ) == [
"this is the base.",
"pageargs: (type: <type 'dict'>) [('x', 5), ('y', 10)]",
- "print 5, 10, 7"
+ "print 5, 10, 7",
]
def test_pageargs_2(self):
collection = lookup.TemplateLookup()
- collection.put_string("base", """
+ collection.put_string(
+ "base",
+ """
this is the base.
${next.body(**context.kwargs)}
@@ -232,61 +293,84 @@ ${next.body()}
${foo(x=12, y=15, z=8)}
${bar(x=19, y=17)}
- """)
- collection.put_string("index", """
+ """,
+ )
+ collection.put_string(
+ "index",
+ """
<%inherit file="base"/>
<%page args="x, y, z=7"/>
pageargs: ${x}, ${y}, ${z}
- """)
- assert result_lines(collection.get_template('index').render(x=5,y=10)) == [
+ """,
+ )
+ assert result_lines(
+ collection.get_template("index").render(x=5, y=10)
+ ) == [
"this is the base.",
"pageargs: 5, 10, 7",
"pageargs: 12, 15, 8",
- "pageargs: 5, 10, 16"
+ "pageargs: 5, 10, 16",
]
def test_pageargs_err(self):
collection = lookup.TemplateLookup()
- collection.put_string("base", """
+ collection.put_string(
+ "base",
+ """
this is the base.
${next.body()}
- """)
- collection.put_string("index", """
+ """,
+ )
+ collection.put_string(
+ "index",
+ """
<%inherit file="base"/>
<%page args="x, y, z=7"/>
print ${x}, ${y}, ${z}
- """)
+ """,
+ )
try:
- print(collection.get_template('index').render(x=5,y=10))
+ print(collection.get_template("index").render(x=5, y=10))
assert False
except TypeError:
assert True
def test_toplevel(self):
collection = lookup.TemplateLookup()
- collection.put_string("base", """
+ collection.put_string(
+ "base",
+ """
this is the base.
${next.body()}
- """)
- collection.put_string("index", """
+ """,
+ )
+ collection.put_string(
+ "index",
+ """
<%inherit file="base"/>
this is the body
- """)
- assert result_lines(collection.get_template('index').render()) == [
+ """,
+ )
+ assert result_lines(collection.get_template("index").render()) == [
"this is the base.",
- "this is the body"
- ]
- assert result_lines(collection.get_template('index').get_def("body").render()) == [
- "this is the body"
+ "this is the body",
]
+ assert result_lines(
+ collection.get_template("index").get_def("body").render()
+ ) == ["this is the body"]
def test_dynamic(self):
collection = lookup.TemplateLookup()
- collection.put_string("base", """
+ collection.put_string(
+ "base",
+ """
this is the base.
${next.body()}
- """)
- collection.put_string("index", """
+ """,
+ )
+ collection.put_string(
+ "index",
+ """
<%!
def dyn(context):
if context.get('base', None) is not None:
@@ -296,18 +380,20 @@ ${next.body()}
%>
<%inherit file="${dyn(context)}"/>
this is index.
- """)
- assert result_lines(collection.get_template('index').render()) == [
- 'this is index.'
- ]
- assert result_lines(collection.get_template('index').render(base=True)) == [
- 'this is the base.',
- 'this is index.'
+ """,
+ )
+ assert result_lines(collection.get_template("index").render()) == [
+ "this is index."
]
+ assert result_lines(
+ collection.get_template("index").render(base=True)
+ ) == ["this is the base.", "this is index."]
def test_in_call(self):
collection = lookup.TemplateLookup()
- collection.put_string("/layout.html","""
+ collection.put_string(
+ "/layout.html",
+ """
Super layout!
<%call expr="self.grid()">
${next.body()}
@@ -319,10 +405,12 @@ ${next.body()}
${caller.body()}
End Parent
</%def>
- """)
-
+ """,
+ )
- collection.put_string("/subdir/layout.html", """
+ collection.put_string(
+ "/subdir/layout.html",
+ """
${next.body()}
<%def name="grid()">
Subdir grid
@@ -330,20 +418,23 @@ ${next.body()}
End subdir
</%def>
<%inherit file="/layout.html"/>
- """)
+ """,
+ )
- collection.put_string("/subdir/renderedtemplate.html","""
+ collection.put_string(
+ "/subdir/renderedtemplate.html",
+ """
Holy smokes!
<%inherit file="/subdir/layout.html"/>
- """)
+ """,
+ )
- #print collection.get_template("/layout.html").code
- #print collection.get_template("/subdir/renderedtemplate.html").render()
- assert result_lines(collection.get_template("/subdir/renderedtemplate.html").render()) == [
+ assert result_lines(
+ collection.get_template("/subdir/renderedtemplate.html").render()
+ ) == [
"Super layout!",
"Subdir grid",
"Holy smokes!",
"End subdir",
- "Oh yea!"
+ "Oh yea!",
]
-
diff --git a/test/test_lexer.py b/test/test_lexer.py
index 06ebb05..9807961 100644
--- a/test/test_lexer.py
+++ b/test/test_lexer.py
@@ -1,37 +1,64 @@
+import re
+
+from mako import compat
+from mako import exceptions
+from mako import parsetree
+from mako import util
from mako.lexer import Lexer
-from mako import exceptions, util, compat
-from test.util import flatten_result
from mako.template import Template
-import re
-from test import TemplateTest, eq_, assert_raises_message
+from test import assert_raises_message
+from test import eq_
+from test import TemplateTest
+from test.util import flatten_result
# create fake parsetree classes which are constructed
# exactly as the repr() of a real parsetree object.
# this allows us to use a Python construct as the source
# of a comparable repr(), which is also hit by the 2to3 tool.
+
def repr_arg(x):
if isinstance(x, dict):
return util.sorted_dict_repr(x)
else:
return repr(x)
+
def _as_unicode(arg):
if isinstance(arg, compat.string_types):
return compat.text_type(arg)
elif isinstance(arg, dict):
- return dict(
- (_as_unicode(k), _as_unicode(v))
- for k, v in arg.items()
- )
+ return dict((_as_unicode(k), _as_unicode(v)) for k, v in arg.items())
else:
return arg
-from mako import parsetree
+
+Node = None
+TemplateNode = None
+ControlLine = None
+Text = None
+Code = None
+Comment = None
+Expression = None
+_TagMeta = None
+Tag = None
+IncludeTag = None
+NamespaceTag = None
+TextTag = None
+DefTag = None
+BlockTag = None
+CallTag = None
+CallNamespaceTag = None
+InheritTag = None
+PageTag = None
+
+# go through all the elements in parsetree and build out
+# mocks of them
for cls in list(parsetree.__dict__.values()):
- if isinstance(cls, type) and \
- issubclass(cls, parsetree.Node):
+ if isinstance(cls, type) and issubclass(cls, parsetree.Node):
clsname = cls.__name__
- exec(("""
+ exec(
+ (
+ """
class %s(object):
def __init__(self, *args):
self.args = [_as_unicode(arg) for arg in args]
@@ -40,13 +67,17 @@ class %s(object):
self.__class__.__name__,
", ".join(repr_arg(x) for x in self.args)
)
-""" % clsname), locals())
+"""
+ % clsname
+ ),
+ locals(),
+ )
# NOTE: most assertion expressions were generated, then formatted
# by PyTidy, hence the dense formatting.
-class LexerTest(TemplateTest):
+class LexerTest(TemplateTest):
def _compare(self, node, expected):
eq_(repr(node), repr(expected))
@@ -60,13 +91,27 @@ class LexerTest(TemplateTest):
and some more text.
"""
node = Lexer(template).parse()
- self._compare(node, TemplateNode({},
- [Text('''\n<b>Hello world</b>\n ''', (1,
- 1)), DefTag('def', {'name': 'foo()'}, (3, 9),
- [Text('''\n this is a def.\n ''',
- (3, 28))]),
- Text('''\n\n and some more text.\n''',
- (5, 16))]))
+ self._compare(
+ node,
+ TemplateNode(
+ {},
+ [
+ Text("""\n<b>Hello world</b>\n """, (1, 1)),
+ DefTag(
+ "def",
+ {"name": "foo()"},
+ (3, 9),
+ [
+ Text(
+ "\n this is a def.\n ",
+ (3, 28),
+ )
+ ],
+ ),
+ Text("""\n\n and some more text.\n""", (5, 16)),
+ ],
+ ),
+ )
def test_unclosed_tag(self):
template = """
@@ -75,17 +120,16 @@ class LexerTest(TemplateTest):
other text
"""
try:
- nodes = Lexer(template).parse()
+ Lexer(template).parse()
assert False
except exceptions.SyntaxException:
eq_(
str(compat.exception_as()),
- "Unclosed tag: <%def> at line: 5 char: 9"
+ "Unclosed tag: <%def> at line: 5 char: 9",
)
def test_onlyclosed_tag(self):
- template = \
- """
+ template = """
<%def name="foo()">
foo
</%def>
@@ -94,20 +138,16 @@ class LexerTest(TemplateTest):
hi.
"""
- self.assertRaises(exceptions.SyntaxException,
- Lexer(template).parse)
+ self.assertRaises(exceptions.SyntaxException, Lexer(template).parse)
def test_noexpr_allowed(self):
- template = \
- """
+ template = """
<%namespace name="${foo}"/>
"""
- self.assertRaises(exceptions.CompileException,
- Lexer(template).parse)
+ self.assertRaises(exceptions.CompileException, Lexer(template).parse)
def test_unmatched_tag(self):
- template = \
- """
+ template = """
<%namespace name="bar">
<%def name="foo()">
foo
@@ -117,29 +157,24 @@ class LexerTest(TemplateTest):
hi.
"""
- self.assertRaises(exceptions.SyntaxException,
- Lexer(template).parse)
+ self.assertRaises(exceptions.SyntaxException, Lexer(template).parse)
def test_nonexistent_tag(self):
template = """
<%lala x="5"/>
"""
- self.assertRaises(exceptions.CompileException,
- Lexer(template).parse)
+ self.assertRaises(exceptions.CompileException, Lexer(template).parse)
def test_wrongcase_tag(self):
- template = \
- """
+ template = """
<%DEF name="foo()">
</%def>
"""
- self.assertRaises(exceptions.CompileException,
- Lexer(template).parse)
+ self.assertRaises(exceptions.CompileException, Lexer(template).parse)
def test_percent_escape(self):
- template = \
- """
+ template = """
%% some whatever.
@@ -148,22 +183,28 @@ class LexerTest(TemplateTest):
% endif
"""
node = Lexer(template).parse()
- self._compare(node, TemplateNode({}, [Text('''\n\n''',
- (1, 1)), Text('''% some whatever.\n\n''', (3, 2)),
- Text(' %% more some whatever\n', (5, 2)),
- ControlLine('if', 'if foo:', False, (6, 1)),
- ControlLine('if', 'endif', True, (7, 1)),
- Text(' ', (8, 1))]))
+ self._compare(
+ node,
+ TemplateNode(
+ {},
+ [
+ Text("""\n\n""", (1, 1)),
+ Text("""% some whatever.\n\n""", (3, 2)),
+ Text(" %% more some whatever\n", (5, 2)),
+ ControlLine("if", "if foo:", False, (6, 1)),
+ ControlLine("if", "endif", True, (7, 1)),
+ Text(" ", (8, 1)),
+ ],
+ ),
+ )
def test_old_multiline_comment(self):
template = """#*"""
node = Lexer(template).parse()
- self._compare(node, TemplateNode({}, [Text('''#*''', (1, 1))]))
-
+ self._compare(node, TemplateNode({}, [Text("""#*""", (1, 1))]))
def test_text_tag(self):
- template = \
- """
+ template = """
## comment
% if foo:
hi
@@ -185,105 +226,176 @@ class LexerTest(TemplateTest):
% endif
"""
node = Lexer(template).parse()
- self._compare(node,
- TemplateNode({}, [Text('\n', (1, 1)),
- Comment('comment', (2, 1)),
- ControlLine('if', 'if foo:', False, (3, 1)),
- Text(' hi\n', (4, 1)),
- ControlLine('if', 'endif', True, (5, 1)),
- Text(' ', (6, 1)),
- TextTag('text', {}, (6, 9),
- [Text('\n # more code\n\n '
- ' % more code\n <%illegal compionent>/></>\n'
- ' <%def name="laal()">def</%def>\n\n\n ',
- (6, 16))]), Text('\n\n ', (14, 17)),
- DefTag('def', {'name': 'foo()'}, (16, 9),
- [Text('this is foo', (16, 28))]), Text('\n\n', (16, 46)),
- ControlLine('if', 'if bar:', False, (18, 1)),
- Text(' code\n', (19, 1)),
- ControlLine('if', 'endif', True, (20, 1)),
- Text(' ', (21, 1))])
+ self._compare(
+ node,
+ TemplateNode(
+ {},
+ [
+ Text("\n", (1, 1)),
+ Comment("comment", (2, 1)),
+ ControlLine("if", "if foo:", False, (3, 1)),
+ Text(" hi\n", (4, 1)),
+ ControlLine("if", "endif", True, (5, 1)),
+ Text(" ", (6, 1)),
+ TextTag(
+ "text",
+ {},
+ (6, 9),
+ [
+ Text(
+ "\n # more code\n\n "
+ " % more code\n "
+ "<%illegal compionent>/></>\n"
+ ' <%def name="laal()">def</%def>'
+ '\n\n\n ',
+ (6, 16),
+ )
+ ],
+ ),
+ Text("\n\n ", (14, 17)),
+ DefTag(
+ "def",
+ {"name": "foo()"},
+ (16, 9),
+ [Text("this is foo", (16, 28))],
+ ),
+ Text("\n\n", (16, 46)),
+ ControlLine("if", "if bar:", False, (18, 1)),
+ Text(" code\n", (19, 1)),
+ ControlLine("if", "endif", True, (20, 1)),
+ Text(" ", (21, 1)),
+ ],
+ ),
)
def test_def_syntax(self):
- template = \
- """
+ template = """
<%def lala>
hi
</%def>
"""
- self.assertRaises(exceptions.CompileException,
- Lexer(template).parse)
+ self.assertRaises(exceptions.CompileException, Lexer(template).parse)
def test_def_syntax_2(self):
- template = \
- """
+ template = """
<%def name="lala">
hi
</%def>
"""
- self.assertRaises(exceptions.CompileException,
- Lexer(template).parse)
+ self.assertRaises(exceptions.CompileException, Lexer(template).parse)
def test_whitespace_equals(self):
- template = \
- """
+ template = """
<%def name = "adef()" >
adef
</%def>
"""
node = Lexer(template).parse()
- self._compare(node, TemplateNode({}, [Text('\n ',
- (1, 1)), DefTag('def', {'name': 'adef()'}, (2,
- 13),
- [Text('''\n adef\n ''',
- (2, 36))]), Text('\n ', (4, 20))]))
+ self._compare(
+ node,
+ TemplateNode(
+ {},
+ [
+ Text("\n ", (1, 1)),
+ DefTag(
+ "def",
+ {"name": "adef()"},
+ (2, 13),
+ [
+ Text(
+ """\n adef\n """,
+ (2, 36),
+ )
+ ],
+ ),
+ Text("\n ", (4, 20)),
+ ],
+ ),
+ )
def test_ns_tag_closed(self):
- template = \
- """
+ template = """
<%self:go x="1" y="2" z="${'hi' + ' ' + 'there'}"/>
"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({},
- [Text('''
-
- ''', (1, 1)),
- CallNamespaceTag('self:go', {'x': '1', 'y'
- : '2', 'z': "${'hi' + ' ' + 'there'}"}, (3,
- 13), []), Text('\n ', (3, 64))]))
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Text(
+ """
+
+ """,
+ (1, 1),
+ ),
+ CallNamespaceTag(
+ "self:go",
+ {"x": "1", "y": "2", "z": "${'hi' + ' ' + 'there'}"},
+ (3, 13),
+ [],
+ ),
+ Text("\n ", (3, 64)),
+ ],
+ ),
+ )
def test_ns_tag_empty(self):
- template = \
- """
+ template = """
<%form:option value=""></%form:option>
"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({}, [Text('\n ',
- (1, 1)), CallNamespaceTag('form:option',
- {'value': ''}, (2, 13), []), Text('\n '
- , (2, 51))]))
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Text("\n ", (1, 1)),
+ CallNamespaceTag(
+ "form:option", {"value": ""}, (2, 13), []
+ ),
+ Text("\n ", (2, 51)),
+ ],
+ ),
+ )
def test_ns_tag_open(self):
- template = \
- """
+ template = """
<%self:go x="1" y="${process()}">
this is the body
</%self:go>
"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({},
- [Text('''
-
- ''', (1, 1)),
- CallNamespaceTag('self:go', {'x': '1', 'y'
- : '${process()}'}, (3, 13),
- [Text('''
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Text(
+ """
+
+ """,
+ (1, 1),
+ ),
+ CallNamespaceTag(
+ "self:go",
+ {"x": "1", "y": "${process()}"},
+ (3, 13),
+ [
+ Text(
+ """
this is the body
- ''',
- (3, 46))]), Text('\n ', (5, 24))]))
+ """,
+ (3, 46),
+ )
+ ],
+ ),
+ Text("\n ", (5, 24)),
+ ],
+ ),
+ )
def test_expr_in_attribute(self):
"""test some slightly trickier expressions.
@@ -291,39 +403,64 @@ class LexerTest(TemplateTest):
you can still trip up the expression parsing, though, unless we
integrated really deeply somehow with AST."""
- template = \
- """
+ template = """
<%call expr="foo>bar and 'lala' or 'hoho'"/>
<%call expr='foo<bar and hoho>lala and "x" + "y"'/>
"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({}, [Text('\n ',
- (1, 1)), CallTag('call', {'expr'
- : "foo>bar and 'lala' or 'hoho'"}, (2, 13), []),
- Text('\n ', (2, 57)), CallTag('call'
- , {'expr': 'foo<bar and hoho>lala and "x" + "y"'
- }, (3, 13), []), Text('\n ', (3, 64))]))
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Text("\n ", (1, 1)),
+ CallTag(
+ "call",
+ {"expr": "foo>bar and 'lala' or 'hoho'"},
+ (2, 13),
+ [],
+ ),
+ Text("\n ", (2, 57)),
+ CallTag(
+ "call",
+ {"expr": 'foo<bar and hoho>lala and "x" + "y"'},
+ (3, 13),
+ [],
+ ),
+ Text("\n ", (3, 64)),
+ ],
+ ),
+ )
def test_pagetag(self):
- template = \
- """
+ template = """
<%page cached="True", args="a, b"/>
some template
"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({}, [Text('\n ',
- (1, 1)), PageTag('page', {'args': 'a, b',
- 'cached': 'True'}, (2, 13), []),
- Text('''
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Text("\n ", (1, 1)),
+ PageTag(
+ "page", {"args": "a, b", "cached": "True"}, (2, 13), []
+ ),
+ Text(
+ """
some template
- ''',
- (2, 48))]))
+ """,
+ (2, 48),
+ ),
+ ],
+ ),
+ )
def test_nesting(self):
- template = \
- """
+ template = """
<%namespace name="ns">
<%def name="lala(hi, there)">
@@ -333,25 +470,55 @@ class LexerTest(TemplateTest):
"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({},
- [Text('''
-
- ''', (1, 1)),
- NamespaceTag('namespace', {'name': 'ns'}, (3,
- 9), [Text('\n ', (3, 31)),
- DefTag('def', {'name': 'lala(hi, there)'}, (4,
- 13), [Text('\n ', (4, 42)),
- CallTag('call', {'expr': 'something()'}, (5,
- 17), []), Text('\n ', (5, 44))]),
- Text('\n ', (6, 20))]),
- Text('''
-
- ''', (7, 22))]))
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Text(
+ """
+
+ """,
+ (1, 1),
+ ),
+ NamespaceTag(
+ "namespace",
+ {"name": "ns"},
+ (3, 9),
+ [
+ Text("\n ", (3, 31)),
+ DefTag(
+ "def",
+ {"name": "lala(hi, there)"},
+ (4, 13),
+ [
+ Text("\n ", (4, 42)),
+ CallTag(
+ "call",
+ {"expr": "something()"},
+ (5, 17),
+ [],
+ ),
+ Text("\n ", (5, 44)),
+ ],
+ ),
+ Text("\n ", (6, 20)),
+ ],
+ ),
+ Text(
+ """
+
+ """,
+ (7, 22),
+ ),
+ ],
+ ),
+ )
if compat.py3k:
+
def test_code(self):
- template = \
-"""text
+ template = """text
<%
print("hi")
for x in range(1,5):
@@ -363,22 +530,29 @@ more text
%>
"""
nodes = Lexer(template).parse()
- self._compare(nodes,
- TemplateNode({}, [
- Text('text\n ', (1, 1)),
- Code('\nprint("hi")\nfor x in range(1,5):\n '
- 'print(x)\n \n', False, (2, 5)),
- Text('\nmore text\n ', (6, 7)),
- Code('\nimport foo\n \n', True, (8, 5)),
- Text('\n', (10, 7))])
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Text("text\n ", (1, 1)),
+ Code(
+ '\nprint("hi")\nfor x in range(1,5):\n '
+ "print(x)\n \n",
+ False,
+ (2, 5),
+ ),
+ Text("\nmore text\n ", (6, 7)),
+ Code("\nimport foo\n \n", True, (8, 5)),
+ Text("\n", (10, 7)),
+ ],
+ ),
)
-
else:
def test_code(self):
- template = \
-"""text
+ template = """text
<%
print "hi"
for x in range(1,5):
@@ -390,19 +564,27 @@ more text
%>
"""
nodes = Lexer(template).parse()
- self._compare(nodes,
- TemplateNode({}, [
- Text('text\n ', (1, 1)),
- Code('\nprint "hi"\nfor x in range(1,5):\n '
- 'print x\n \n', False, (2, 5)),
- Text('\nmore text\n ', (6, 7)),
- Code('\nimport foo\n \n', True, (8, 5)),
- Text('\n', (10, 7))])
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Text("text\n ", (1, 1)),
+ Code(
+ '\nprint "hi"\nfor x in range(1,5):\n '
+ "print x\n \n",
+ False,
+ (2, 5),
+ ),
+ Text("\nmore text\n ", (6, 7)),
+ Code("\nimport foo\n \n", True, (8, 5)),
+ Text("\n", (10, 7)),
+ ],
+ ),
)
def test_code_and_tags(self):
- template = \
- """
+ template = """
<%namespace name="foo">
<%def name="x()">
this is x
@@ -422,24 +604,60 @@ more text
result: <%call expr="foo.x(result)"/>
"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({}, [Text('\n', (1, 1)),
- NamespaceTag('namespace', {'name': 'foo'}, (2,
- 1), [Text('\n ', (2, 24)), DefTag('def',
- {'name': 'x()'}, (3, 5),
- [Text('''\n this is x\n ''', (3, 22))]),
- Text('\n ', (5, 12)), DefTag('def', {'name'
- : 'y()'}, (6, 5),
- [Text('''\n this is y\n ''', (6, 22))]),
- Text('\n', (8, 12))]), Text('''\n\n''', (9, 14)),
- Code('''\nresult = []\ndata = get_data()\n'''
- '''for x in data:\n result.append(x+7)\n\n''',
- False, (11, 1)), Text('''\n\n result: ''', (16,
- 3)), CallTag('call', {'expr': 'foo.x(result)'
- }, (18, 13), []), Text('\n', (18, 42))]))
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Text("\n", (1, 1)),
+ NamespaceTag(
+ "namespace",
+ {"name": "foo"},
+ (2, 1),
+ [
+ Text("\n ", (2, 24)),
+ DefTag(
+ "def",
+ {"name": "x()"},
+ (3, 5),
+ [
+ Text(
+ """\n this is x\n """,
+ (3, 22),
+ )
+ ],
+ ),
+ Text("\n ", (5, 12)),
+ DefTag(
+ "def",
+ {"name": "y()"},
+ (6, 5),
+ [
+ Text(
+ """\n this is y\n """,
+ (6, 22),
+ )
+ ],
+ ),
+ Text("\n", (8, 12)),
+ ],
+ ),
+ Text("""\n\n""", (9, 14)),
+ Code(
+ """\nresult = []\ndata = get_data()\n"""
+ """for x in data:\n result.append(x+7)\n\n""",
+ False,
+ (11, 1),
+ ),
+ Text("""\n\n result: """, (16, 3)),
+ CallTag("call", {"expr": "foo.x(result)"}, (18, 13), []),
+ Text("\n", (18, 42)),
+ ],
+ ),
+ )
def test_expression(self):
- template = \
- """
+ template = """
this is some ${text} and this is ${textwith | escapes, moreescapes}
<%def name="hi()">
give me ${foo()} and ${bar()}
@@ -447,20 +665,36 @@ more text
${hi()}
"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({},
- [Text('\n this is some ', (1, 1)),
- Expression('text', [], (2, 22)),
- Text(' and this is ', (2, 29)),
- Expression('textwith ', ['escapes', 'moreescapes'
- ], (2, 42)), Text('\n ', (2, 76)),
- DefTag('def', {'name': 'hi()'}, (3, 9),
- [Text('\n give me ', (3, 27)),
- Expression('foo()', [], (4, 21)), Text(' and ',
- (4, 29)), Expression('bar()', [], (4, 34)),
- Text('\n ', (4, 42))]), Text('\n '
- , (5, 16)), Expression('hi()', [], (6, 9)),
- Text('\n', (6, 16))]))
-
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Text("\n this is some ", (1, 1)),
+ Expression("text", [], (2, 22)),
+ Text(" and this is ", (2, 29)),
+ Expression(
+ "textwith ", ["escapes", "moreescapes"], (2, 42)
+ ),
+ Text("\n ", (2, 76)),
+ DefTag(
+ "def",
+ {"name": "hi()"},
+ (3, 9),
+ [
+ Text("\n give me ", (3, 27)),
+ Expression("foo()", [], (4, 21)),
+ Text(" and ", (4, 29)),
+ Expression("bar()", [], (4, 34)),
+ Text("\n ", (4, 42)),
+ ],
+ ),
+ Text("\n ", (5, 16)),
+ Expression("hi()", [], (6, 9)),
+ Text("\n", (6, 16)),
+ ],
+ ),
+ )
def test_tricky_expression(self):
template = """
@@ -470,11 +704,14 @@ more text
nodes = Lexer(template).parse()
self._compare(
nodes,
- TemplateNode({}, [
- Text('\n\n ', (1, 1)),
- Expression('x and "|" or "hi"', [], (3, 13)),
- Text('\n ', (3, 33))
- ])
+ TemplateNode(
+ {},
+ [
+ Text("\n\n ", (1, 1)),
+ Expression('x and "|" or "hi"', [], (3, 13)),
+ Text("\n ", (3, 33)),
+ ],
+ ),
)
template = r"""
@@ -485,47 +722,68 @@ more text
nodes = Lexer(template).parse()
self._compare(
nodes,
- TemplateNode({}, [
- Text('\n\n ', (1, 1)),
- Expression("hello + '''heres '{|}' text | | }''' ",
- ['escape1'], (3, 13)),
- Text('\n ', (3, 62)),
- Expression(r"""'Tricky string: ' + '\\\"\\\'|\\'""",
- [], (4, 13)),
- Text('\n ', (4, 49))
- ])
+ TemplateNode(
+ {},
+ [
+ Text("\n\n ", (1, 1)),
+ Expression(
+ "hello + '''heres '{|}' text | | }''' ",
+ ["escape1"],
+ (3, 13),
+ ),
+ Text("\n ", (3, 62)),
+ Expression(
+ r"""'Tricky string: ' + '\\\"\\\'|\\'""", [], (4, 13)
+ ),
+ Text("\n ", (4, 49)),
+ ],
+ ),
)
def test_tricky_code(self):
if compat.py3k:
template = """<% print('hi %>') %>"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({},
- [Code("print('hi %>') \n", False, (1, 1))]))
+ self._compare(
+ nodes,
+ TemplateNode({}, [Code("print('hi %>') \n", False, (1, 1))]),
+ )
else:
template = """<% print 'hi %>' %>"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({},
- [Code("print 'hi %>' \n", False, (1, 1))]))
+ self._compare(
+ nodes,
+ TemplateNode({}, [Code("print 'hi %>' \n", False, (1, 1))]),
+ )
def test_tricky_code_2(self):
- template = \
- """<%
+ template = """<%
# someone's comment
%>
"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({},
- [Code("""
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Code(
+ """
# someone's comment
""",
- False, (1, 1)), Text('\n ', (3, 3))]))
+ False,
+ (1, 1),
+ ),
+ Text("\n ", (3, 3)),
+ ],
+ ),
+ )
if compat.py3k:
+
def test_tricky_code_3(self):
- template = \
- """<%
+ template = """<%
print('hi')
# this is a comment
# another comment
@@ -536,8 +794,13 @@ more text
# someone else's comment
%> '''and now some text '''"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({},
- [Code("""
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Code(
+ """
print('hi')
# this is a comment
# another comment
@@ -548,13 +811,18 @@ print('''
# someone else's comment
""",
- False, (1, 1)),
- Text(" '''and now some text '''", (10,
- 3))]))
+ False,
+ (1, 1),
+ ),
+ Text(" '''and now some text '''", (10, 3)),
+ ],
+ ),
+ )
+
else:
+
def test_tricky_code_3(self):
- template = \
- """<%
+ template = """<%
print 'hi'
# this is a comment
# another comment
@@ -565,44 +833,65 @@ print('''
# someone else's comment
%> '''and now some text '''"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({},
- [Code("""\nprint 'hi'\n# this is a comment\n"""
- """# another comment\nx = 7 """
- """# someone's '''comment\nprint '''\n """
- """there\n '''\n# someone else's """
- """comment\n\n""",
- False, (1, 1)),
- Text(" '''and now some text '''", (10, 3))]))
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Code(
+ """\nprint 'hi'\n# this is a comment\n"""
+ """# another comment\nx = 7 """
+ """# someone's '''comment\nprint '''\n """
+ """there\n '''\n# someone else's """
+ """comment\n\n""",
+ False,
+ (1, 1),
+ ),
+ Text(" '''and now some text '''", (10, 3)),
+ ],
+ ),
+ )
def test_tricky_code_4(self):
- template = \
- """<% foo = "\\"\\\\" %>"""
+ template = """<% foo = "\\"\\\\" %>"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({},
- [Code("""foo = "\\"\\\\" \n""",
- False, (1, 1))]))
+ self._compare(
+ nodes,
+ TemplateNode({}, [Code("""foo = "\\"\\\\" \n""", False, (1, 1))]),
+ )
def test_tricky_code_5(self):
- template = \
- """before ${ {'key': 'value'} } after"""
+ template = """before ${ {'key': 'value'} } after"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({},
- [Text('before ', (1, 1)),
- Expression(" {'key': 'value'} ", [], (1, 8)),
- Text(' after', (1, 29))]))
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Text("before ", (1, 1)),
+ Expression(" {'key': 'value'} ", [], (1, 8)),
+ Text(" after", (1, 29)),
+ ],
+ ),
+ )
def test_tricky_code_6(self):
- template = \
- """before ${ (0x5302 | 0x0400) } after"""
+ template = """before ${ (0x5302 | 0x0400) } after"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({},
- [Text('before ', (1, 1)),
- Expression(" (0x5302 | 0x0400) ", [], (1, 8)),
- Text(' after', (1, 30))]))
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Text("before ", (1, 1)),
+ Expression(" (0x5302 | 0x0400) ", [], (1, 8)),
+ Text(" after", (1, 30)),
+ ],
+ ),
+ )
def test_control_lines(self):
- template = \
- """
+ template = """
text text la la
% if foo():
mroe text la la blah blah
@@ -616,34 +905,51 @@ text text la la
"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({},
- [Text('''\ntext text la la\n''', (1, 1)),
- ControlLine('if', 'if foo():', False, (3, 1)),
- Text(' mroe text la la blah blah\n', (4, 1)),
- ControlLine('if', 'endif', True, (5, 1)),
- Text('''\n and osme more stuff\n''', (6,
- 1)), ControlLine('for', 'for l in range(1,5):',
- False, (8, 1)), Text(' tex tesl asdl l is ',
- (9, 1)), Expression('l', [], (9, 24)),
- Text(' kfmas d\n', (9, 28)), ControlLine('for',
- 'endfor', True, (10, 1)),
- Text(''' tetx text\n\n''', (11, 1))]))
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Text("""\ntext text la la\n""", (1, 1)),
+ ControlLine("if", "if foo():", False, (3, 1)),
+ Text(" mroe text la la blah blah\n", (4, 1)),
+ ControlLine("if", "endif", True, (5, 1)),
+ Text("""\n and osme more stuff\n""", (6, 1)),
+ ControlLine("for", "for l in range(1,5):", False, (8, 1)),
+ Text(" tex tesl asdl l is ", (9, 1)),
+ Expression("l", [], (9, 24)),
+ Text(" kfmas d\n", (9, 28)),
+ ControlLine("for", "endfor", True, (10, 1)),
+ Text(""" tetx text\n\n""", (11, 1)),
+ ],
+ ),
+ )
def test_control_lines_2(self):
- template = \
-"""% for file in requestattr['toc'].filenames:
+ template = """% for file in requestattr['toc'].filenames:
x
% endfor
"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({}, [ControlLine('for',
- "for file in requestattr['toc'].filenames:",
- False, (1, 1)), Text(' x\n', (2, 1)),
- ControlLine('for', 'endfor', True, (3, 1))]))
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ ControlLine(
+ "for",
+ "for file in requestattr['toc'].filenames:",
+ False,
+ (1, 1),
+ ),
+ Text(" x\n", (2, 1)),
+ ControlLine("for", "endfor", True, (3, 1)),
+ ],
+ ),
+ )
def test_long_control_lines(self):
- template = \
- """
+ template = """
% for file in \\
requestattr['toc'].filenames:
x
@@ -652,15 +958,22 @@ text text la la
nodes = Lexer(template).parse()
self._compare(
nodes,
- TemplateNode({}, [
- Text('\n', (1, 1)),
- ControlLine('for', "for file in \\\n "
- "requestattr['toc'].filenames:",
- False, (2, 1)),
- Text(' x\n', (4, 1)),
- ControlLine('for', 'endfor', True, (5, 1)),
- Text(' ', (6, 1))
- ])
+ TemplateNode(
+ {},
+ [
+ Text("\n", (1, 1)),
+ ControlLine(
+ "for",
+ "for file in \\\n "
+ "requestattr['toc'].filenames:",
+ False,
+ (2, 1),
+ ),
+ Text(" x\n", (4, 1)),
+ ControlLine("for", "endfor", True, (5, 1)),
+ Text(" ", (6, 1)),
+ ],
+ ),
)
def test_unmatched_control(self):
@@ -673,7 +986,7 @@ text text la la
assert_raises_message(
exceptions.SyntaxException,
"Keyword 'endif' doesn't match keyword 'for' at line: 5 char: 1",
- Lexer(template).parse
+ Lexer(template).parse,
)
def test_unmatched_control_2(self):
@@ -687,7 +1000,7 @@ text text la la
assert_raises_message(
exceptions.SyntaxException,
"Unterminated control keyword: 'if' at line: 3 char: 1",
- Lexer(template).parse
+ Lexer(template).parse,
)
def test_unmatched_control_3(self):
@@ -701,12 +1014,11 @@ text text la la
assert_raises_message(
exceptions.SyntaxException,
"Keyword 'endlala' doesn't match keyword 'for' at line: 5 char: 1",
- Lexer(template).parse
+ Lexer(template).parse,
)
def test_ternary_control(self):
- template = \
- """
+ template = """
% if x:
hi
% elif y+7==10:
@@ -718,20 +1030,27 @@ text text la la
% endif
"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({}, [Text('\n', (1, 1)),
- ControlLine('if', 'if x:', False, (2, 1)),
- Text(' hi\n', (3, 1)),
- ControlLine('elif', 'elif y+7==10:', False, (4,
- 1)), Text(' there\n', (5, 1)),
- ControlLine('elif', 'elif lala:', False, (6,
- 1)), Text(' lala\n', (7, 1)),
- ControlLine('else', 'else:', False, (8, 1)),
- Text(' hi\n', (9, 1)),
- ControlLine('if', 'endif', True, (10, 1))]))
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Text("\n", (1, 1)),
+ ControlLine("if", "if x:", False, (2, 1)),
+ Text(" hi\n", (3, 1)),
+ ControlLine("elif", "elif y+7==10:", False, (4, 1)),
+ Text(" there\n", (5, 1)),
+ ControlLine("elif", "elif lala:", False, (6, 1)),
+ Text(" lala\n", (7, 1)),
+ ControlLine("else", "else:", False, (8, 1)),
+ Text(" hi\n", (9, 1)),
+ ControlLine("if", "endif", True, (10, 1)),
+ ],
+ ),
+ )
def test_integration(self):
- template = \
- """<%namespace name="foo" file="somefile.html"/>
+ template = """<%namespace name="foo" file="somefile.html"/>
## inherit from foobar.html
<%inherit file="foobar.html"/>
@@ -753,31 +1072,51 @@ text text la la
</table>
"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({}, [NamespaceTag('namespace'
- , {'file': 'somefile.html', 'name': 'foo'},
- (1, 1), []), Text('\n', (1, 46)),
- Comment('inherit from foobar.html', (2, 1)),
- InheritTag('inherit', {'file': 'foobar.html'},
- (3, 1), []), Text('''\n\n''', (3, 31)),
- DefTag('def', {'name': 'header()'}, (5, 1),
- [Text('''\n <div>header</div>\n''', (5,
- 23))]), Text('\n', (7, 8)), DefTag('def',
- {'name': 'footer()'}, (8, 1),
- [Text('''\n <div> footer</div>\n''', (8,
- 23))]), Text('''\n\n<table>\n''', (10, 8)),
- ControlLine('for', 'for j in data():', False,
- (13, 1)), Text(' <tr>\n', (14, 1)),
- ControlLine('for', 'for x in j:', False, (15,
- 1)), Text(' <td>Hello ', (16, 1)),
- Expression('x', ['h'], (16, 23)), Text('</td>\n'
- , (16, 30)), ControlLine('for', 'endfor', True,
- (17, 1)), Text(' </tr>\n', (18, 1)),
- ControlLine('for', 'endfor', True, (19, 1)),
- Text('</table>\n', (20, 1))]))
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ NamespaceTag(
+ "namespace",
+ {"file": "somefile.html", "name": "foo"},
+ (1, 1),
+ [],
+ ),
+ Text("\n", (1, 46)),
+ Comment("inherit from foobar.html", (2, 1)),
+ InheritTag("inherit", {"file": "foobar.html"}, (3, 1), []),
+ Text("""\n\n""", (3, 31)),
+ DefTag(
+ "def",
+ {"name": "header()"},
+ (5, 1),
+ [Text("""\n <div>header</div>\n""", (5, 23))],
+ ),
+ Text("\n", (7, 8)),
+ DefTag(
+ "def",
+ {"name": "footer()"},
+ (8, 1),
+ [Text("""\n <div> footer</div>\n""", (8, 23))],
+ ),
+ Text("""\n\n<table>\n""", (10, 8)),
+ ControlLine("for", "for j in data():", False, (13, 1)),
+ Text(" <tr>\n", (14, 1)),
+ ControlLine("for", "for x in j:", False, (15, 1)),
+ Text(" <td>Hello ", (16, 1)),
+ Expression("x", ["h"], (16, 23)),
+ Text("</td>\n", (16, 30)),
+ ControlLine("for", "endfor", True, (17, 1)),
+ Text(" </tr>\n", (18, 1)),
+ ControlLine("for", "endfor", True, (19, 1)),
+ Text("</table>\n", (20, 1)),
+ ],
+ ),
+ )
def test_comment_after_statement(self):
- template = \
- """
+ template = """
% if x: #comment
hi
% else: #next
@@ -785,44 +1124,66 @@ text text la la
% endif #end
"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({}, [Text('\n', (1, 1)),
- ControlLine('if', 'if x: #comment', False, (2,
- 1)), Text(' hi\n', (3, 1)),
- ControlLine('else', 'else: #next', False, (4,
- 1)), Text(' hi\n', (5, 1)),
- ControlLine('if', 'endif #end', True, (6, 1))]))
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Text("\n", (1, 1)),
+ ControlLine("if", "if x: #comment", False, (2, 1)),
+ Text(" hi\n", (3, 1)),
+ ControlLine("else", "else: #next", False, (4, 1)),
+ Text(" hi\n", (5, 1)),
+ ControlLine("if", "endif #end", True, (6, 1)),
+ ],
+ ),
+ )
def test_crlf(self):
template = util.read_file(self._file_path("crlf.html"))
nodes = Lexer(template).parse()
self._compare(
nodes,
- TemplateNode({}, [
- Text('<html>\r\n\r\n', (1, 1)),
- PageTag('page', {
- 'args': "a=['foo',\n 'bar']"
- }, (3, 1), []),
- Text('\r\n\r\nlike the name says.\r\n\r\n', (4, 26)),
- ControlLine('for', 'for x in [1,2,3]:', False, (8, 1)),
- Text(' ', (9, 1)),
- Expression('x', [], (9, 9)),
- ControlLine('for', 'endfor', True, (10, 1)),
- Text('\r\n', (11, 1)),
- Expression("trumpeter == 'Miles' and "
- "trumpeter or \\\n 'Dizzy'",
- [], (12, 1)),
- Text('\r\n\r\n', (13, 15)),
- DefTag('def', {'name': 'hi()'}, (15, 1), [
- Text('\r\n hi!\r\n', (15, 19))]),
- Text('\r\n\r\n</html>\r\n', (17, 8))
- ])
- )
- assert flatten_result(Template(template).render()) \
+ TemplateNode(
+ {},
+ [
+ Text("<html>\r\n\r\n", (1, 1)),
+ PageTag(
+ "page",
+ {"args": "a=['foo',\n 'bar']"},
+ (3, 1),
+ [],
+ ),
+ Text("\r\n\r\nlike the name says.\r\n\r\n", (4, 26)),
+ ControlLine("for", "for x in [1,2,3]:", False, (8, 1)),
+ Text(" ", (9, 1)),
+ Expression("x", [], (9, 9)),
+ ControlLine("for", "endfor", True, (10, 1)),
+ Text("\r\n", (11, 1)),
+ Expression(
+ "trumpeter == 'Miles' and "
+ "trumpeter or \\\n 'Dizzy'",
+ [],
+ (12, 1),
+ ),
+ Text("\r\n\r\n", (13, 15)),
+ DefTag(
+ "def",
+ {"name": "hi()"},
+ (15, 1),
+ [Text("\r\n hi!\r\n", (15, 19))],
+ ),
+ Text("\r\n\r\n</html>\r\n", (17, 8)),
+ ],
+ ),
+ )
+ assert (
+ flatten_result(Template(template).render())
== """<html> like the name says. 1 2 3 Dizzy </html>"""
+ )
def test_comments(self):
- template = \
- """
+ template = """
<style>
#someselector
# other non comment stuff
@@ -842,22 +1203,34 @@ comment
hi
"""
nodes = Lexer(template).parse()
- self._compare(nodes, TemplateNode({},
- [Text('''\n<style>\n #someselector\n # '''
- '''other non comment stuff\n</style>\n''',
- (1, 1)), Comment('a comment', (6, 1)),
- Text('''\n# also not a comment\n\n''', (7, 1)),
- Comment('this is a comment', (10, 1)),
- Text('''\nthis is ## not a comment\n\n''', (11,
- 1)), Comment(''' multiline\ncomment\n''', (14,
- 1)), Text('''
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Text(
+ """\n<style>\n #someselector\n # """
+ """other non comment stuff\n</style>\n""",
+ (1, 1),
+ ),
+ Comment("a comment", (6, 1)),
+ Text("""\n# also not a comment\n\n""", (7, 1)),
+ Comment("this is a comment", (10, 1)),
+ Text("""\nthis is ## not a comment\n\n""", (11, 1)),
+ Comment(""" multiline\ncomment\n""", (14, 1)),
+ Text(
+ """
hi
-''', (16, 8))]))
+""",
+ (16, 8),
+ ),
+ ],
+ ),
+ )
def test_docs(self):
- template = \
- """
+ template = """
<%doc>
this is a comment
</%doc>
@@ -868,30 +1241,53 @@ hi
</%def>
"""
nodes = Lexer(template).parse()
- self._compare(nodes,
- TemplateNode({}, [Text('\n ', (1,
- 1)),
- Comment('''\n this is a comment\n ''',
- (2, 9)), Text('\n ', (4, 16)),
- DefTag('def', {'name': 'foo()'}, (5, 9),
- [Text('\n ', (5, 28)),
- Comment('''\n this is the foo func\n'''
- ''' ''',
- (6, 13)), Text('\n ', (8, 20))]),
- Text('\n ', (9, 16))]))
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Text("\n ", (1, 1)),
+ Comment(
+ """\n this is a comment\n """, (2, 9)
+ ),
+ Text("\n ", (4, 16)),
+ DefTag(
+ "def",
+ {"name": "foo()"},
+ (5, 9),
+ [
+ Text("\n ", (5, 28)),
+ Comment(
+ """\n this is the foo func\n"""
+ """ """,
+ (6, 13),
+ ),
+ Text("\n ", (8, 20)),
+ ],
+ ),
+ Text("\n ", (9, 16)),
+ ],
+ ),
+ )
def test_preprocess(self):
-
def preproc(text):
- return re.sub(r'(?<=\n)\s*#[^#]', '##', text)
+ return re.sub(r"(?<=\n)\s*#[^#]", "##", text)
- template = \
- """
+ template = """
hi
# old style comment
# another comment
"""
nodes = Lexer(template, preprocessor=preproc).parse()
- self._compare(nodes, TemplateNode({}, [Text('''\n hi\n''',
- (1, 1)), Comment('old style comment', (3, 1)),
- Comment('another comment', (4, 1))]))
+ self._compare(
+ nodes,
+ TemplateNode(
+ {},
+ [
+ Text("""\n hi\n""", (1, 1)),
+ Comment("old style comment", (3, 1)),
+ Comment("another comment", (4, 1)),
+ ],
+ ),
+ )
diff --git a/test/test_lookup.py b/test/test_lookup.py
index 43234d2..0dacfbb 100644
--- a/test/test_lookup.py
+++ b/test/test_lookup.py
@@ -1,46 +1,50 @@
+import os
+import unittest
+
+from mako import compat
+from mako import exceptions
+from mako import lookup
+from mako import runtime
from mako.template import Template
-from mako import lookup, exceptions, runtime
from mako.util import FastEncodingBuffer
-from mako import compat
-from test.util import flatten_result, result_lines
+from test import assert_raises_message
from test import eq_
-import unittest
-import os
-
-from test import TemplateTest, template_base, module_base, assert_raises_message
+from test import template_base
+from test.util import result_lines
tl = lookup.TemplateLookup(directories=[template_base])
+
+
class LookupTest(unittest.TestCase):
def test_basic(self):
- t = tl.get_template('index.html')
- assert result_lines(t.render()) == [
- "this is index"
- ]
+ t = tl.get_template("index.html")
+ assert result_lines(t.render()) == ["this is index"]
+
def test_subdir(self):
- t = tl.get_template('/subdir/index.html')
+ t = tl.get_template("/subdir/index.html")
assert result_lines(t.render()) == [
"this is sub index",
- "this is include 2"
-
+ "this is include 2",
]
- assert tl.get_template('/subdir/index.html').module_id \
- == '_subdir_index_html'
+ assert (
+ tl.get_template("/subdir/index.html").module_id
+ == "_subdir_index_html"
+ )
def test_updir(self):
- t = tl.get_template('/subdir/foo/../bar/../index.html')
+ t = tl.get_template("/subdir/foo/../bar/../index.html")
assert result_lines(t.render()) == [
"this is sub index",
- "this is include 2"
-
+ "this is include 2",
]
def test_directory_lookup(self):
"""test that hitting an existent directory still raises
LookupError."""
- self.assertRaises(exceptions.TopLevelLookupException,
- tl.get_template, "/subdir"
+ self.assertRaises(
+ exceptions.TopLevelLookupException, tl.get_template, "/subdir"
)
def test_no_lookup(self):
@@ -51,23 +55,26 @@ class LookupTest(unittest.TestCase):
except exceptions.TemplateLookupException:
eq_(
str(compat.exception_as()),
- "Template 'memory:%s' has no TemplateLookup associated" % \
- hex(id(t))
- )
+ "Template 'memory:%s' has no TemplateLookup associated"
+ % hex(id(t)),
+ )
def test_uri_adjust(self):
- tl = lookup.TemplateLookup(directories=['/foo/bar'])
- assert tl.filename_to_uri('/foo/bar/etc/lala/index.html') == \
- '/etc/lala/index.html'
+ tl = lookup.TemplateLookup(directories=["/foo/bar"])
+ assert (
+ tl.filename_to_uri("/foo/bar/etc/lala/index.html")
+ == "/etc/lala/index.html"
+ )
- tl = lookup.TemplateLookup(directories=['./foo/bar'])
- assert tl.filename_to_uri('./foo/bar/etc/index.html') == \
- '/etc/index.html'
+ tl = lookup.TemplateLookup(directories=["./foo/bar"])
+ assert (
+ tl.filename_to_uri("./foo/bar/etc/index.html") == "/etc/index.html"
+ )
def test_uri_cache(self):
"""test that the _uri_cache dictionary is available"""
- tl._uri_cache[('foo', 'bar')] = '/some/path'
- assert tl._uri_cache[('foo', 'bar')] == '/some/path'
+ tl._uri_cache[("foo", "bar")] = "/some/path"
+ assert tl._uri_cache[("foo", "bar")] == "/some/path"
def test_check_not_found(self):
tl = lookup.TemplateLookup()
@@ -75,34 +82,41 @@ class LookupTest(unittest.TestCase):
f = tl.get_template("foo")
assert f.uri in tl._collection
f.filename = "nonexistent"
- self.assertRaises(exceptions.TemplateLookupException,
- tl.get_template, "foo"
+ self.assertRaises(
+ exceptions.TemplateLookupException, tl.get_template, "foo"
)
assert f.uri not in tl._collection
def test_dont_accept_relative_outside_of_root(self):
"""test the mechanics of an include where
the include goes outside of the path"""
- tl = lookup.TemplateLookup(directories=[os.path.join(template_base, "subdir")])
+ tl = lookup.TemplateLookup(
+ directories=[os.path.join(template_base, "subdir")]
+ )
index = tl.get_template("index.html")
ctx = runtime.Context(FastEncodingBuffer())
- ctx._with_template=index
+ ctx._with_template = index
assert_raises_message(
exceptions.TemplateLookupException,
- "Template uri \"../index.html\" is invalid - it "
+ 'Template uri "../index.html" is invalid - it '
"cannot be relative outside of the root path",
- runtime._lookup_template, ctx, "../index.html", index.uri
+ runtime._lookup_template,
+ ctx,
+ "../index.html",
+ index.uri,
)
assert_raises_message(
exceptions.TemplateLookupException,
- "Template uri \"../othersubdir/foo.html\" is invalid - it "
+ 'Template uri "../othersubdir/foo.html" is invalid - it '
"cannot be relative outside of the root path",
- runtime._lookup_template, ctx, "../othersubdir/foo.html", index.uri
+ runtime._lookup_template,
+ ctx,
+ "../othersubdir/foo.html",
+ index.uri,
)
# this is OK since the .. cancels out
- t = runtime._lookup_template(ctx, "foo/../index.html", index.uri)
-
+ runtime._lookup_template(ctx, "foo/../index.html", index.uri)
diff --git a/test/test_loop.py b/test/test_loop.py
index bdfbaea..8104e49 100644
--- a/test/test_loop.py
+++ b/test/test_loop.py
@@ -1,136 +1,162 @@
import re
import unittest
-from mako.template import Template
-from mako.lookup import TemplateLookup
-from mako.codegen import (
- _FOR_LOOP, mangle_mako_loop, LoopVariable
- )
-from mako.runtime import LoopStack, LoopContext
from mako import exceptions
+from mako.codegen import _FOR_LOOP
+from mako.lookup import TemplateLookup
+from mako.runtime import LoopContext
+from mako.runtime import LoopStack
+from mako.template import Template
from test import assert_raises_message
-from test import TemplateTest, eq_
-from test.util import flatten_result, result_lines
+from test import TemplateTest
+from test.util import flatten_result
-class TestLoop(unittest.TestCase):
+class TestLoop(unittest.TestCase):
def test__FOR_LOOP(self):
for statement, target_list, expression_list in (
- ('for x in y:', 'x', 'y'),
- ('for x, y in z:', 'x, y', 'z'),
- ('for (x,y) in z:', '(x,y)', 'z'),
- ('for ( x, y, z) in a:', '( x, y, z)', 'a'),
- ('for x in [1, 2, 3]:', 'x', '[1, 2, 3]'),
- ('for x in "spam":', 'x', '"spam"'),
- ('for k,v in dict(a=1,b=2).items():', 'k,v',
- 'dict(a=1,b=2).items()'),
- ('for x in [y+1 for y in [1, 2, 3]]:', 'x',
- '[y+1 for y in [1, 2, 3]]')
- ):
+ ("for x in y:", "x", "y"),
+ ("for x, y in z:", "x, y", "z"),
+ ("for (x,y) in z:", "(x,y)", "z"),
+ ("for ( x, y, z) in a:", "( x, y, z)", "a"),
+ ("for x in [1, 2, 3]:", "x", "[1, 2, 3]"),
+ ('for x in "spam":', "x", '"spam"'),
+ (
+ "for k,v in dict(a=1,b=2).items():",
+ "k,v",
+ "dict(a=1,b=2).items()",
+ ),
+ (
+ "for x in [y+1 for y in [1, 2, 3]]:",
+ "x",
+ "[y+1 for y in [1, 2, 3]]",
+ ),
+ ):
match = _FOR_LOOP.match(statement)
assert match and match.groups() == (target_list, expression_list)
def test_no_loop(self):
- template = Template("""% for x in 'spam':
+ template = Template(
+ """% for x in 'spam':
${x}
-% endfor""")
+% endfor"""
+ )
code = template.code
- assert not re.match(r"loop = __M_loop._enter\(:", code), "No need to "\
- "generate a loop context if the loop variable wasn't accessed"
+ assert not re.match(r"loop = __M_loop._enter\(:", code), (
+ "No need to "
+ "generate a loop context if the loop variable wasn't accessed"
+ )
print(template.render())
def test_loop_demo(self):
- template = Template("""x|index|reverse_index|first|last|cycle|even|odd
+ template = Template(
+ """x|index|reverse_index|first|last|cycle|even|odd
% for x in 'ham':
-${x}|${loop.index}|${loop.reverse_index}|${loop.first}|${loop.last}|${loop.cycle('even', 'odd')}|${loop.even}|${loop.odd}
-% endfor""")
+${x}|${loop.index}|${loop.reverse_index}|${loop.first}|"""
+ """${loop.last}|${loop.cycle('even', 'odd')}|"""
+ """${loop.even}|${loop.odd}
+% endfor"""
+ )
expected = [
- "x|index|reverse_index|first|last|cycle|even|odd",
- "h|0|2|True|False|even|True|False",
- "a|1|1|False|False|odd|False|True",
- "m|2|0|False|True|even|True|False"
- ]
+ "x|index|reverse_index|first|last|cycle|even|odd",
+ "h|0|2|True|False|even|True|False",
+ "a|1|1|False|False|odd|False|True",
+ "m|2|0|False|True|even|True|False",
+ ]
code = template.code
- assert "loop = __M_loop._enter(" in code, "Generated a loop context since "\
- "the loop variable was accessed"
+ assert "loop = __M_loop._enter(" in code, (
+ "Generated a loop context since " "the loop variable was accessed"
+ )
rendered = template.render()
print(rendered)
for line in expected:
- assert line in rendered, "Loop variables give information about "\
- "the progress of the loop"
+ assert line in rendered, (
+ "Loop variables give information about "
+ "the progress of the loop"
+ )
def test_nested_loops(self):
- template = Template("""% for x in 'ab':
+ template = Template(
+ """% for x in 'ab':
${x} ${loop.index} <- start in outer loop
% for y in [0, 1]:
${y} ${loop.index} <- go to inner loop
% endfor
${x} ${loop.index} <- back to outer loop
-% endfor""")
- code = template.code
+% endfor"""
+ )
rendered = template.render()
expected = [
- "a 0 <- start in outer loop",
- "0 0 <- go to inner loop",
- "1 1 <- go to inner loop",
- "a 0 <- back to outer loop",
- "b 1 <- start in outer loop",
- "0 0 <- go to inner loop",
- "1 1 <- go to inner loop",
- "b 1 <- back to outer loop",
- ]
+ "a 0 <- start in outer loop",
+ "0 0 <- go to inner loop",
+ "1 1 <- go to inner loop",
+ "a 0 <- back to outer loop",
+ "b 1 <- start in outer loop",
+ "0 0 <- go to inner loop",
+ "1 1 <- go to inner loop",
+ "b 1 <- back to outer loop",
+ ]
for line in expected:
- assert line in rendered, "The LoopStack allows you to take "\
- "advantage of the loop variable even in embedded loops"
+ assert line in rendered, (
+ "The LoopStack allows you to take "
+ "advantage of the loop variable even in embedded loops"
+ )
def test_parent_loops(self):
- template = Template("""% for x in 'ab':
+ template = Template(
+ """% for x in 'ab':
${x} ${loop.index} <- outer loop
% for y in [0, 1]:
${y} ${loop.index} <- inner loop
${x} ${loop.parent.index} <- parent loop
% endfor
${x} ${loop.index} <- outer loop
-% endfor""")
+% endfor"""
+ )
code = template.code
rendered = template.render()
expected = [
- "a 0 <- outer loop",
- "a 0 <- parent loop",
- "b 1 <- outer loop",
- "b 1 <- parent loop"
- ]
+ "a 0 <- outer loop",
+ "a 0 <- parent loop",
+ "b 1 <- outer loop",
+ "b 1 <- parent loop",
+ ]
for line in expected:
print(code)
- assert line in rendered, "The parent attribute of a loop gives "\
- "you the previous loop context in the stack"
+ assert line in rendered, (
+ "The parent attribute of a loop gives "
+ "you the previous loop context in the stack"
+ )
def test_out_of_context_access(self):
template = Template("""${loop.index}""")
assert_raises_message(
exceptions.RuntimeException,
"No loop context is established",
- template.render
+ template.render,
)
-class TestLoopStack(unittest.TestCase):
+class TestLoopStack(unittest.TestCase):
def setUp(self):
self.stack = LoopStack()
- self.bottom = 'spam'
+ self.bottom = "spam"
self.stack.stack = [self.bottom]
def test_enter(self):
- iterable = 'ham'
+ iterable = "ham"
s = self.stack._enter(iterable)
- assert s is self.stack.stack[-1], "Calling the stack with an iterable returns "\
- "the stack"
- assert iterable == self.stack.stack[-1]._iterable, "and pushes the "\
- "iterable on the top of the stack"
+ assert s is self.stack.stack[-1], (
+ "Calling the stack with an iterable returns " "the stack"
+ )
+ assert iterable == self.stack.stack[-1]._iterable, (
+ "and pushes the " "iterable on the top of the stack"
+ )
def test__top(self):
- assert self.bottom == self.stack._top, "_top returns the last item "\
- "on the stack"
+ assert self.bottom == self.stack._top, (
+ "_top returns the last item " "on the stack"
+ )
def test__pop(self):
assert len(self.stack.stack) == 1
@@ -140,13 +166,13 @@ class TestLoopStack(unittest.TestCase):
def test__push(self):
assert len(self.stack.stack) == 1
- iterable = 'ham'
+ iterable = "ham"
self.stack._push(iterable)
assert len(self.stack.stack) == 2
assert iterable is self.stack._top._iterable
def test_exit(self):
- iterable = 'ham'
+ iterable = "ham"
self.stack._enter(iterable)
before = len(self.stack.stack)
self.stack._exit()
@@ -155,28 +181,30 @@ class TestLoopStack(unittest.TestCase):
class TestLoopContext(unittest.TestCase):
-
def setUp(self):
self.iterable = [1, 2, 3]
self.ctx = LoopContext(self.iterable)
def test___len__(self):
- assert len(self.iterable) == len(self.ctx), "The LoopContext is the "\
- "same length as the iterable"
+ assert len(self.iterable) == len(self.ctx), (
+ "The LoopContext is the " "same length as the iterable"
+ )
def test_index(self):
expected = tuple(range(len(self.iterable)))
actual = tuple(self.ctx.index for i in self.ctx)
- assert expected == actual, "The index is consistent with the current "\
- "iteration count"
+ assert expected == actual, (
+ "The index is consistent with the current " "iteration count"
+ )
def test_reverse_index(self):
length = len(self.iterable)
- expected = tuple([length-i-1 for i in range(length)])
+ expected = tuple([length - i - 1 for i in range(length)])
actual = tuple(self.ctx.reverse_index for i in self.ctx)
print(expected, actual)
- assert expected == actual, "The reverse_index is the number of "\
- "iterations until the end"
+ assert expected == actual, (
+ "The reverse_index is the number of " "iterations until the end"
+ )
def test_first(self):
expected = (True, False, False)
@@ -199,91 +227,95 @@ class TestLoopContext(unittest.TestCase):
assert expected == actual, "odd is true on odd iterations"
def test_cycle(self):
- expected = ('a', 'b', 'a')
- actual = tuple(self.ctx.cycle('a', 'b') for i in self.ctx)
+ expected = ("a", "b", "a")
+ actual = tuple(self.ctx.cycle("a", "b") for i in self.ctx)
assert expected == actual, "cycle endlessly cycles through the values"
+
class TestLoopFlags(TemplateTest):
def test_loop_disabled_template(self):
self._do_memory_test(
- """
+ """
the loop: ${loop}
""",
- "the loop: hi",
- template_args=dict(loop='hi'),
- filters=flatten_result,
- enable_loop=False
+ "the loop: hi",
+ template_args=dict(loop="hi"),
+ filters=flatten_result,
+ enable_loop=False,
)
def test_loop_disabled_lookup(self):
l = TemplateLookup(enable_loop=False)
- l.put_string("x",
- """
+ l.put_string(
+ "x",
+ """
the loop: ${loop}
- """
+ """,
)
self._do_test(
l.get_template("x"),
"the loop: hi",
- template_args=dict(loop='hi'),
+ template_args=dict(loop="hi"),
filters=flatten_result,
)
def test_loop_disabled_override_template(self):
self._do_memory_test(
- """
+ """
<%page enable_loop="True" />
% for i in (1, 2, 3):
${i} ${loop.index}
% endfor
""",
- "1 0 2 1 3 2",
- template_args=dict(loop='hi'),
- filters=flatten_result,
- enable_loop=False
+ "1 0 2 1 3 2",
+ template_args=dict(loop="hi"),
+ filters=flatten_result,
+ enable_loop=False,
)
def test_loop_disabled_override_lookup(self):
l = TemplateLookup(enable_loop=False)
- l.put_string("x",
- """
+ l.put_string(
+ "x",
+ """
<%page enable_loop="True" />
% for i in (1, 2, 3):
${i} ${loop.index}
% endfor
- """
+ """,
)
self._do_test(
l.get_template("x"),
"1 0 2 1 3 2",
- template_args=dict(loop='hi'),
+ template_args=dict(loop="hi"),
filters=flatten_result,
)
def test_loop_enabled_override_template(self):
self._do_memory_test(
- """
+ """
<%page enable_loop="True" />
% for i in (1, 2, 3):
${i} ${loop.index}
% endfor
""",
- "1 0 2 1 3 2",
- template_args=dict(),
- filters=flatten_result,
+ "1 0 2 1 3 2",
+ template_args=dict(),
+ filters=flatten_result,
)
def test_loop_enabled_override_lookup(self):
l = TemplateLookup()
- l.put_string("x",
- """
+ l.put_string(
+ "x",
+ """
<%page enable_loop="True" />
% for i in (1, 2, 3):
${i} ${loop.index}
% endfor
- """
+ """,
)
self._do_test(
@@ -292,4 +324,3 @@ class TestLoopFlags(TemplateTest):
template_args=dict(),
filters=flatten_result,
)
-
diff --git a/test/test_lru.py b/test/test_lru.py
index 6152799..7281537 100644
--- a/test/test_lru.py
+++ b/test/test_lru.py
@@ -1,34 +1,30 @@
-from mako.util import LRUCache
-import string
import unittest
-import time
-import random
-from mako.compat import thread
+from mako.util import LRUCache
+
class item:
- def __init__(self, id):
- self.id = id
+ def __init__(self, id_):
+ self.id = id_
def __str__(self):
return "item id %d" % self.id
-class LRUTest(unittest.TestCase):
-
+class LRUTest(unittest.TestCase):
def testlru(self):
- l = LRUCache(10, threshold=.2)
+ l = LRUCache(10, threshold=0.2)
- for id in range(1,20):
- l[id] = item(id)
+ for id_ in range(1, 20):
+ l[id_] = item(id_)
# first couple of items should be gone
assert 1 not in l
assert 2 not in l
# next batch over the threshold of 10 should be present
- for id in range(11,20):
- assert id in l
+ for id_ in range(11, 20):
+ assert id_ in l
l[12]
l[15]
@@ -41,74 +37,5 @@ class LRUTest(unittest.TestCase):
assert 11 not in l
assert 13 not in l
- for id in (25, 24, 23, 14, 12, 19, 18, 17, 16, 15):
- assert id in l
-
- def _disabled_test_threaded(self):
- size = 100
- threshold = .5
- all_elems = 2000
- hot_zone = list(range(30,40))
- cache = LRUCache(size, threshold)
-
- # element to store
- class Element(object):
- def __init__(self, id):
- self.id = id
- self.regets = 0
-
- # return an element. we will favor ids in the relatively small
- # "hot zone" 25% of the time.
- def get_elem():
- if random.randint(1,4) == 1:
- return hot_zone[random.randint(0, len(hot_zone) - 1)]
- else:
- return random.randint(1, all_elems)
-
- total = [0]
- # request thread.
- def request_elem():
- while True:
- total[0] += 1
- id = get_elem()
- try:
- elem = cache[id]
- elem.regets += 1
- except KeyError:
- e = Element(id)
- cache[id] = e
-
- time.sleep(random.random() / 1000)
-
- for x in range(0,20):
- _thread.start_new_thread(request_elem, ())
-
- # assert size doesn't grow unbounded, doesnt shrink well below size
- for x in range(0,5):
- time.sleep(1)
- print("size:", len(cache))
- assert len(cache) < size + size * threshold * 2
- assert len(cache) > size - (size * .1)
-
- # computs the average number of times a range of elements were "reused",
- # i.e. without being removed from the cache.
- def average_regets_in_range(start, end):
- elem = [e for e in list(cache.values()) if e.id >= start and e.id <= end]
- if len(elem) == 0:
- return 0
- avg = sum([e.regets for e in elem]) / len(elem)
- return avg
-
- hotzone_avg = average_regets_in_range(30, 40)
- control_avg = average_regets_in_range(450,760)
- total_avg = average_regets_in_range(0, 2000)
-
- # hotzone should be way above the others
- print("total fetches", total[0], "hotzone", \
- hotzone_avg, "control", \
- control_avg, "total", total_avg)
-
- assert hotzone_avg > total_avg * 5 > control_avg * 5
-
-
-
+ for id_ in (25, 24, 23, 14, 12, 19, 18, 17, 16, 15):
+ assert id_ in l
diff --git a/test/test_namespace.py b/test/test_namespace.py
index 90964b5..8d223d5 100644
--- a/test/test_namespace.py
+++ b/test/test_namespace.py
@@ -1,7 +1,10 @@
-from mako.template import Template
from mako import lookup
-from test.util import flatten_result, result_lines
-from test import TemplateTest, eq_
+from mako.template import Template
+from test import eq_
+from test import TemplateTest
+from test.util import flatten_result
+from test.util import result_lines
+
class NamespaceTest(TemplateTest):
def test_inline_crossreference(self):
@@ -21,7 +24,7 @@ class NamespaceTest(TemplateTest):
${x.b()}
""",
"this is x a this is x b, and heres this is x a",
- filters=flatten_result
+ filters=flatten_result,
)
def test_inline_assignment(self):
@@ -40,7 +43,7 @@ class NamespaceTest(TemplateTest):
""",
"this is x: 5",
- filters=flatten_result
+ filters=flatten_result,
)
def test_inline_arguments(self):
@@ -59,7 +62,7 @@ class NamespaceTest(TemplateTest):
""",
"result: 50",
- filters=flatten_result
+ filters=flatten_result,
)
def test_inline_not_duped(self):
@@ -78,38 +81,49 @@ class NamespaceTest(TemplateTest):
""",
"",
- filters=flatten_result
+ filters=flatten_result,
)
def test_dynamic(self):
collection = lookup.TemplateLookup()
- collection.put_string('a', """
+ collection.put_string(
+ "a",
+ """
<%namespace name="b" file="${context['b_def']}"/>
a. b: ${b.body()}
-""")
+""",
+ )
- collection.put_string('b', """
+ collection.put_string(
+ "b",
+ """
b.
-""")
+""",
+ )
eq_(
- flatten_result(collection.get_template('a').render(b_def='b')),
- "a. b: b."
+ flatten_result(collection.get_template("a").render(b_def="b")),
+ "a. b: b.",
)
def test_template(self):
collection = lookup.TemplateLookup()
- collection.put_string('main.html', """
+ collection.put_string(
+ "main.html",
+ """
<%namespace name="comp" file="defs.html"/>
this is main. ${comp.def1("hi")}
${comp.def2("there")}
-""")
+""",
+ )
- collection.put_string('defs.html', """
+ collection.put_string(
+ "defs.html",
+ """
<%def name="def1(s)">
def1: ${s}
</%def>
@@ -117,70 +131,103 @@ class NamespaceTest(TemplateTest):
<%def name="def2(x)">
def2: ${x}
</%def>
-""")
+""",
+ )
- assert flatten_result(collection.get_template('main.html').render()) == "this is main. def1: hi def2: there"
+ assert (
+ flatten_result(collection.get_template("main.html").render())
+ == "this is main. def1: hi def2: there"
+ )
def test_module(self):
collection = lookup.TemplateLookup()
- collection.put_string('main.html', """
+ collection.put_string(
+ "main.html",
+ """
<%namespace name="comp" module="test.sample_module_namespace"/>
this is main. ${comp.foo1()}
${comp.foo2("hi")}
-""")
+""",
+ )
- assert flatten_result(collection.get_template('main.html').render()) == "this is main. this is foo1. this is foo2, x is hi"
+ assert (
+ flatten_result(collection.get_template("main.html").render())
+ == "this is main. this is foo1. this is foo2, x is hi"
+ )
def test_module_2(self):
collection = lookup.TemplateLookup()
- collection.put_string('main.html', """
+ collection.put_string(
+ "main.html",
+ """
<%namespace name="comp" module="test.foo.test_ns"/>
this is main. ${comp.foo1()}
${comp.foo2("hi")}
-""")
+""",
+ )
- assert flatten_result(collection.get_template('main.html').render()) == "this is main. this is foo1. this is foo2, x is hi"
+ assert (
+ flatten_result(collection.get_template("main.html").render())
+ == "this is main. this is foo1. this is foo2, x is hi"
+ )
def test_module_imports(self):
collection = lookup.TemplateLookup()
- collection.put_string('main.html', """
+ collection.put_string(
+ "main.html",
+ """
<%namespace import="*" module="test.foo.test_ns"/>
this is main. ${foo1()}
${foo2("hi")}
-""")
+""",
+ )
- assert flatten_result(collection.get_template('main.html').render()) == "this is main. this is foo1. this is foo2, x is hi"
+ assert (
+ flatten_result(collection.get_template("main.html").render())
+ == "this is main. this is foo1. this is foo2, x is hi"
+ )
def test_module_imports_2(self):
collection = lookup.TemplateLookup()
- collection.put_string('main.html', """
+ collection.put_string(
+ "main.html",
+ """
<%namespace import="foo1, foo2" module="test.foo.test_ns"/>
this is main. ${foo1()}
${foo2("hi")}
-""")
+""",
+ )
- assert flatten_result(collection.get_template('main.html').render()) == "this is main. this is foo1. this is foo2, x is hi"
+ assert (
+ flatten_result(collection.get_template("main.html").render())
+ == "this is main. this is foo1. this is foo2, x is hi"
+ )
def test_context(self):
"""test that namespace callables get access to the current context"""
collection = lookup.TemplateLookup()
- collection.put_string('main.html', """
+ collection.put_string(
+ "main.html",
+ """
<%namespace name="comp" file="defs.html"/>
this is main. ${comp.def1()}
${comp.def2("there")}
-""")
+""",
+ )
- collection.put_string('defs.html', """
+ collection.put_string(
+ "defs.html",
+ """
<%def name="def1()">
def1: x is ${x}
</%def>
@@ -188,14 +235,22 @@ class NamespaceTest(TemplateTest):
<%def name="def2(x)">
def2: x is ${x}
</%def>
-""")
+""",
+ )
- assert flatten_result(collection.get_template('main.html').render(x="context x")) == "this is main. def1: x is context x def2: x is there"
+ assert (
+ flatten_result(
+ collection.get_template("main.html").render(x="context x")
+ )
+ == "this is main. def1: x is context x def2: x is there"
+ )
def test_overload(self):
collection = lookup.TemplateLookup()
- collection.put_string('main.html', """
+ collection.put_string(
+ "main.html",
+ """
<%namespace name="comp" file="defs.html">
<%def name="def1(x, y)">
overridden def1 ${x}, ${y}
@@ -204,9 +259,12 @@ class NamespaceTest(TemplateTest):
this is main. ${comp.def1("hi", "there")}
${comp.def2("there")}
- """)
+ """,
+ )
- collection.put_string('defs.html', """
+ collection.put_string(
+ "defs.html",
+ """
<%def name="def1(s)">
def1: ${s}
</%def>
@@ -214,13 +272,19 @@ class NamespaceTest(TemplateTest):
<%def name="def2(x)">
def2: ${x}
</%def>
- """)
+ """,
+ )
- assert flatten_result(collection.get_template('main.html').render()) == "this is main. overridden def1 hi, there def2: there"
+ assert (
+ flatten_result(collection.get_template("main.html").render())
+ == "this is main. overridden def1 hi, there def2: there"
+ )
def test_getattr(self):
collection = lookup.TemplateLookup()
- collection.put_string("main.html", """
+ collection.put_string(
+ "main.html",
+ """
<%namespace name="foo" file="ns.html"/>
<%
if hasattr(foo, 'lala'):
@@ -228,72 +292,93 @@ class NamespaceTest(TemplateTest):
if not hasattr(foo, 'hoho'):
context.write('foo has no hoho.')
%>
- """)
- collection.put_string("ns.html", """
+ """,
+ )
+ collection.put_string(
+ "ns.html",
+ """
<%def name="lala()">this is lala.</%def>
- """)
- assert flatten_result(collection.get_template("main.html").render()) == "this is lala.foo has no hoho."
+ """,
+ )
+ assert (
+ flatten_result(collection.get_template("main.html").render())
+ == "this is lala.foo has no hoho."
+ )
def test_in_def(self):
collection = lookup.TemplateLookup()
- collection.put_string("main.html", """
+ collection.put_string(
+ "main.html",
+ """
<%namespace name="foo" file="ns.html"/>
this is main. ${bar()}
<%def name="bar()">
this is bar, foo is ${foo.bar()}
</%def>
- """)
+ """,
+ )
- collection.put_string("ns.html", """
+ collection.put_string(
+ "ns.html",
+ """
<%def name="bar()">
this is ns.html->bar
</%def>
- """)
+ """,
+ )
assert result_lines(collection.get_template("main.html").render()) == [
"this is main.",
- "this is bar, foo is" ,
- "this is ns.html->bar"
+ "this is bar, foo is",
+ "this is ns.html->bar",
]
-
def test_in_remote_def(self):
collection = lookup.TemplateLookup()
- collection.put_string("main.html", """
+ collection.put_string(
+ "main.html",
+ """
<%namespace name="foo" file="ns.html"/>
this is main. ${bar()}
<%def name="bar()">
this is bar, foo is ${foo.bar()}
</%def>
- """)
+ """,
+ )
- collection.put_string("ns.html", """
+ collection.put_string(
+ "ns.html",
+ """
<%def name="bar()">
this is ns.html->bar
</%def>
- """)
+ """,
+ )
- collection.put_string("index.html", """
+ collection.put_string(
+ "index.html",
+ """
<%namespace name="main" file="main.html"/>
this is index
${main.bar()}
- """)
+ """,
+ )
- assert result_lines(collection.get_template("index.html").render()) == [
- "this is index",
- "this is bar, foo is" ,
- "this is ns.html->bar"
- ]
+ assert result_lines(
+ collection.get_template("index.html").render()
+ ) == ["this is index", "this is bar, foo is", "this is ns.html->bar"]
def test_dont_pollute_self(self):
# test that get_namespace() doesn't modify the original context
# incompatibly
collection = lookup.TemplateLookup()
- collection.put_string("base.html", """
+ collection.put_string(
+ "base.html",
+ """
<%def name="foo()">
<%
@@ -313,16 +398,20 @@ class NamespaceTest(TemplateTest):
</%def>
- """)
+ """,
+ )
- collection.put_string("page.html", """
+ collection.put_string(
+ "page.html",
+ """
<%inherit file="base.html"/>
${self.foo()}
hello world
- """)
+ """,
+ )
collection.put_string("foo.html", """<%inherit file="base.html"/>""")
assert result_lines(collection.get_template("page.html").render()) == [
@@ -332,38 +421,49 @@ class NamespaceTest(TemplateTest):
"hello world",
"name: self:page.html",
"name via bar:",
- "self:page.html"
+ "self:page.html",
]
def test_inheritance(self):
- """test namespace initialization in a base inherited template that doesnt otherwise access the namespace"""
+ """test namespace initialization in a base inherited template that
+ doesnt otherwise access the namespace"""
collection = lookup.TemplateLookup()
- collection.put_string("base.html", """
+ collection.put_string(
+ "base.html",
+ """
<%namespace name="foo" file="ns.html" inheritable="True"/>
${next.body()}
-""")
- collection.put_string("ns.html", """
+""",
+ )
+ collection.put_string(
+ "ns.html",
+ """
<%def name="bar()">
this is ns.html->bar
</%def>
- """)
+ """,
+ )
- collection.put_string("index.html", """
+ collection.put_string(
+ "index.html",
+ """
<%inherit file="base.html"/>
this is index
${self.foo.bar()}
- """)
+ """,
+ )
- assert result_lines(collection.get_template("index.html").render()) == [
- "this is index",
- "this is ns.html->bar"
- ]
+ assert result_lines(
+ collection.get_template("index.html").render()
+ ) == ["this is index", "this is ns.html->bar"]
def test_inheritance_two(self):
collection = lookup.TemplateLookup()
- collection.put_string("base.html", """
+ collection.put_string(
+ "base.html",
+ """
<%def name="foo()">
base.foo
</%def>
@@ -371,8 +471,11 @@ class NamespaceTest(TemplateTest):
<%def name="bat()">
base.bat
</%def>
-""")
- collection.put_string("lib.html", """
+""",
+ )
+ collection.put_string(
+ "lib.html",
+ """
<%inherit file="base.html"/>
<%def name="bar()">
lib.bar
@@ -386,19 +489,27 @@ class NamespaceTest(TemplateTest):
lib.foo
</%def>
- """)
+ """,
+ )
- collection.put_string("front.html", """
+ collection.put_string(
+ "front.html",
+ """
<%namespace name="lib" file="lib.html"/>
${lib.bar()}
- """)
+ """,
+ )
- assert result_lines(collection.get_template("front.html").render()) == ['lib.bar', 'base.foo', 'lib.foo', 'base.bat', 'base.bat']
+ assert result_lines(
+ collection.get_template("front.html").render()
+ ) == ["lib.bar", "base.foo", "lib.foo", "base.bat", "base.bat"]
def test_attr(self):
l = lookup.TemplateLookup()
- l.put_string("foo.html", """
+ l.put_string(
+ "foo.html",
+ """
<%!
foofoo = "foo foo"
onlyfoo = "only foo"
@@ -414,9 +525,12 @@ class NamespaceTest(TemplateTest):
${self.attr.onlyfoo}
${self.attr.lala}
${self.attr.foolala}
- """)
+ """,
+ )
- l.put_string("base.html", """
+ l.put_string(
+ "base.html",
+ """
<%!
basefoo = "base foo 1"
foofoo = "base foo 2"
@@ -433,7 +547,8 @@ class NamespaceTest(TemplateTest):
${self.attr.foolala}
body
${self.body()}
- """)
+ """,
+ )
assert result_lines(l.get_template("foo.html").render()) == [
"base foo 1",
@@ -452,33 +567,43 @@ class NamespaceTest(TemplateTest):
def test_attr_raise(self):
l = lookup.TemplateLookup()
- l.put_string("foo.html", """
+ l.put_string(
+ "foo.html",
+ """
<%def name="foo()">
</%def>
- """)
+ """,
+ )
- l.put_string("bar.html", """
+ l.put_string(
+ "bar.html",
+ """
<%namespace name="foo" file="foo.html"/>
${foo.notfoo()}
- """)
+ """,
+ )
self.assertRaises(AttributeError, l.get_template("bar.html").render)
def test_custom_tag_1(self):
- template = Template("""
+ template = Template(
+ """
<%def name="foo(x, y)">
foo: ${x} ${y}
</%def>
<%self:foo x="5" y="${7+8}"/>
- """)
- assert result_lines(template.render()) == ['foo: 5 15']
+ """
+ )
+ assert result_lines(template.render()) == ["foo: 5 15"]
def test_custom_tag_2(self):
collection = lookup.TemplateLookup()
- collection.put_string("base.html", """
+ collection.put_string(
+ "base.html",
+ """
<%def name="foo(x, y)">
foo: ${x} ${y}
</%def>
@@ -490,9 +615,12 @@ class NamespaceTest(TemplateTest):
<%def name="bar(x)">
${caller.body(z=x)}
</%def>
- """)
+ """,
+ )
- collection.put_string("index.html", """
+ collection.put_string(
+ "index.html",
+ """
<%namespace name="myns" file="base.html"/>
<%myns:foo x="${'some x'}" y="some y"/>
@@ -501,45 +629,57 @@ class NamespaceTest(TemplateTest):
record: ${z}
</%myns:bar>
- """)
+ """,
+ )
- assert result_lines(collection.get_template("index.html").render()) == [
- 'foo: some x some y',
- 'record: the bat! 10'
- ]
+ assert result_lines(
+ collection.get_template("index.html").render()
+ ) == ["foo: some x some y", "record: the bat! 10"]
def test_custom_tag_3(self):
collection = lookup.TemplateLookup()
- collection.put_string("base.html", """
+ collection.put_string(
+ "base.html",
+ """
<%namespace name="foo" file="ns.html" inheritable="True"/>
${next.body()}
- """)
- collection.put_string("ns.html", """
+ """,
+ )
+ collection.put_string(
+ "ns.html",
+ """
<%def name="bar()">
this is ns.html->bar
caller body: ${caller.body()}
</%def>
- """)
+ """,
+ )
- collection.put_string("index.html", """
+ collection.put_string(
+ "index.html",
+ """
<%inherit file="base.html"/>
this is index
<%self.foo:bar>
call body
</%self.foo:bar>
- """)
+ """,
+ )
- assert result_lines(collection.get_template("index.html").render()) == [
+ assert result_lines(
+ collection.get_template("index.html").render()
+ ) == [
"this is index",
"this is ns.html->bar",
"caller body:",
- "call body"
+ "call body",
]
def test_custom_tag_case_sensitive(self):
- t = Template("""
+ t = Template(
+ """
<%def name="renderPanel()">
panel ${caller.body()}
</%def>
@@ -551,67 +691,86 @@ class NamespaceTest(TemplateTest):
</%def>
<%self:renderTablePanel/>
- """)
- assert result_lines(t.render()) == ['panel', 'hi']
-
+ """
+ )
+ assert result_lines(t.render()) == ["panel", "hi"]
def test_expr_grouping(self):
- """test that parenthesis are placed around string-embedded expressions."""
+ """test that parenthesis are placed around string-embedded
+ expressions."""
- template = Template("""
+ template = Template(
+ """
<%def name="bar(x, y)">
${x}
${y}
</%def>
<%self:bar x=" ${foo} " y="x${g and '1' or '2'}y"/>
- """, input_encoding='utf-8')
+ """,
+ input_encoding="utf-8",
+ )
# the concat has to come out as "x + (g and '1' or '2') + y"
- assert result_lines(template.render(foo='this is foo', g=False)) == [
+ assert result_lines(template.render(foo="this is foo", g=False)) == [
"this is foo",
- "x2y"
+ "x2y",
]
-
def test_ccall(self):
collection = lookup.TemplateLookup()
- collection.put_string("base.html", """
+ collection.put_string(
+ "base.html",
+ """
<%namespace name="foo" file="ns.html" inheritable="True"/>
${next.body()}
- """)
- collection.put_string("ns.html", """
+ """,
+ )
+ collection.put_string(
+ "ns.html",
+ """
<%def name="bar()">
this is ns.html->bar
caller body: ${caller.body()}
</%def>
- """)
+ """,
+ )
- collection.put_string("index.html", """
+ collection.put_string(
+ "index.html",
+ """
<%inherit file="base.html"/>
this is index
<%call expr="self.foo.bar()">
call body
</%call>
- """)
+ """,
+ )
- assert result_lines(collection.get_template("index.html").render()) == [
+ assert result_lines(
+ collection.get_template("index.html").render()
+ ) == [
"this is index",
"this is ns.html->bar",
"caller body:",
- "call body"
+ "call body",
]
def test_ccall_2(self):
collection = lookup.TemplateLookup()
- collection.put_string("base.html", """
+ collection.put_string(
+ "base.html",
+ """
<%namespace name="foo" file="ns1.html" inheritable="True"/>
${next.body()}
- """)
- collection.put_string("ns1.html", """
+ """,
+ )
+ collection.put_string(
+ "ns1.html",
+ """
<%namespace name="foo2" file="ns2.html"/>
<%def name="bar()">
<%call expr="foo2.ns2_bar()">
@@ -619,36 +778,47 @@ class NamespaceTest(TemplateTest):
caller body: ${caller.body()}
</%call>
</%def>
- """)
+ """,
+ )
- collection.put_string("ns2.html", """
+ collection.put_string(
+ "ns2.html",
+ """
<%def name="ns2_bar()">
this is ns2.html->bar
caller body: ${caller.body()}
</%def>
- """)
+ """,
+ )
- collection.put_string("index.html", """
+ collection.put_string(
+ "index.html",
+ """
<%inherit file="base.html"/>
this is index
<%call expr="self.foo.bar()">
call body
</%call>
- """)
+ """,
+ )
- assert result_lines(collection.get_template("index.html").render()) == [
+ assert result_lines(
+ collection.get_template("index.html").render()
+ ) == [
"this is index",
"this is ns2.html->bar",
"caller body:",
"this is ns1.html->bar",
"caller body:",
- "call body"
+ "call body",
]
def test_import(self):
collection = lookup.TemplateLookup()
- collection.put_string("functions.html","""
+ collection.put_string(
+ "functions.html",
+ """
<%def name="foo()">
this is foo
</%def>
@@ -660,17 +830,23 @@ class NamespaceTest(TemplateTest):
<%def name="lala()">
this is lala
</%def>
- """)
+ """,
+ )
- collection.put_string("func2.html", """
+ collection.put_string(
+ "func2.html",
+ """
<%def name="a()">
this is a
</%def>
<%def name="b()">
this is b
</%def>
- """)
- collection.put_string("index.html", """
+ """,
+ )
+ collection.put_string(
+ "index.html",
+ """
<%namespace file="functions.html" import="*"/>
<%namespace file="func2.html" import="a, b"/>
${foo()}
@@ -679,26 +855,36 @@ class NamespaceTest(TemplateTest):
${a()}
${b()}
${x}
- """)
+ """,
+ )
- assert result_lines(collection.get_template("index.html").render(bar="this is bar", x="this is x")) == [
+ assert result_lines(
+ collection.get_template("index.html").render(
+ bar="this is bar", x="this is x"
+ )
+ ) == [
"this is foo",
"this is bar",
"this is lala",
"this is a",
"this is b",
- "this is x"
+ "this is x",
]
def test_import_calledfromdef(self):
l = lookup.TemplateLookup()
- l.put_string("a", """
+ l.put_string(
+ "a",
+ """
<%def name="table()">
im table
</%def>
- """)
+ """,
+ )
- l.put_string("b","""
+ l.put_string(
+ "b",
+ """
<%namespace file="a" import="table"/>
<%
@@ -708,14 +894,17 @@ class NamespaceTest(TemplateTest):
%>
${table2()}
- """)
+ """,
+ )
t = l.get_template("b")
assert flatten_result(t.render()) == "im table"
def test_closure_import(self):
collection = lookup.TemplateLookup()
- collection.put_string("functions.html","""
+ collection.put_string(
+ "functions.html",
+ """
<%def name="foo()">
this is foo
</%def>
@@ -723,9 +912,12 @@ class NamespaceTest(TemplateTest):
<%def name="bar()">
this is bar
</%def>
- """)
+ """,
+ )
- collection.put_string("index.html", """
+ collection.put_string(
+ "index.html",
+ """
<%namespace file="functions.html" import="*"/>
<%def name="cl1()">
${foo()}
@@ -737,14 +929,17 @@ class NamespaceTest(TemplateTest):
${cl1()}
${cl2()}
- """)
- assert result_lines(collection.get_template("index.html").render(bar="this is bar", x="this is x")) == [
- "this is foo",
- "this is bar",
- ]
+ """,
+ )
+ assert result_lines(
+ collection.get_template("index.html").render(
+ bar="this is bar", x="this is x"
+ )
+ ) == ["this is foo", "this is bar"]
def test_import_local(self):
- t = Template("""
+ t = Template(
+ """
<%namespace import="*">
<%def name="foo()">
this is foo
@@ -753,12 +948,15 @@ class NamespaceTest(TemplateTest):
${foo()}
- """)
+ """
+ )
assert flatten_result(t.render()) == "this is foo"
def test_ccall_import(self):
collection = lookup.TemplateLookup()
- collection.put_string("functions.html","""
+ collection.put_string(
+ "functions.html",
+ """
<%def name="foo()">
this is foo
</%def>
@@ -768,9 +966,12 @@ class NamespaceTest(TemplateTest):
${caller.body()}
${caller.lala()}
</%def>
- """)
+ """,
+ )
- collection.put_string("index.html", """
+ collection.put_string(
+ "index.html",
+ """
<%namespace name="func" file="functions.html" import="*"/>
<%call expr="bar()">
this is index embedded
@@ -779,14 +980,17 @@ class NamespaceTest(TemplateTest):
this is lala ${foo()}
</%def>
</%call>
- """)
- #print collection.get_template("index.html").code
- #print collection.get_template("functions.html").code
- assert result_lines(collection.get_template("index.html").render()) == [
+ """,
+ )
+ # print collection.get_template("index.html").code
+ # print collection.get_template("functions.html").code
+ assert result_lines(
+ collection.get_template("index.html").render()
+ ) == [
"this is bar.",
"this is index embedded",
"foo is",
"this is foo",
"this is lala",
- "this is foo"
+ "this is foo",
]
diff --git a/test/test_pygen.py b/test/test_pygen.py
index 7671bd9..daa76de 100644
--- a/test/test_pygen.py
+++ b/test/test_pygen.py
@@ -1,7 +1,8 @@
import unittest
-from mako.pygen import PythonPrinter, adjust_whitespace
from mako.compat import StringIO
+from mako.pygen import adjust_whitespace
+from mako.pygen import PythonPrinter
from test import eq_
@@ -14,12 +15,15 @@ class GeneratePythonTest(unittest.TestCase):
printer.writeline("print x")
printer.writeline(None)
printer.writeline("print y")
- assert stream.getvalue() == \
-"""import lala
+ assert (
+ stream.getvalue()
+ == """import lala
for x in foo:
print x
print y
"""
+ )
+
def test_generate_adjusted(self):
block = """
x = 5 +6
@@ -31,18 +35,20 @@ print y
printer = PythonPrinter(stream)
printer.write_indented_block(block)
printer.close()
- #print stream.getvalue()
- assert stream.getvalue() == \
-"""
+ # print stream.getvalue()
+ assert (
+ stream.getvalue()
+ == """
x = 5 +6
if x > 7:
for y in range(1,5):
print "<td>%s</td>" % y
"""
+ )
+
def test_generate_combo(self):
- block = \
-"""
+ block = """
x = 5 +6
if x > 7:
for y in range(1,5):
@@ -60,9 +66,10 @@ if x > 7:
printer.writeline(None)
printer.writeline("print y")
printer.close()
- #print "->" + stream.getvalue().replace(' ', '#') + "<-"
- eq_(stream.getvalue(),
-"""import lala
+ # print "->" + stream.getvalue().replace(' ', '#') + "<-"
+ eq_(
+ stream.getvalue(),
+ """import lala
for x in foo:
print x
@@ -75,10 +82,11 @@ for x in foo:
foo(lala)
print y
-""")
+""",
+ )
+
def test_multi_line(self):
- block = \
-"""
+ block = """
if test:
print ''' this is a block of stuff.
this is more stuff in the block.
@@ -90,9 +98,10 @@ and more block.
printer = PythonPrinter(stream)
printer.write_indented_block(block)
printer.close()
- #print stream.getvalue()
- assert stream.getvalue() == \
-"""
+ # print stream.getvalue()
+ assert (
+ stream.getvalue()
+ == """
if test:
print ''' this is a block of stuff.
this is more stuff in the block.
@@ -101,6 +110,7 @@ and more block.
do_more_stuff(g)
"""
+ )
def test_false_unindentor(self):
stream = StringIO()
@@ -113,23 +123,23 @@ and more block.
None,
"finally:",
"dosomething",
- None
+ None,
]:
printer.writeline(line)
- assert stream.getvalue() == \
-"""try:
+ assert (
+ stream.getvalue()
+ == """try:
elsemyvar = 12
if True:
print 'hi'
finally:
dosomething
-""" , stream.getvalue()
-
+"""
+ ), stream.getvalue()
def test_backslash_line(self):
- block = \
-"""
+ block = """
# comment
if test:
if (lala + hoho) + \\
@@ -141,8 +151,9 @@ finally:
printer = PythonPrinter(stream)
printer.write_indented_block(block)
printer.close()
- assert stream.getvalue() == \
-"""
+ assert (
+ stream.getvalue()
+ == """
# comment
if test:
if (lala + hoho) + \\
@@ -151,6 +162,8 @@ if test:
print "more indent"
"""
+ )
+
class WhitespaceTest(unittest.TestCase):
def test_basic(self):
@@ -159,12 +172,14 @@ class WhitespaceTest(unittest.TestCase):
print x
print "hi"
"""
- assert adjust_whitespace(text) == \
-"""
+ assert (
+ adjust_whitespace(text)
+ == """
for x in range(0,15):
print x
print "hi"
"""
+ )
def test_blank_lines(self):
text = """
@@ -174,14 +189,16 @@ print "hi"
print g
"""
- assert adjust_whitespace(text) == \
-"""
+ assert (
+ adjust_whitespace(text)
+ == """
print "hi" # a comment
# more comments
print g
"""
+ )
def test_open_quotes_with_pound(self):
text = '''
@@ -189,15 +206,17 @@ print g
# and this is text
# and this is too """
'''
- assert adjust_whitespace(text) == \
-'''
+ assert (
+ adjust_whitespace(text)
+ == '''
print """ this is text
# and this is text
# and this is too """
'''
+ )
def test_quote_with_comments(self):
- text= """
+ text = """
print 'hi'
# this is a comment
# another comment
@@ -208,8 +227,9 @@ print """ this is text
# someone else's comment
"""
- assert adjust_whitespace(text) == \
-"""
+ assert (
+ adjust_whitespace(text)
+ == """
print 'hi'
# this is a comment
# another comment
@@ -219,7 +239,7 @@ print '''
'''
# someone else's comment
"""
-
+ )
def test_quotes_with_pound(self):
text = '''
@@ -228,13 +248,15 @@ print '''
elif False:
"bar"
'''
- assert adjust_whitespace(text) == \
-'''
+ assert (
+ adjust_whitespace(text)
+ == '''
if True:
"""#"""
elif False:
"bar"
'''
+ )
def test_quotes(self):
text = """
@@ -244,11 +266,13 @@ asdkfjnads kfajns '''
if x:
print y
"""
- assert adjust_whitespace(text) == \
-"""
+ assert (
+ adjust_whitespace(text)
+ == """
print ''' aslkjfnas kjdfn
askdjfnaskfd fkasnf dknf sadkfjn asdkfjna sdakjn
asdkfjnads kfajns '''
if x:
print y
"""
+ )
diff --git a/test/test_runtime.py b/test/test_runtime.py
index 80b97ce..d87d264 100644
--- a/test/test_runtime.py
+++ b/test/test_runtime.py
@@ -1,21 +1,21 @@
"""Assorted runtime unit tests
"""
-from mako import runtime
import unittest
+
+from mako import runtime
from test import eq_
+
class ContextTest(unittest.TestCase):
def test_locals_kwargs(self):
- c = runtime.Context(None, foo='bar')
- eq_(c.kwargs, {'foo': 'bar'})
+ c = runtime.Context(None, foo="bar")
+ eq_(c.kwargs, {"foo": "bar"})
- d = c._locals({'zig': 'zag'})
+ d = c._locals({"zig": "zag"})
# kwargs is the original args sent to the Context,
# it's intentionally kept separate from _data
- eq_(c.kwargs, {'foo': 'bar'})
- eq_(d.kwargs, {'foo': 'bar'})
-
- eq_(d._data['zig'], 'zag')
-
+ eq_(c.kwargs, {"foo": "bar"})
+ eq_(d.kwargs, {"foo": "bar"})
+ eq_(d._data["zig"], "zag")
diff --git a/test/test_template.py b/test/test_template.py
index 1f2d0c1..89e5a61 100644
--- a/test/test_template.py
+++ b/test/test_template.py
@@ -1,17 +1,28 @@
# -*- coding: utf-8 -*-
-from mako.template import Template, ModuleTemplate, ModuleInfo
-from mako.lookup import TemplateLookup
-from mako.ext.preprocessors import convert_comments
-from mako import exceptions, runtime
+import os
+import unittest
+
from mako import compat
+from mako import exceptions
+from mako import runtime
from mako import util
-import os
-from test.util import flatten_result, result_lines
from mako.compat import u
-from test import TemplateTest, eq_, template_base, module_base, \
- assert_raises, assert_raises_message, requires_python_2
-import unittest
+from mako.ext.preprocessors import convert_comments
+from mako.lookup import TemplateLookup
+from mako.template import ModuleInfo
+from mako.template import ModuleTemplate
+from mako.template import Template
+from test import assert_raises
+from test import assert_raises_message
+from test import eq_
+from test import module_base
+from test import requires_python_2
+from test import template_base
+from test import TemplateTest
+from test.util import flatten_result
+from test.util import result_lines
+
class ctx(object):
def __init__(self, a, b):
@@ -23,14 +34,17 @@ class ctx(object):
def __exit__(self, *arg):
pass
+
class EncodingTest(TemplateTest):
def test_escapes_html_tags(self):
from mako.exceptions import html_error_template
- x = Template("""
+ x = Template(
+ """
X:
<% raise Exception('<span style="color:red">Foobar</span>') %>
- """)
+ """
+ )
try:
x.render()
@@ -38,254 +52,390 @@ class EncodingTest(TemplateTest):
# <h3>Exception: <span style="color:red">Foobar</span></h3>
markup = html_error_template().render(full=False, css=False)
if compat.py3k:
- assert '<span style="color:red">Foobar</span></h3>'\
- .encode('ascii') not in markup
- assert '&lt;span style=&#34;color:red&#34;'\
- '&gt;Foobar&lt;/span&gt;'\
- .encode('ascii') in markup
+ assert (
+ '<span style="color:red">Foobar</span></h3>'.encode(
+ "ascii"
+ )
+ not in markup
+ )
+ assert (
+ "&lt;span style=&#34;color:red&#34;"
+ "&gt;Foobar&lt;/span&gt;".encode("ascii") in markup
+ )
else:
- assert '<span style="color:red">Foobar</span></h3>' \
- not in markup
- assert '&lt;span style=&#34;color:red&#34;'\
- '&gt;Foobar&lt;/span&gt;' in markup
+ assert (
+ '<span style="color:red">Foobar</span></h3>' not in markup
+ )
+ assert (
+ "&lt;span style=&#34;color:red&#34;"
+ "&gt;Foobar&lt;/span&gt;" in markup
+ )
def test_unicode(self):
self._do_memory_test(
- u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""),
- u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""")
+ u(
+ "Alors vous imaginez ma surprise, au lever du jour, quand "
+ "une drôle de petite voix m’a réveillé. Elle disait: "
+ "« S’il vous plaît… dessine-moi un mouton! »"
+ ),
+ u(
+ "Alors vous imaginez ma surprise, au lever du jour, quand "
+ "une drôle de petite voix m’a réveillé. Elle disait: "
+ "« S’il vous plaît… dessine-moi un mouton! »"
+ ),
)
def test_encoding_doesnt_conflict(self):
self._do_memory_test(
- u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""),
- u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""),
- output_encoding='utf-8'
+ u(
+ "Alors vous imaginez ma surprise, au lever du jour, quand "
+ "une drôle de petite voix m’a réveillé. Elle disait: "
+ "« S’il vous plaît… dessine-moi un mouton! »"
+ ),
+ u(
+ "Alors vous imaginez ma surprise, au lever du jour, quand "
+ "une drôle de petite voix m’a réveillé. Elle disait: "
+ "« S’il vous plaît… dessine-moi un mouton! »"
+ ),
+ output_encoding="utf-8",
)
def test_unicode_arg(self):
- val = u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""")
+ val = u(
+ "Alors vous imaginez ma surprise, au lever du jour, quand "
+ "une drôle de petite voix m’a réveillé. Elle disait: "
+ "« S’il vous plaît… dessine-moi un mouton! »"
+ )
self._do_memory_test(
"${val}",
- u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""),
- template_args={'val':val}
+ u(
+ "Alors vous imaginez ma surprise, au lever du jour, quand "
+ "une drôle de petite voix m’a réveillé. Elle disait: "
+ "« S’il vous plaît… dessine-moi un mouton! »"
+ ),
+ template_args={"val": val},
)
def test_unicode_file(self):
self._do_file_test(
"unicode.html",
- u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""")
+ u(
+ "Alors vous imaginez ma surprise, au lever du jour, quand "
+ "une drôle de petite voix m’a réveillé. Elle disait: "
+ "« S’il vous plaît… dessine-moi un mouton! »"
+ ),
)
def test_unicode_file_code(self):
self._do_file_test(
- 'unicode_code.html',
+ "unicode_code.html",
u("""hi, drôle de petite voix m’a réveillé."""),
- filters=flatten_result
+ filters=flatten_result,
)
def test_unicode_file_lookup(self):
lookup = TemplateLookup(
- directories=[template_base],
- output_encoding='utf-8',
- default_filters=['decode.utf8'])
+ directories=[template_base],
+ output_encoding="utf-8",
+ default_filters=["decode.utf8"],
+ )
if compat.py3k:
- template = lookup.get_template('/chs_unicode_py3k.html')
+ template = lookup.get_template("/chs_unicode_py3k.html")
else:
- template = lookup.get_template('/chs_unicode.html')
+ template = lookup.get_template("/chs_unicode.html")
eq_(
- flatten_result(template.render_unicode(name='毛泽东')),
- u('毛泽东 是 新中国的主席<br/> Welcome 你 to 北京.')
+ flatten_result(template.render_unicode(name="毛泽东")),
+ u("毛泽东 是 新中国的主席<br/> Welcome 你 to 北京."),
)
def test_unicode_bom(self):
self._do_file_test(
- 'bom.html',
- u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""")
+ "bom.html",
+ u(
+ "Alors vous imaginez ma surprise, au lever du jour, quand "
+ "une drôle de petite voix m’a réveillé. Elle disait: "
+ "« S’il vous plaît… dessine-moi un mouton! »"
+ ),
)
self._do_file_test(
- 'bommagic.html',
- u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""")
+ "bommagic.html",
+ u(
+ "Alors vous imaginez ma surprise, au lever du jour, quand "
+ "une drôle de petite voix m’a réveillé. Elle disait: "
+ "« S’il vous plaît… dessine-moi un mouton! »"
+ ),
)
self.assertRaises(
exceptions.CompileException,
- Template, filename=self._file_path('badbom.html'),
- module_directory=module_base
+ Template,
+ filename=self._file_path("badbom.html"),
+ module_directory=module_base,
)
def test_unicode_memory(self):
- val = u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""")
+ val = u(
+ "Alors vous imaginez ma surprise, au lever du jour, quand "
+ "une drôle de petite voix m’a réveillé. Elle disait: "
+ "« S’il vous plaît… dessine-moi un mouton! »"
+ )
self._do_memory_test(
- ("## -*- coding: utf-8 -*-\n" + val).encode('utf-8'),
- u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""")
+ ("## -*- coding: utf-8 -*-\n" + val).encode("utf-8"),
+ u(
+ "Alors vous imaginez ma surprise, au lever du jour, quand "
+ "une drôle de petite voix m’a réveillé. Elle disait: "
+ "« S’il vous plaît… dessine-moi un mouton! »"
+ ),
)
def test_unicode_text(self):
- val = u("""<%text>Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »</%text>""")
+ val = u(
+ "<%text>Alors vous imaginez ma surprise, au lever du jour, quand "
+ "une drôle de petite voix m’a réveillé. Elle disait: "
+ "« S’il vous plaît… dessine-moi un mouton! »</%text>"
+ )
self._do_memory_test(
- ("## -*- coding: utf-8 -*-\n" + val).encode('utf-8'),
- u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""")
+ ("## -*- coding: utf-8 -*-\n" + val).encode("utf-8"),
+ u(
+ "Alors vous imaginez ma surprise, au lever du jour, quand "
+ "une drôle de petite voix m’a réveillé. Elle disait: "
+ "« S’il vous plaît… dessine-moi un mouton! »"
+ ),
)
def test_unicode_text_ccall(self):
- val = u("""
+ val = u(
+ """
<%def name="foo()">
${capture(caller.body)}
</%def>
<%call expr="foo()">
- <%text>Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »</%text>
- </%call>""")
+ <%text>Alors vous imaginez ma surprise, au lever du jour,
+quand une drôle de petite voix m’a réveillé. Elle disait:
+« S’il vous plaît… dessine-moi un mouton! »</%text>
+ </%call>"""
+ )
self._do_memory_test(
- ("## -*- coding: utf-8 -*-\n" + val).encode('utf-8'),
- u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""),
- filters=flatten_result
+ ("## -*- coding: utf-8 -*-\n" + val).encode("utf-8"),
+ u(
+ "Alors vous imaginez ma surprise, au lever du jour, quand "
+ "une drôle de petite voix m’a réveillé. Elle disait: "
+ "« S’il vous plaît… dessine-moi un mouton! »"
+ ),
+ filters=flatten_result,
)
def test_unicode_literal_in_expr(self):
if compat.py3k:
self._do_memory_test(
- u("""## -*- coding: utf-8 -*-
- ${"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"}
- """).encode('utf-8'),
- u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""),
- filters = lambda s:s.strip()
+ u(
+ "## -*- coding: utf-8 -*-\n"
+ '${"Alors vous imaginez ma surprise, au lever du jour, '
+ "quand une drôle de petite voix m’a réveillé. "
+ "Elle disait: "
+ '« S’il vous plaît… dessine-moi un mouton! »"}\n'
+ ).encode("utf-8"),
+ u(
+ "Alors vous imaginez ma surprise, au lever du jour, "
+ "quand une drôle de petite voix m’a réveillé. "
+ "Elle disait: « S’il vous plaît… dessine-moi un mouton! »"
+ ),
+ filters=lambda s: s.strip(),
)
else:
self._do_memory_test(
- u("""## -*- coding: utf-8 -*-
- ${u"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"}
- """).encode('utf-8'),
- u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""),
- filters = lambda s:s.strip()
+ u(
+ "## -*- coding: utf-8 -*-\n"
+ '${u"Alors vous imaginez ma surprise, au lever du jour, '
+ "quand une drôle de petite voix m’a réveillé. "
+ "Elle disait: « S’il vous plaît… dessine-moi un "
+ 'mouton! »"}'
+ ).encode("utf-8"),
+ u(
+ "Alors vous imaginez ma surprise, au lever du jour, "
+ "quand une drôle de petite voix m’a réveillé. "
+ "Elle disait: « S’il vous plaît… dessine-moi un mouton! »"
+ ),
+ filters=lambda s: s.strip(),
)
def test_unicode_literal_in_expr_file(self):
self._do_file_test(
- 'unicode_expr.html',
- u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""),
- lambda t:t.strip()
+ "unicode_expr.html",
+ u(
+ "Alors vous imaginez ma surprise, au lever du jour, "
+ "quand une drôle de petite voix m’a réveillé. "
+ "Elle disait: « S’il vous plaît… dessine-moi un mouton! »"
+ ),
+ lambda t: t.strip(),
)
def test_unicode_literal_in_code(self):
if compat.py3k:
self._do_memory_test(
- u("""## -*- coding: utf-8 -*-
+ u(
+ """## -*- coding: utf-8 -*-
<%
- context.write("Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »")
+ context.write("Alors vous imaginez ma surprise, au """
+ """lever du jour, quand une drôle de petite voix m’a """
+ """réveillé. Elle disait: """
+ """« S’il vous plaît… dessine-moi un mouton! »")
%>
- """).encode('utf-8'),
- u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""),
- filters=lambda s:s.strip()
+ """
+ ).encode("utf-8"),
+ u(
+ "Alors vous imaginez ma surprise, au lever du jour, "
+ "quand une drôle de petite voix m’a réveillé. "
+ "Elle disait: « S’il vous plaît… dessine-moi un mouton! »"
+ ),
+ filters=lambda s: s.strip(),
)
else:
self._do_memory_test(
- u("""## -*- coding: utf-8 -*-
+ u(
+ """## -*- coding: utf-8 -*-
<%
- context.write(u"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »")
+ context.write(u"Alors vous imaginez ma surprise, """
+ """au lever du jour, quand une drôle de petite voix """
+ """m’a réveillé. Elle disait: « S’il vous plaît… """
+ """dessine-moi un mouton! »")
%>
- """).encode('utf-8'),
- u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""),
- filters=lambda s:s.strip()
+ """
+ ).encode("utf-8"),
+ u(
+ "Alors vous imaginez ma surprise, au lever du jour, "
+ "quand une drôle de petite voix m’a réveillé. "
+ "Elle disait: « S’il vous plaît… dessine-moi un mouton! »"
+ ),
+ filters=lambda s: s.strip(),
)
def test_unicode_literal_in_controlline(self):
if compat.py3k:
self._do_memory_test(
- u("""## -*- coding: utf-8 -*-
+ u(
+ """## -*- coding: utf-8 -*-
<%
x = "drôle de petite voix m’a réveillé."
%>
% if x=="drôle de petite voix m’a réveillé.":
hi, ${x}
% endif
- """).encode('utf-8'),
+ """
+ ).encode("utf-8"),
u("""hi, drôle de petite voix m’a réveillé."""),
- filters=lambda s:s.strip(),
+ filters=lambda s: s.strip(),
)
else:
self._do_memory_test(
- u("""## -*- coding: utf-8 -*-
+ u(
+ """## -*- coding: utf-8 -*-
<%
x = u"drôle de petite voix m’a réveillé."
%>
% if x==u"drôle de petite voix m’a réveillé.":
hi, ${x}
% endif
- """).encode('utf-8'),
+ """
+ ).encode("utf-8"),
u("""hi, drôle de petite voix m’a réveillé."""),
- filters=lambda s:s.strip(),
+ filters=lambda s: s.strip(),
)
def test_unicode_literal_in_tag(self):
self._do_file_test(
"unicode_arguments.html",
[
- u('x is: drôle de petite voix m’a réveillé'),
- u('x is: drôle de petite voix m’a réveillé'),
- u('x is: drôle de petite voix m’a réveillé'),
- u('x is: drôle de petite voix m’a réveillé'),
+ u("x is: drôle de petite voix m’a réveillé"),
+ u("x is: drôle de petite voix m’a réveillé"),
+ u("x is: drôle de petite voix m’a réveillé"),
+ u("x is: drôle de petite voix m’a réveillé"),
],
- filters=result_lines
+ filters=result_lines,
)
self._do_memory_test(
util.read_file(self._file_path("unicode_arguments.html")),
[
- u('x is: drôle de petite voix m’a réveillé'),
- u('x is: drôle de petite voix m’a réveillé'),
- u('x is: drôle de petite voix m’a réveillé'),
- u('x is: drôle de petite voix m’a réveillé'),
+ u("x is: drôle de petite voix m’a réveillé"),
+ u("x is: drôle de petite voix m’a réveillé"),
+ u("x is: drôle de petite voix m’a réveillé"),
+ u("x is: drôle de petite voix m’a réveillé"),
],
- filters=result_lines
+ filters=result_lines,
)
def test_unicode_literal_in_def(self):
if compat.py3k:
self._do_memory_test(
- u("""## -*- coding: utf-8 -*-
+ u(
+ """## -*- coding: utf-8 -*-
<%def name="bello(foo, bar)">
Foo: ${ foo }
Bar: ${ bar }
</%def>
- <%call expr="bello(foo='árvíztűrő tükörfúrógép', bar='ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP')">
- </%call>""").encode('utf-8'),
- u("""Foo: árvíztűrő tükörfúrógép Bar: ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP"""),
- filters=flatten_result
+ <%call expr="bello(foo='árvíztűrő tükörfúrógép', """
+ """bar='ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP')">
+ </%call>"""
+ ).encode("utf-8"),
+ u(
+ """Foo: árvíztűrő tükörfúrógép """
+ """Bar: ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP"""
+ ),
+ filters=flatten_result,
)
self._do_memory_test(
- u("""## -*- coding: utf-8 -*-
- <%def name="hello(foo='árvíztűrő tükörfúrógép', bar='ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP')">
- Foo: ${ foo }
- Bar: ${ bar }
- </%def>
- ${ hello() }""").encode('utf-8'),
- u("""Foo: árvíztűrő tükörfúrógép Bar: ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP"""),
- filters=flatten_result
+ u(
+ "## -*- coding: utf-8 -*-\n"
+ """<%def name="hello(foo='árvíztűrő tükörfúrógép', """
+ """bar='ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP')">\n"""
+ "Foo: ${ foo }\n"
+ "Bar: ${ bar }\n"
+ "</%def>\n"
+ "${ hello() }"
+ ).encode("utf-8"),
+ u(
+ """Foo: árvíztűrő tükörfúrógép Bar: """
+ """ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP"""
+ ),
+ filters=flatten_result,
)
else:
self._do_memory_test(
- u("""## -*- coding: utf-8 -*-
+ u(
+ """## -*- coding: utf-8 -*-
<%def name="bello(foo, bar)">
Foo: ${ foo }
Bar: ${ bar }
</%def>
- <%call expr="bello(foo=u'árvíztűrő tükörfúrógép', bar=u'ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP')">
- </%call>""").encode('utf-8'),
- u("""Foo: árvíztűrő tükörfúrógép Bar: ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP"""),
- filters=flatten_result
+ <%call expr="bello(foo=u'árvíztűrő tükörfúrógép', """
+ """bar=u'ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP')">
+ </%call>"""
+ ).encode("utf-8"),
+ u(
+ """Foo: árvíztűrő tükörfúrógép Bar: """
+ """ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP"""
+ ),
+ filters=flatten_result,
)
self._do_memory_test(
- u("""## -*- coding: utf-8 -*-
- <%def name="hello(foo=u'árvíztűrő tükörfúrógép', bar=u'ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP')">
+ u(
+ """## -*- coding: utf-8 -*-
+ <%def name="hello(foo=u'árvíztűrő tükörfúrógép', """
+ """bar=u'ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP')">
Foo: ${ foo }
Bar: ${ bar }
</%def>
- ${ hello() }""").encode('utf-8'),
- u("""Foo: árvíztűrő tükörfúrógép Bar: ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP"""),
- filters=flatten_result
+ ${ hello() }"""
+ ).encode("utf-8"),
+ u(
+ """Foo: árvíztűrő tükörfúrógép Bar: """
+ """ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP"""
+ ),
+ filters=flatten_result,
)
def test_input_encoding(self):
@@ -296,32 +446,32 @@ class EncodingTest(TemplateTest):
self._do_memory_test(
u("hello ${f('śląsk')}"),
u("hello śląsk"),
- input_encoding='utf-8',
- template_args={'f': lambda x:x}
+ input_encoding="utf-8",
+ template_args={"f": lambda x: x},
)
self._do_memory_test(
u("## -*- coding: utf-8 -*-\nhello ${f('śląsk')}"),
u("hello śląsk"),
- template_args={'f': lambda x:x}
+ template_args={"f": lambda x: x},
)
else:
self._do_memory_test(
u("hello ${f(u'śląsk')}"),
u("hello śląsk"),
- input_encoding='utf-8',
- template_args={'f': lambda x:x}
+ input_encoding="utf-8",
+ template_args={"f": lambda x: x},
)
self._do_memory_test(
u("## -*- coding: utf-8 -*-\nhello ${f(u'śląsk')}"),
u("hello śląsk"),
- template_args={'f': lambda x:x}
+ template_args={"f": lambda x: x},
)
def test_raw_strings(self):
- """test that raw strings go straight thru with default_filters turned off,
- bytestring_passthrough enabled.
+ """test that raw strings go straight thru with default_filters
+ turned off, bytestring_passthrough enabled.
"""
@@ -329,75 +479,101 @@ class EncodingTest(TemplateTest):
u("## -*- coding: utf-8 -*-\nhello ${x}"),
"hello śląsk",
default_filters=[],
- template_args={'x':'śląsk'},
+ template_args={"x": "śląsk"},
unicode_=False,
bytestring_passthrough=True,
- output_encoding=None #'ascii'
+ output_encoding=None, # 'ascii'
)
# now, the way you *should* be doing it....
self._do_memory_test(
u("## -*- coding: utf-8 -*-\nhello ${x}"),
u("hello śląsk"),
- template_args={'x':u('śląsk')}
+ template_args={"x": u("śląsk")},
)
def test_encoding(self):
self._do_memory_test(
- u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""),
- u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""").encode('utf-8'),
- output_encoding='utf-8',
- unicode_=False
+ u(
+ "Alors vous imaginez ma surprise, au lever du jour, quand "
+ "une drôle de petite voix m’a réveillé. Elle disait: "
+ "« S’il vous plaît… dessine-moi un mouton! »"
+ ),
+ u(
+ "Alors vous imaginez ma surprise, au lever du jour, quand "
+ "une drôle de petite voix m’a réveillé. Elle disait: "
+ "« S’il vous plaît… dessine-moi un mouton! »"
+ ).encode("utf-8"),
+ output_encoding="utf-8",
+ unicode_=False,
)
def test_encoding_errors(self):
self._do_memory_test(
- u("""KGB (transliteration of "КГБ") is the Russian-language abbreviation for Committee for State Security, (Russian: Комит́ет Госуд́арственной Безоп́асности (help·info); Komitet Gosudarstvennoy Bezopasnosti)"""),
- u("""KGB (transliteration of "КГБ") is the Russian-language abbreviation for Committee for State Security, (Russian: Комит́ет Госуд́арственной Безоп́асности (help·info); Komitet Gosudarstvennoy Bezopasnosti)""").encode('iso-8859-1', 'replace'),
- output_encoding='iso-8859-1', encoding_errors='replace',
- unicode_=False
+ u(
+ """KGB (transliteration of "КГБ") is the Russian-language """
+ """abbreviation for Committee for State Security, """
+ """(Russian: Комит́ет Госуд́арственной Безоп́асности """
+ """(help·info); Komitet Gosudarstvennoy Bezopasnosti)"""
+ ),
+ u(
+ """KGB (transliteration of "КГБ") is the Russian-language """
+ """abbreviation for Committee for State Security, """
+ """(Russian: Комит́ет Госуд́арственной Безоп́асности """
+ """(help·info); Komitet Gosudarstvennoy Bezopasnosti)"""
+ ).encode("iso-8859-1", "replace"),
+ output_encoding="iso-8859-1",
+ encoding_errors="replace",
+ unicode_=False,
)
def test_read_unicode(self):
- lookup = TemplateLookup(directories=[template_base],
- filesystem_checks=True, output_encoding='utf-8')
+ lookup = TemplateLookup(
+ directories=[template_base],
+ filesystem_checks=True,
+ output_encoding="utf-8",
+ )
if compat.py3k:
- template = lookup.get_template('/read_unicode_py3k.html')
+ template = lookup.get_template("/read_unicode_py3k.html")
else:
- template = lookup.get_template('/read_unicode.html')
+ template = lookup.get_template("/read_unicode.html")
# TODO: I've no idea what encoding this file is, Python 3.1.2
# won't read the file even with open(...encoding='utf-8') unless
# errors is specified. or if there's some quirk in 3.1.2
# since I'm pretty sure this test worked with py3k when I wrote it.
- data = template.render(path=self._file_path('internationalization.html'))
+ template.render(
+ path=self._file_path("internationalization.html")
+ )
@requires_python_2
def test_bytestring_passthru(self):
self._do_file_test(
- 'chs_utf8.html',
- '毛泽东 是 新中国的主席<br/> Welcome 你 to 北京. Welcome 你 to 北京.',
+ "chs_utf8.html",
+ "毛泽东 是 新中国的主席<br/> Welcome 你 to 北京. Welcome 你 to 北京.",
default_filters=[],
disable_unicode=True,
output_encoding=None,
- template_args={'name':'毛泽东'},
+ template_args={"name": "毛泽东"},
filters=flatten_result,
- unicode_=False
+ unicode_=False,
)
self._do_file_test(
- 'chs_utf8.html',
- '毛泽东 是 新中国的主席<br/> Welcome 你 to 北京. Welcome 你 to 北京.',
+ "chs_utf8.html",
+ "毛泽东 是 新中国的主席<br/> Welcome 你 to 北京. Welcome 你 to 北京.",
disable_unicode=True,
output_encoding=None,
- template_args={'name':'毛泽东'},
+ template_args={"name": "毛泽东"},
filters=flatten_result,
- unicode_=False
+ unicode_=False,
)
- template = self._file_template('chs_utf8.html',
- output_encoding=None,
- disable_unicode=True)
- self.assertRaises(UnicodeDecodeError, template.render_unicode, name='毛泽东')
+ template = self._file_template(
+ "chs_utf8.html", output_encoding=None, disable_unicode=True
+ )
+ self.assertRaises(
+ UnicodeDecodeError, template.render_unicode, name="毛泽东"
+ )
template = Template(
"${'Alors vous imaginez ma surprise, au lever"
@@ -405,400 +581,531 @@ class EncodingTest(TemplateTest):
"réveillé. Elle disait: « S’il vous plaît… "
"dessine-moi un mouton! »'}",
output_encoding=None,
- disable_unicode=True, input_encoding='utf-8')
- assert template.render() == "Alors vous imaginez ma surprise, "\
- "au lever du jour, quand une drôle de petite "\
- "voix m’a réveillé. Elle disait: « S’il vous "\
- "plaît… dessine-moi un mouton! »"
+ disable_unicode=True,
+ input_encoding="utf-8",
+ )
+ assert (
+ template.render() == "Alors vous imaginez ma surprise, "
+ "au lever du jour, quand une drôle de petite "
+ "voix m’a réveillé. Elle disait: « S’il vous "
+ "plaît… dessine-moi un mouton! »"
+ )
template = Template(
- "${'Alors vous imaginez ma surprise, au "
- "lever du jour, quand une drôle de petite "
- "voix m’a réveillé. Elle disait: « S’il "
- "vous plaît… dessine-moi un mouton! »'}",
- input_encoding='utf8', output_encoding='utf8',
- disable_unicode=False, default_filters=[])
- # raises because expression contains an encoded bytestring which cannot be decoded
+ "${'Alors vous imaginez ma surprise, au "
+ "lever du jour, quand une drôle de petite "
+ "voix m’a réveillé. Elle disait: « S’il "
+ "vous plaît… dessine-moi un mouton! »'}",
+ input_encoding="utf8",
+ output_encoding="utf8",
+ disable_unicode=False,
+ default_filters=[],
+ )
+ # raises because expression contains an encoded bytestring which cannot
+ # be decoded
self.assertRaises(UnicodeDecodeError, template.render)
class PageArgsTest(TemplateTest):
def test_basic(self):
- template = Template("""
+ template = Template(
+ """
<%page args="x, y, z=7"/>
this is page, ${x}, ${y}, ${z}
-""")
+"""
+ )
- assert flatten_result(template.render(x=5, y=10)) == "this is page, 5, 10, 7"
- assert flatten_result(template.render(x=5, y=10, z=32)) == "this is page, 5, 10, 32"
+ assert (
+ flatten_result(template.render(x=5, y=10))
+ == "this is page, 5, 10, 7"
+ )
+ assert (
+ flatten_result(template.render(x=5, y=10, z=32))
+ == "this is page, 5, 10, 32"
+ )
assert_raises(TypeError, template.render, y=10)
def test_inherits(self):
lookup = TemplateLookup()
- lookup.put_string("base.tmpl",
- """
+ lookup.put_string(
+ "base.tmpl",
+ """
<%page args="bar" />
${bar}
${pageargs['foo']}
${self.body(**pageargs)}
- """
+ """,
)
- lookup.put_string("index.tmpl", """
+ lookup.put_string(
+ "index.tmpl",
+ """
<%inherit file="base.tmpl" />
<%page args="variable" />
${variable}
- """)
+ """,
+ )
self._do_test(
lookup.get_template("index.tmpl"),
"bar foo var",
filters=flatten_result,
- template_args={'variable':'var', 'bar':'bar', 'foo':'foo'}
-
+ template_args={"variable": "var", "bar": "bar", "foo": "foo"},
)
def test_includes(self):
lookup = TemplateLookup()
- lookup.put_string("incl1.tmpl",
- """
+ lookup.put_string(
+ "incl1.tmpl",
+ """
<%page args="bar" />
${bar}
${pageargs['foo']}
- """
+ """,
)
- lookup.put_string("incl2.tmpl",
- """
+ lookup.put_string(
+ "incl2.tmpl",
+ """
${pageargs}
- """
+ """,
)
- lookup.put_string("index.tmpl", """
+ lookup.put_string(
+ "index.tmpl",
+ """
<%include file="incl1.tmpl" args="**pageargs"/>
<%page args="variable" />
${variable}
<%include file="incl2.tmpl" />
- """)
+ """,
+ )
self._do_test(
lookup.get_template("index.tmpl"),
"bar foo var {}",
filters=flatten_result,
- template_args={'variable':'var', 'bar':'bar', 'foo':'foo'}
-
+ template_args={"variable": "var", "bar": "bar", "foo": "foo"},
)
def test_context_small(self):
ctx = runtime.Context([].append, x=5, y=4)
- eq_(sorted(ctx.keys()), ['caller', 'capture', 'x', 'y'])
+ eq_(sorted(ctx.keys()), ["caller", "capture", "x", "y"])
def test_with_context(self):
- template = Template("""
+ template = Template(
+ """
<%page args="x, y, z=7"/>
this is page, ${x}, ${y}, ${z}, ${w}
-""")
- #print template.code
- assert flatten_result(template.render(x=5, y=10, w=17)) == "this is page, 5, 10, 7, 17"
+"""
+ )
+ # print template.code
+ assert (
+ flatten_result(template.render(x=5, y=10, w=17))
+ == "this is page, 5, 10, 7, 17"
+ )
def test_overrides_builtins(self):
- template = Template("""
+ template = Template(
+ """
<%page args="id"/>
this is page, id is ${id}
- """)
+ """
+ )
- assert flatten_result(template.render(id="im the id")) == "this is page, id is im the id"
+ assert (
+ flatten_result(template.render(id="im the id"))
+ == "this is page, id is im the id"
+ )
def test_canuse_builtin_names(self):
- template = Template("""
+ template = Template(
+ """
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_builtin_names_dont_clobber_defaults_in_includes(self):
lookup = TemplateLookup()
- lookup.put_string("test.mako",
- """
+ lookup.put_string(
+ "test.mako",
+ """
<%include file="test1.mako"/>
- """)
+ """,
+ )
- lookup.put_string("test1.mako", """
+ lookup.put_string(
+ "test1.mako",
+ """
<%page args="id='foo'"/>
${id}
- """)
+ """,
+ )
for template in ("test.mako", "test1.mako"):
- assert flatten_result(lookup.get_template(template).render()) == "foo"
- assert flatten_result(lookup.get_template(template).render(id=5)) == "5"
- assert flatten_result(lookup.get_template(template).render(id=id)) == "<built-in function id>"
+ assert (
+ flatten_result(lookup.get_template(template).render()) == "foo"
+ )
+ assert (
+ flatten_result(lookup.get_template(template).render(id=5))
+ == "5"
+ )
+ assert (
+ flatten_result(lookup.get_template(template).render(id=id))
+ == "<built-in function id>"
+ )
def test_dict_locals(self):
- template = Template("""
+ 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"
+ """
+ )
+ assert (
+ flatten_result(template.render())
+ == "dict: this is dict locals: this is locals"
+ )
+
class IncludeTest(TemplateTest):
def test_basic(self):
lookup = TemplateLookup()
- lookup.put_string("a", """
+ lookup.put_string(
+ "a",
+ """
this is a
<%include file="b" args="a=3,b=4,c=5"/>
- """)
- lookup.put_string("b", """
+ """,
+ )
+ lookup.put_string(
+ "b",
+ """
<%page args="a,b,c"/>
this is b. ${a}, ${b}, ${c}
- """)
- assert flatten_result(lookup.get_template("a").render()) == "this is a this is b. 3, 4, 5"
+ """,
+ )
+ assert (
+ flatten_result(lookup.get_template("a").render())
+ == "this is a this is b. 3, 4, 5"
+ )
def test_localargs(self):
lookup = TemplateLookup()
- lookup.put_string("a", """
+ lookup.put_string(
+ "a",
+ """
this is a
<%include file="b" args="a=a,b=b,c=5"/>
- """)
- lookup.put_string("b", """
+ """,
+ )
+ lookup.put_string(
+ "b",
+ """
<%page args="a,b,c"/>
this is b. ${a}, ${b}, ${c}
- """)
- assert flatten_result(lookup.get_template("a").render(a=7,b=8)) == "this is a this is b. 7, 8, 5"
+ """,
+ )
+ assert (
+ flatten_result(lookup.get_template("a").render(a=7, b=8))
+ == "this is a this is b. 7, 8, 5"
+ )
def test_viakwargs(self):
lookup = TemplateLookup()
- lookup.put_string("a", """
+ lookup.put_string(
+ "a",
+ """
this is a
<%include file="b" args="c=5, **context.kwargs"/>
- """)
- lookup.put_string("b", """
+ """,
+ )
+ lookup.put_string(
+ "b",
+ """
<%page args="a,b,c"/>
this is b. ${a}, ${b}, ${c}
- """)
- #print lookup.get_template("a").code
- assert flatten_result(lookup.get_template("a").render(a=7,b=8)) == "this is a this is b. 7, 8, 5"
+ """,
+ )
+ # print lookup.get_template("a").code
+ assert (
+ flatten_result(lookup.get_template("a").render(a=7, b=8))
+ == "this is a this is b. 7, 8, 5"
+ )
def test_include_withargs(self):
lookup = TemplateLookup()
- lookup.put_string("a", """
+ lookup.put_string(
+ "a",
+ """
this is a
<%include file="${i}" args="c=5, **context.kwargs"/>
- """)
- lookup.put_string("b", """
+ """,
+ )
+ lookup.put_string(
+ "b",
+ """
<%page args="a,b,c"/>
this is b. ${a}, ${b}, ${c}
- """)
- assert flatten_result(lookup.get_template("a").render(a=7,b=8,i='b')) == "this is a this is b. 7, 8, 5"
+ """,
+ )
+ assert (
+ flatten_result(lookup.get_template("a").render(a=7, b=8, i="b"))
+ == "this is a this is b. 7, 8, 5"
+ )
def test_within_ccall(self):
lookup = TemplateLookup()
lookup.put_string("a", """this is a""")
- lookup.put_string("b", """
+ lookup.put_string(
+ "b",
+ """
<%def name="bar()">
bar: ${caller.body()}
<%include file="a"/>
</%def>
- """)
- lookup.put_string("c", """
+ """,
+ )
+ lookup.put_string(
+ "c",
+ """
<%namespace name="b" file="b"/>
<%b:bar>
calling bar
</%b:bar>
- """)
- assert flatten_result(lookup.get_template("c").render()) == "bar: calling bar this is a"
+ """,
+ )
+ assert (
+ flatten_result(lookup.get_template("c").render())
+ == "bar: calling bar this is a"
+ )
def test_include_error_handler(self):
def handle(context, error):
- context.write('include error')
+ context.write("include error")
return True
lookup = TemplateLookup(include_error_handler=handle)
- lookup.put_string("a", """
+ lookup.put_string(
+ "a",
+ """
this is a.
<%include file="b"/>
- """)
- lookup.put_string("b", """
+ """,
+ )
+ lookup.put_string(
+ "b",
+ """
this is b ${1/0} end.
- """)
- assert flatten_result(lookup.get_template("a").render()) == "this is a. this is b include error"
+ """,
+ )
+ assert (
+ flatten_result(lookup.get_template("a").render())
+ == "this is a. this is b include error"
+ )
+
class UndefinedVarsTest(TemplateTest):
def test_undefined(self):
- t = Template("""
+ t = Template(
+ """
% if x is UNDEFINED:
undefined
% else:
x: ${x}
% endif
- """)
+ """
+ )
assert result_lines(t.render(x=12)) == ["x: 12"]
assert result_lines(t.render(y=12)) == ["undefined"]
def test_strict(self):
- t = Template("""
+ t = Template(
+ """
% if x is UNDEFINED:
undefined
% else:
x: ${x}
% endif
- """, strict_undefined=True)
+ """,
+ strict_undefined=True,
+ )
- assert result_lines(t.render(x=12)) == ['x: 12']
+ assert result_lines(t.render(x=12)) == ["x: 12"]
- assert_raises(
- NameError,
- t.render, y=12
- )
+ assert_raises(NameError, t.render, y=12)
l = TemplateLookup(strict_undefined=True)
l.put_string("a", "some template")
- l.put_string("b", """
+ l.put_string(
+ "b",
+ """
<%namespace name='a' file='a' import='*'/>
% if x is UNDEFINED:
undefined
% else:
x: ${x}
% endif
- """)
+ """,
+ )
- assert result_lines(t.render(x=12)) == ['x: 12']
+ assert result_lines(t.render(x=12)) == ["x: 12"]
- assert_raises(
- NameError,
- t.render, y=12
- )
+ assert_raises(NameError, t.render, y=12)
def test_expression_declared(self):
- t = Template("""
+ t = Template(
+ """
${",".join([t for t in ("a", "b", "c")])}
- """, strict_undefined=True)
+ """,
+ strict_undefined=True,
+ )
- eq_(result_lines(t.render()), ['a,b,c'])
+ eq_(result_lines(t.render()), ["a,b,c"])
- t = Template("""
+ t = Template(
+ """
<%self:foo value="${[(val, n) for val, n in [(1, 2)]]}"/>
<%def name="foo(value)">
${value}
</%def>
- """, strict_undefined=True)
+ """,
+ strict_undefined=True,
+ )
- eq_(result_lines(t.render()), ['[(1, 2)]'])
+ eq_(result_lines(t.render()), ["[(1, 2)]"])
- t = Template("""
+ t = Template(
+ """
<%call expr="foo(value=[(val, n) for val, n in [(1, 2)]])" />
<%def name="foo(value)">
${value}
</%def>
- """, strict_undefined=True)
+ """,
+ strict_undefined=True,
+ )
- eq_(result_lines(t.render()), ['[(1, 2)]'])
+ eq_(result_lines(t.render()), ["[(1, 2)]"])
l = TemplateLookup(strict_undefined=True)
l.put_string("i", "hi, ${pageargs['y']}")
- l.put_string("t", """
+ l.put_string(
+ "t",
+ """
<%include file="i" args="y=[x for x in range(3)]" />
- """)
- eq_(
- result_lines(l.get_template("t").render()), ['hi, [0, 1, 2]']
+ """,
)
+ eq_(result_lines(l.get_template("t").render()), ["hi, [0, 1, 2]"])
- l.put_string('q', """
- <%namespace name="i" file="${(str([x for x in range(3)][2]) + 'i')[-1]}" />
+ l.put_string(
+ "q",
+ """
+ <%namespace name="i" file="${(str([x for x in range(3)][2]) + """
+ """'i')[-1]}" />
${i.body(y='x')}
- """)
- eq_(
- result_lines(l.get_template("q").render()), ['hi, x']
+ """,
)
+ eq_(result_lines(l.get_template("q").render()), ["hi, x"])
- t = Template("""
+ t = Template(
+ """
<%
y = lambda q: str(q)
%>
${y('hi')}
- """, strict_undefined=True)
- eq_(
- result_lines(t.render()), ["hi"]
+ """,
+ strict_undefined=True,
)
+ eq_(result_lines(t.render()), ["hi"])
def test_list_comprehensions_plus_undeclared_nonstrict(self):
# traditional behavior. variable inside a list comprehension
# is treated as an "undefined", so is pulled from the context.
- t = Template("""
+ t = Template(
+ """
t is: ${t}
${",".join([t for t in ("a", "b", "c")])}
- """)
-
- eq_(
- result_lines(t.render(t="T")),
- ['t is: T', 'a,b,c']
+ """
)
+ eq_(result_lines(t.render(t="T")), ["t is: T", "a,b,c"])
+
def test_traditional_assignment_plus_undeclared(self):
- t = Template("""
+ t = Template(
+ """
t is: ${t}
<%
t = 12
%>
- """)
- assert_raises(
- UnboundLocalError,
- t.render, t="T"
+ """
)
+ assert_raises(UnboundLocalError, t.render, t="T")
def test_list_comprehensions_plus_undeclared_strict(self):
# with strict, a list comprehension now behaves
# like the undeclared case above.
- t = Template("""
+ t = Template(
+ """
t is: ${t}
${",".join([t for t in ("a", "b", "c")])}
- """, strict_undefined=True)
-
- eq_(
- result_lines(t.render(t="T")),
- ['t is: T', 'a,b,c']
+ """,
+ strict_undefined=True,
)
+ eq_(result_lines(t.render(t="T")), ["t is: T", "a,b,c"])
+
+
class StopRenderingTest(TemplateTest):
def test_return_in_template(self):
- t = Template("""
+ t = Template(
+ """
Line one
<% return STOP_RENDERING %>
Line Three
- """, strict_undefined=True)
-
- eq_(
- result_lines(t.render()),
- ['Line one']
+ """,
+ strict_undefined=True,
)
+ eq_(result_lines(t.render()), ["Line one"])
+
+
class ReservedNameTest(TemplateTest):
def test_names_on_context(self):
- for name in ('context', 'loop', 'UNDEFINED', 'STOP_RENDERING'):
+ for name in ("context", "loop", "UNDEFINED", "STOP_RENDERING"):
assert_raises_message(
exceptions.NameConflictError,
r"Reserved words passed to render\(\): %s" % name,
- Template("x").render, **{name:'foo'}
+ Template("x").render,
+ **{name: "foo"}
)
def test_names_in_template(self):
- for name in ('context', 'loop', 'UNDEFINED', 'STOP_RENDERING'):
+ for name in ("context", "loop", "UNDEFINED", "STOP_RENDERING"):
assert_raises_message(
exceptions.NameConflictError,
r"Reserved words declared in template: %s" % name,
- Template, "<%% %s = 5 %%>" % name
+ Template,
+ "<%% %s = 5 %%>" % name,
)
def test_exclude_loop_context(self):
@@ -806,19 +1113,19 @@ class ReservedNameTest(TemplateTest):
"loop is ${loop}",
"loop is 5",
template_args=dict(loop=5),
- enable_loop=False
+ enable_loop=False,
)
def test_exclude_loop_template(self):
self._do_memory_test(
- "<% loop = 12 %>loop is ${loop}",
- "loop is 12",
- enable_loop=False
+ "<% loop = 12 %>loop is ${loop}", "loop is 12", enable_loop=False
)
+
class ControlTest(TemplateTest):
def test_control(self):
- t = Template("""
+ t = Template(
+ """
## this is a template.
% for x in y:
% if 'test' in x:
@@ -827,12 +1134,17 @@ class ControlTest(TemplateTest):
no x does not have test
%endif
%endfor
-""")
- assert result_lines(t.render(y=[{'test':'one'}, {'foo':'bar'}, {'foo':'bar', 'test':'two'}])) == [
- "yes x has test",
- "no x does not have test",
- "yes x has test"
- ]
+"""
+ )
+ assert result_lines(
+ t.render(
+ y=[
+ {"test": "one"},
+ {"foo": "bar"},
+ {"foo": "bar", "test": "two"},
+ ]
+ )
+ ) == ["yes x has test", "no x does not have test", "yes x has test"]
def test_blank_control_1(self):
self._do_memory_test(
@@ -841,7 +1153,7 @@ class ControlTest(TemplateTest):
% endif
""",
"",
- filters=lambda s:s.strip()
+ filters=lambda s: s.strip(),
)
def test_blank_control_2(self):
@@ -852,7 +1164,7 @@ class ControlTest(TemplateTest):
% endif
""",
"",
- filters=lambda s:s.strip()
+ filters=lambda s: s.strip(),
)
def test_blank_control_3(self):
@@ -863,7 +1175,7 @@ class ControlTest(TemplateTest):
% endif
""",
"",
- filters=lambda s:s.strip()
+ filters=lambda s: s.strip(),
)
def test_blank_control_4(self):
@@ -875,7 +1187,7 @@ class ControlTest(TemplateTest):
% endif
""",
"",
- filters=lambda s:s.strip()
+ filters=lambda s: s.strip(),
)
def test_blank_control_5(self):
@@ -885,7 +1197,7 @@ class ControlTest(TemplateTest):
% endfor
""",
"",
- filters=lambda s:s.strip()
+ filters=lambda s: s.strip(),
)
def test_blank_control_6(self):
@@ -895,7 +1207,7 @@ class ControlTest(TemplateTest):
% endwhile
""",
"",
- filters=lambda s:s.strip()
+ filters=lambda s: s.strip(),
)
def test_blank_control_7(self):
@@ -906,7 +1218,7 @@ class ControlTest(TemplateTest):
% endtry
""",
"",
- filters=lambda s:s.strip()
+ filters=lambda s: s.strip(),
)
def test_blank_control_8(self):
@@ -917,7 +1229,7 @@ class ControlTest(TemplateTest):
""",
"",
filters=lambda s: s.strip(),
- template_args={"ctx": ctx}
+ template_args={"ctx": ctx},
)
def test_commented_blank_control_1(self):
@@ -928,7 +1240,7 @@ class ControlTest(TemplateTest):
% endif
""",
"",
- filters=lambda s:s.strip()
+ filters=lambda s: s.strip(),
)
def test_commented_blank_control_2(self):
@@ -941,7 +1253,7 @@ class ControlTest(TemplateTest):
% endif
""",
"",
- filters=lambda s:s.strip()
+ filters=lambda s: s.strip(),
)
def test_commented_blank_control_3(self):
@@ -954,7 +1266,7 @@ class ControlTest(TemplateTest):
% endif
""",
"",
- filters=lambda s:s.strip()
+ filters=lambda s: s.strip(),
)
def test_commented_blank_control_4(self):
@@ -969,7 +1281,7 @@ class ControlTest(TemplateTest):
% endif
""",
"",
- filters=lambda s:s.strip()
+ filters=lambda s: s.strip(),
)
def test_commented_blank_control_5(self):
@@ -980,7 +1292,7 @@ class ControlTest(TemplateTest):
% endfor
""",
"",
- filters=lambda s:s.strip()
+ filters=lambda s: s.strip(),
)
def test_commented_blank_control_6(self):
@@ -991,7 +1303,7 @@ class ControlTest(TemplateTest):
% endwhile
""",
"",
- filters=lambda s:s.strip()
+ filters=lambda s: s.strip(),
)
def test_commented_blank_control_7(self):
@@ -1004,7 +1316,7 @@ class ControlTest(TemplateTest):
% endtry
""",
"",
- filters=lambda s:s.strip()
+ filters=lambda s: s.strip(),
)
def test_commented_blank_control_8(self):
@@ -1016,19 +1328,22 @@ class ControlTest(TemplateTest):
""",
"",
filters=lambda s: s.strip(),
- template_args={"ctx": ctx}
+ template_args={"ctx": ctx},
)
def test_multiline_control(self):
- t = Template("""
+ t = Template(
+ """
% for x in \\
[y for y in [1,2,3]]:
${x}
% endfor
-""")
- #print t.code
+"""
+ )
+ # print t.code
assert flatten_result(t.render()) == "1 2 3"
+
class GlobalsTest(TemplateTest):
def test_globals(self):
self._do_memory_test(
@@ -1039,33 +1354,39 @@ class GlobalsTest(TemplateTest):
y is ${y}
""",
"y is hi",
- filters=lambda t:t.strip()
+ filters=lambda t: t.strip(),
)
-class RichTracebackTest(TemplateTest):
+class RichTracebackTest(TemplateTest):
def _do_test_traceback(self, utf8, memory, syntax):
if memory:
if syntax:
- source = u('## coding: utf-8\n<% print "m’a réveillé. '\
- 'Elle disait: « S’il vous plaît… dessine-moi un mouton! » %>')
+ source = u(
+ '## coding: utf-8\n<% print "m’a réveillé. '
+ "Elle disait: « S’il vous plaît… dessine-moi "
+ "un mouton! » %>"
+ )
else:
- source = u('## coding: utf-8\n<% print u"m’a réveillé. '\
- 'Elle disait: « S’il vous plaît… dessine-moi un mouton! »" + str(5/0) %>')
+ source = u(
+ '## coding: utf-8\n<% print u"m’a réveillé. '
+ "Elle disait: « S’il vous plaît… dessine-moi un "
+ 'mouton! »" + str(5/0) %>'
+ )
if utf8:
- source = source.encode('utf-8')
+ source = source.encode("utf-8")
else:
source = source
- templateargs = {'text': source}
+ templateargs = {"text": source}
else:
if syntax:
- filename = 'unicode_syntax_error.html'
+ filename = "unicode_syntax_error.html"
else:
- filename = 'unicode_runtime_error.html'
- source = util.read_file(self._file_path(filename), 'rb')
+ filename = "unicode_runtime_error.html"
+ source = util.read_file(self._file_path(filename), "rb")
if not utf8:
- source = source.decode('utf-8')
- templateargs = {'filename': self._file_path(filename)}
+ source = source.decode("utf-8")
+ templateargs = {"filename": self._file_path(filename)}
try:
template = Template(**templateargs)
if not syntax:
@@ -1074,101 +1395,119 @@ class RichTracebackTest(TemplateTest):
except Exception:
tback = exceptions.RichTraceback()
if utf8:
- assert tback.source == source.decode('utf-8')
+ assert tback.source == source.decode("utf-8")
else:
assert tback.source == source
+
for utf8 in (True, False):
for memory in (True, False):
for syntax in (True, False):
+
def _do_test(self):
self._do_test_traceback(utf8, memory, syntax)
- name = 'test_%s_%s_%s' % (utf8 and 'utf8' or 'unicode',
- memory and 'memory' or 'file',
- syntax and 'syntax' or 'runtime')
+
+ name = "test_%s_%s_%s" % (
+ utf8 and "utf8" or "unicode",
+ memory and "memory" or "file",
+ syntax and "syntax" or "runtime",
+ )
_do_test.__name__ = name
setattr(RichTracebackTest, name, _do_test)
del _do_test
+
class ModuleDirTest(TemplateTest):
def tearDown(self):
import shutil
+
shutil.rmtree(module_base, True)
def test_basic(self):
t = self._file_template("modtest.html")
- t2 = self._file_template('subdir/modtest.html')
+ t2 = self._file_template("subdir/modtest.html")
- eq_(
- t.module.__file__,
- os.path.join(module_base, 'modtest.html.py')
- )
+ eq_(t.module.__file__, os.path.join(module_base, "modtest.html.py"))
eq_(
t2.module.__file__,
- os.path.join(module_base, 'subdir', 'modtest.html.py')
+ os.path.join(module_base, "subdir", "modtest.html.py"),
)
def test_callable(self):
def get_modname(filename, uri):
return os.path.join(
- module_base,
- os.path.dirname(uri)[1:],
- 'foo',
- os.path.basename(filename) + ".py")
+ module_base,
+ os.path.dirname(uri)[1:],
+ "foo",
+ os.path.basename(filename) + ".py",
+ )
lookup = TemplateLookup(template_base, modulename_callable=get_modname)
- t = lookup.get_template('/modtest.html')
- t2 = lookup.get_template('/subdir/modtest.html')
+ t = lookup.get_template("/modtest.html")
+ t2 = lookup.get_template("/subdir/modtest.html")
eq_(
t.module.__file__,
- os.path.join(module_base, 'foo', 'modtest.html.py')
+ os.path.join(module_base, "foo", "modtest.html.py"),
)
eq_(
t2.module.__file__,
- os.path.join(module_base, 'subdir', 'foo', 'modtest.html.py')
+ os.path.join(module_base, "subdir", "foo", "modtest.html.py"),
)
def test_custom_writer(self):
canary = []
+
def write_module(source, outputpath):
- f = open(outputpath, 'wb')
+ f = open(outputpath, "wb")
canary.append(outputpath)
f.write(source)
f.close()
- lookup = TemplateLookup(template_base, module_writer=write_module,
- module_directory=module_base)
- t = lookup.get_template('/modtest.html')
- t2 = lookup.get_template('/subdir/modtest.html')
+
+ lookup = TemplateLookup(
+ template_base,
+ module_writer=write_module,
+ module_directory=module_base,
+ )
+ lookup.get_template("/modtest.html")
+ lookup.get_template("/subdir/modtest.html")
eq_(
canary,
- [os.path.join(module_base, "modtest.html.py"),
- os.path.join(module_base, "subdir", "modtest.html.py")]
+ [
+ os.path.join(module_base, "modtest.html.py"),
+ os.path.join(module_base, "subdir", "modtest.html.py"),
+ ],
)
+
class FilenameToURITest(TemplateTest):
def test_windows_paths(self):
- """test that windows filenames are handled appropriately by Template."""
+ """test that windows filenames are handled appropriately by
+ Template."""
current_path = os.path
import ntpath
+
os.path = ntpath
try:
+
class NoCompileTemplate(Template):
def _compile_from_file(self, path, filename):
self.path = path
return Template("foo bar").module
t1 = NoCompileTemplate(
- filename="c:\\foo\\template.html",
- module_directory="c:\\modules\\")
+ filename="c:\\foo\\template.html",
+ module_directory="c:\\modules\\",
+ )
eq_(t1.uri, "/foo/template.html")
eq_(t1.path, "c:\\modules\\foo\\template.html.py")
t1 = NoCompileTemplate(
- filename="c:\\path\\to\\templates\\template.html",
- uri = "/bar/template.html",
- module_directory="c:\\modules\\")
+ filename="c:\\path\\to\\templates\\template.html",
+ uri="/bar/template.html",
+ module_directory="c:\\modules\\",
+ )
eq_(t1.uri, "/bar/template.html")
eq_(t1.path, "c:\\modules\\bar\\template.html.py")
@@ -1181,24 +1520,31 @@ class FilenameToURITest(TemplateTest):
current_path = os.path
import posixpath
+
os.path = posixpath
try:
+
class NoCompileTemplate(Template):
def _compile_from_file(self, path, filename):
self.path = path
return Template("foo bar").module
t1 = NoCompileTemplate(
- filename="/var/www/htdocs/includes/template.html",
- module_directory="/var/lib/modules")
+ filename="/var/www/htdocs/includes/template.html",
+ module_directory="/var/lib/modules",
+ )
eq_(t1.uri, "/var/www/htdocs/includes/template.html")
- eq_(t1.path, "/var/lib/modules/var/www/htdocs/includes/template.html.py")
+ eq_(
+ t1.path,
+ "/var/lib/modules/var/www/htdocs/includes/template.html.py",
+ )
t1 = NoCompileTemplate(
- filename="/var/www/htdocs/includes/template.html",
- uri = "/bar/template.html",
- module_directory="/var/lib/modules")
+ filename="/var/www/htdocs/includes/template.html",
+ uri="/bar/template.html",
+ module_directory="/var/lib/modules",
+ )
eq_(t1.uri, "/bar/template.html")
eq_(t1.path, "/var/lib/modules/bar/template.html.py")
@@ -1209,16 +1555,20 @@ class FilenameToURITest(TemplateTest):
def test_dont_accept_relative_outside_of_root(self):
assert_raises_message(
exceptions.TemplateLookupException,
- "Template uri \"../../foo.html\" is invalid - it "
+ 'Template uri "../../foo.html" is invalid - it '
"cannot be relative outside of the root path",
- Template, "test", uri="../../foo.html",
+ Template,
+ "test",
+ uri="../../foo.html",
)
assert_raises_message(
exceptions.TemplateLookupException,
- "Template uri \"/../../foo.html\" is invalid - it "
+ 'Template uri "/../../foo.html" is invalid - it '
"cannot be relative outside of the root path",
- Template, "test", uri="/../../foo.html",
+ Template,
+ "test",
+ uri="/../../foo.html",
)
# normalizes in the root is OK
@@ -1230,24 +1580,35 @@ class ModuleTemplateTest(TemplateTest):
def test_module_roundtrip(self):
lookup = TemplateLookup()
- template = Template("""
+ template = Template(
+ """
<%inherit file="base.html"/>
% for x in range(5):
${x}
% endfor
-""", lookup=lookup)
+""",
+ lookup=lookup,
+ )
- base = Template("""
+ base = Template(
+ """
This is base.
${self.body()}
-""", lookup=lookup)
+""",
+ lookup=lookup,
+ )
lookup.put_template("base.html", base)
lookup.put_template("template.html", template)
assert result_lines(template.render()) == [
- "This is base.", "0", "1", "2", "3", "4"
+ "This is base.",
+ "0",
+ "1",
+ "2",
+ "3",
+ "4",
]
lookup = TemplateLookup()
@@ -1258,12 +1619,19 @@ class ModuleTemplateTest(TemplateTest):
lookup.put_template("template.html", template)
assert result_lines(template.render()) == [
- "This is base.", "0", "1", "2", "3", "4"
+ "This is base.",
+ "0",
+ "1",
+ "2",
+ "3",
+ "4",
]
+
class TestTemplateAPI(unittest.TestCase):
def test_metadata(self):
- t = Template("""
+ t = Template(
+ """
Text
Text
% if bar:
@@ -1272,24 +1640,69 @@ Text
<%include file='bar'/>
-""", uri="/some/template")
+""",
+ uri="/some/template",
+ )
eq_(
ModuleInfo.get_module_source_metadata(t.code, full_line_map=True),
{
- 'full_line_map': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 4, 5, 5, 5, 7,
- 8, 8, 8, 8, 8, 8, 8],
- 'source_encoding': 'ascii',
- 'filename': None,
- 'line_map': {35: 29, 15: 0, 22: 1, 23: 4, 24: 5, 25: 5,
- 26: 5, 27: 7, 28: 8, 29: 8},
- 'uri': '/some/template'
- }
-
+ "full_line_map": [
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 4,
+ 5,
+ 5,
+ 5,
+ 7,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ ],
+ "source_encoding": "ascii",
+ "filename": None,
+ "line_map": {
+ 35: 29,
+ 15: 0,
+ 22: 1,
+ 23: 4,
+ 24: 5,
+ 25: 5,
+ 26: 5,
+ 27: 7,
+ 28: 8,
+ 29: 8,
+ },
+ "uri": "/some/template",
+ },
)
def test_metadata_two(self):
- t = Template("""
+ t = Template(
+ """
Text
Text
% if bar:
@@ -1301,26 +1714,89 @@ Text
</%block>
-""", uri="/some/template")
+""",
+ uri="/some/template",
+ )
eq_(
ModuleInfo.get_module_source_metadata(t.code, full_line_map=True),
{
- 'full_line_map': [
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 5, 5, 5, 7, 7,
- 7, 7, 7, 10, 10, 10, 10, 10, 10, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8],
- 'source_encoding': 'ascii',
- 'filename': None,
- 'line_map': {34: 10, 40: 8, 46: 8, 15: 0, 52: 46,
- 24: 1, 25: 4, 26: 5, 27: 5, 28: 5, 29: 7},
- 'uri': '/some/template'}
+ "full_line_map": [
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 4,
+ 5,
+ 5,
+ 5,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ ],
+ "source_encoding": "ascii",
+ "filename": None,
+ "line_map": {
+ 34: 10,
+ 40: 8,
+ 46: 8,
+ 15: 0,
+ 52: 46,
+ 24: 1,
+ 25: 4,
+ 26: 5,
+ 27: 5,
+ 28: 5,
+ 29: 7,
+ },
+ "uri": "/some/template",
+ },
)
class PreprocessTest(TemplateTest):
def test_old_comments(self):
- t = Template("""
+ t = Template(
+ """
im a template
# old style comment
# more old style comment
@@ -1328,32 +1804,43 @@ class PreprocessTest(TemplateTest):
## new style comment
- # not a comment
- ## not a comment
-""", preprocessor=convert_comments)
+""",
+ preprocessor=convert_comments,
+ )
+
+ assert (
+ flatten_result(t.render())
+ == "im a template - # not a comment - ## not a comment"
+ )
- assert flatten_result(t.render()) == "im a template - # not a comment - ## not a comment"
class LexerTest(TemplateTest):
def _fixture(self):
from mako.parsetree import TemplateNode, Text
+
class MyLexer(object):
- encoding = 'ascii'
+ encoding = "ascii"
+
def __init__(self, *arg, **kw):
pass
def parse(self):
t = TemplateNode("foo")
t.nodes.append(
- Text("hello world", source="foo", lineno=0,
- pos=0, filename=None)
+ Text(
+ "hello world",
+ source="foo",
+ lineno=0,
+ pos=0,
+ filename=None,
+ )
)
return t
+
return MyLexer
def _test_custom_lexer(self, template):
- eq_(
- result_lines(template.render()),
- ["hello world"]
- )
+ eq_(result_lines(template.render()), ["hello world"])
def test_via_template(self):
t = Template("foo", lexer_cls=self._fixture())
@@ -1365,8 +1852,8 @@ class LexerTest(TemplateTest):
t = tl.get_template("foo")
self._test_custom_lexer(t)
-class FuturesTest(TemplateTest):
+class FuturesTest(TemplateTest):
def test_future_import(self):
t = Template("${ x / y }", future_imports=["division"])
assert result_lines(t.render(x=12, y=5)) == ["2.4"]
diff --git a/test/test_tgplugin.py b/test/test_tgplugin.py
index 3f548c4..df95d00 100644
--- a/test/test_tgplugin.py
+++ b/test/test_tgplugin.py
@@ -1,49 +1,52 @@
+from mako import compat
from mako.ext.turbogears import TGPlugin
+from test import template_base
+from test import TemplateTest
from test.util import result_lines
-from test import TemplateTest, template_base
-from mako import compat
-tl = TGPlugin(options=dict(directories=[template_base]), extension='html')
+tl = TGPlugin(options=dict(directories=[template_base]), extension="html")
+
class TestTGPlugin(TemplateTest):
def test_basic(self):
- t = tl.load_template('/index.html')
- assert result_lines(t.render()) == [
- "this is index"
- ]
+ t = tl.load_template("/index.html")
+ assert result_lines(t.render()) == ["this is index"]
+
def test_subdir(self):
- t = tl.load_template('/subdir/index.html')
+ t = tl.load_template("/subdir/index.html")
assert result_lines(t.render()) == [
"this is sub index",
- "this is include 2"
-
+ "this is include 2",
]
- assert tl.load_template('/subdir/index.html').module_id == '_subdir_index_html'
+ assert (
+ tl.load_template("/subdir/index.html").module_id
+ == "_subdir_index_html"
+ )
def test_basic_dot(self):
- t = tl.load_template('index')
- assert result_lines(t.render()) == [
- "this is index"
- ]
+ t = tl.load_template("index")
+ assert result_lines(t.render()) == ["this is index"]
+
def test_subdir_dot(self):
- t = tl.load_template('subdir.index')
+ t = tl.load_template("subdir.index")
assert result_lines(t.render()) == [
"this is sub index",
- "this is include 2"
-
+ "this is include 2",
]
- assert tl.load_template('subdir.index').module_id == '_subdir_index_html'
+ assert (
+ tl.load_template("subdir.index").module_id == "_subdir_index_html"
+ )
def test_string(self):
- t = tl.load_template('foo', "hello world")
+ t = tl.load_template("foo", "hello world")
assert t.render() == "hello world"
def test_render(self):
- assert result_lines(tl.render({}, template='/index.html')) == [
- "this is index"
- ]
- assert result_lines(tl.render({}, template=compat.u('/index.html'))) == [
+ assert result_lines(tl.render({}, template="/index.html")) == [
"this is index"
]
+ assert result_lines(
+ tl.render({}, template=compat.u("/index.html"))
+ ) == ["this is index"]
diff --git a/test/test_util.py b/test/test_util.py
index c8034a1..f3f3edb 100644
--- a/test/test_util.py
+++ b/test/test_util.py
@@ -2,9 +2,15 @@
import os
import unittest
-from mako import util, exceptions, compat
-from test import eq_, skip_if, assert_raises_message
+
+from mako import compat
+from mako import exceptions
+from mako import util
from mako.compat import u
+from test import assert_raises_message
+from test import eq_
+from test import skip_if
+
class UtilTest(unittest.TestCase):
def test_fast_buffer_write(self):
@@ -24,22 +30,22 @@ class UtilTest(unittest.TestCase):
def test_fast_buffer_encoded(self):
s = u("drôl m’a rée « S’il")
- buf = util.FastEncodingBuffer(encoding='utf-8')
+ buf = util.FastEncodingBuffer(encoding="utf-8")
buf.write(s[0:10])
buf.write(s[10:])
- q = buf.getvalue()
- eq_(buf.getvalue(), s.encode('utf-8'))
+ eq_(buf.getvalue(), s.encode("utf-8"))
def test_read_file(self):
- fn = os.path.join(os.path.dirname(__file__), 'test_util.py')
- data = util.read_file(fn, 'rb')
- assert 'test_util' in str(data) # str() for py3k
+ fn = os.path.join(os.path.dirname(__file__), "test_util.py")
+ data = util.read_file(fn, "rb")
+ assert "test_util" in str(data) # str() for py3k
@skip_if(lambda: compat.pypy, "Pypy does this differently")
def test_load_module(self):
- fn = os.path.join(os.path.dirname(__file__), 'test_util.py')
- module = compat.load_module('mako.template', fn)
+ fn = os.path.join(os.path.dirname(__file__), "test_util.py")
+ module = compat.load_module("mako.template", fn)
import mako.template
+
self.assertEqual(module, mako.template)
def test_load_plugin_failure(self):
@@ -47,5 +53,6 @@ class UtilTest(unittest.TestCase):
assert_raises_message(
exceptions.RuntimeException,
"Can't load plugin fakegroup fake",
- loader.load, "fake"
+ loader.load,
+ "fake",
)
diff --git a/test/util.py b/test/util.py
index 605269f..29225e2 100644
--- a/test/util.py
+++ b/test/util.py
@@ -1,7 +1,13 @@
import re
+
def flatten_result(result):
- return re.sub(r'[\s\r\n]+', ' ', result).strip()
+ return re.sub(r"[\s\r\n]+", " ", result).strip()
+
def result_lines(result):
- return [x.strip() for x in re.split(r'\r?\n', re.sub(r' +', ' ', result)) if x.strip() != ''] \ No newline at end of file
+ return [
+ x.strip()
+ for x in re.split(r"\r?\n", re.sub(r" +", " ", result))
+ if x.strip() != ""
+ ]
diff --git a/tox.ini b/tox.ini
index 45d7f00..9be38dd 100644
--- a/tox.ini
+++ b/tox.ini
@@ -22,9 +22,15 @@ setenv=
commands=py.test {env:COVERAGE:} {posargs}
-[flake8]
-
-show-source = True
-ignore = E711,E712,E721,D,N
-# F841,F811,F401
-exclude=.venv,.git,.tox,dist,doc,*egg,build
+# thanks to https://julien.danjou.info/the-best-flake8-extensions/
+[testenv:pep8]
+basepython = python3.7
+deps=
+ flake8
+ flake8-import-order
+ flake8-builtins
+ flake8-docstrings
+ flake8-rst-docstrings
+ # used by flake8-rst-docstrings
+ pygments
+commands = flake8 ./mako/ ./test/ setup.py --exclude test/templates,test/foo