aboutsummaryrefslogtreecommitdiffstats
path: root/mako/codegen.py
diff options
context:
space:
mode:
Diffstat (limited to 'mako/codegen.py')
-rw-r--r--mako/codegen.py700
1 files changed, 381 insertions, 319 deletions
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():