1c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley# mako/template.py 2c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley# Copyright (C) 2006-2015 the Mako authors and contributors <see AUTHORS file> 3c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley# 4c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley# This module is part of Mako and is released under 5c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley# the MIT License: http://www.opensource.org/licenses/mit-license.php 6c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 7c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley"""Provides the Template class, a facade for parsing, generating and executing 8c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowleytemplate strings, as well as template runtime operations.""" 9c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 10c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowleyfrom mako.lexer import Lexer 11c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowleyfrom mako import runtime, util, exceptions, codegen, cache, compat 12c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowleyimport os 13c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowleyimport re 14c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowleyimport shutil 15c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowleyimport stat 16c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowleyimport sys 17c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowleyimport tempfile 18c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowleyimport types 19c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowleyimport weakref 20c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 21c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 22c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowleyclass Template(object): 23c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley """Represents a compiled template. 24c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 25c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :class:`.Template` includes a reference to the original 26c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley template source (via the :attr:`.source` attribute) 27c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley as well as the source code of the 28c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley generated Python module (i.e. the :attr:`.code` attribute), 29c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley as well as a reference to an actual Python module. 30c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 31c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :class:`.Template` is constructed using either a literal string 32c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley representing the template text, or a filename representing a filesystem 33c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley path to a source file. 34c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 35c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param text: textual template source. This argument is mutually 36c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley exclusive versus the ``filename`` parameter. 37c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 38c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param filename: filename of the source template. This argument is 39c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley mutually exclusive versus the ``text`` parameter. 40c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 41c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param buffer_filters: string list of filters to be applied 42c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley to the output of ``%def``\ s which are buffered, cached, or otherwise 43c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley filtered, after all filters 44c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley defined with the ``%def`` itself have been applied. Allows the 45c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley creation of default expression filters that let the output 46c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley of return-valued ``%def``\ s "opt out" of that filtering via 47c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley passing special attributes or objects. 48c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 49c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param bytestring_passthrough: When ``True``, and ``output_encoding`` is 50c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley set to ``None``, and :meth:`.Template.render` is used to render, 51c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley the `StringIO` or `cStringIO` buffer will be used instead of the 52c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley default "fast" buffer. This allows raw bytestrings in the 53c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley output stream, such as in expressions, to pass straight 54c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley through to the buffer. This flag is forced 55c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley to ``True`` if ``disable_unicode`` is also configured. 56c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 57c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley .. versionadded:: 0.4 58c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley Added to provide the same behavior as that of the previous series. 59c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 60c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param cache_args: Dictionary of cache configuration arguments that 61c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley will be passed to the :class:`.CacheImpl`. See :ref:`caching_toplevel`. 62c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 63c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param cache_dir: 64c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 65c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley .. deprecated:: 0.6 66c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley Use the ``'dir'`` argument in the ``cache_args`` dictionary. 67c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley See :ref:`caching_toplevel`. 68c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 69c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param cache_enabled: Boolean flag which enables caching of this 70c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley template. See :ref:`caching_toplevel`. 71c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 72c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param cache_impl: String name of a :class:`.CacheImpl` caching 73c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley implementation to use. Defaults to ``'beaker'``. 74c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 75c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param cache_type: 76c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 77c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley .. deprecated:: 0.6 78c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley Use the ``'type'`` argument in the ``cache_args`` dictionary. 79c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley See :ref:`caching_toplevel`. 80c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 81c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param cache_url: 82c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 83c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley .. deprecated:: 0.6 84c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley Use the ``'url'`` argument in the ``cache_args`` dictionary. 85c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley See :ref:`caching_toplevel`. 86c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 87c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param default_filters: List of string filter names that will 88c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley be applied to all expressions. See :ref:`filtering_default_filters`. 89c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 90c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param disable_unicode: Disables all awareness of Python Unicode 91c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley objects. See :ref:`unicode_disabled`. 92c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 93c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param enable_loop: When ``True``, enable the ``loop`` context variable. 94c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley This can be set to ``False`` to support templates that may 95c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley be making usage of the name "``loop``". Individual templates can 96c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley re-enable the "loop" context by placing the directive 97c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley ``enable_loop="True"`` inside the ``<%page>`` tag -- see 98c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :ref:`migrating_loop`. 99c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 100c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param encoding_errors: Error parameter passed to ``encode()`` when 101c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley string encoding is performed. See :ref:`usage_unicode`. 102c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 103c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param error_handler: Python callable which is called whenever 104c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley compile or runtime exceptions occur. The callable is passed 105c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley the current context as well as the exception. If the 106c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley callable returns ``True``, the exception is considered to 107c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley be handled, else it is re-raised after the function 108c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley completes. Is used to provide custom error-rendering 109c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley functions. 110c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 111c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param format_exceptions: if ``True``, exceptions which occur during 112c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley the render phase of this template will be caught and 113c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley formatted into an HTML error page, which then becomes the 114c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley rendered result of the :meth:`.render` call. Otherwise, 115c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley runtime exceptions are propagated outwards. 116c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 117c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param imports: String list of Python statements, typically individual 118c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley "import" lines, which will be placed into the module level 119c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley preamble of all generated Python modules. See the example 120c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley in :ref:`filtering_default_filters`. 121c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 122c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param future_imports: String list of names to import from `__future__`. 123c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley These will be concatenated into a comma-separated string and inserted 124c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley into the beginning of the template, e.g. ``futures_imports=['FOO', 125c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 'BAR']`` results in ``from __future__ import FOO, BAR``. If you're 126c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley interested in using features like the new division operator, you must 127c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley use future_imports to convey that to the renderer, as otherwise the 128c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley import will not appear as the first executed statement in the generated 129c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley code and will therefore not have the desired effect. 130c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 131c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param input_encoding: Encoding of the template's source code. Can 132c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley be used in lieu of the coding comment. See 133c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :ref:`usage_unicode` as well as :ref:`unicode_toplevel` for 134c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley details on source encoding. 135c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 136c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param lookup: a :class:`.TemplateLookup` instance that will be used 137c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley for all file lookups via the ``<%namespace>``, 138c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley ``<%include>``, and ``<%inherit>`` tags. See 139c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :ref:`usage_templatelookup`. 140c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 141c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param module_directory: Filesystem location where generated 142c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley Python module files will be placed. 143c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 144c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param module_filename: Overrides the filename of the generated 145c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley Python module file. For advanced usage only. 146c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 147c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param module_writer: A callable which overrides how the Python 148c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley module is written entirely. The callable is passed the 149c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley encoded source content of the module and the destination 150c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley path to be written to. The default behavior of module writing 151c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley uses a tempfile in conjunction with a file move in order 152c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley to make the operation atomic. So a user-defined module 153c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley writing function that mimics the default behavior would be: 154c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 155c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley .. sourcecode:: python 156c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 157c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley import tempfile 158c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley import os 159c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley import shutil 160c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 161c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def module_writer(source, outputpath): 162c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley (dest, name) = \\ 163c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley tempfile.mkstemp( 164c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley dir=os.path.dirname(outputpath) 165c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley ) 166c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 167c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley os.write(dest, source) 168c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley os.close(dest) 169c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley shutil.move(name, outputpath) 170c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 171c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley from mako.template import Template 172c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley mytemplate = Template( 173c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley filename="index.html", 174c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley module_directory="/path/to/modules", 175c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley module_writer=module_writer 176c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley ) 177c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 178c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley The function is provided for unusual configurations where 179c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley certain platform-specific permissions or other special 180c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley steps are needed. 181c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 182c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param output_encoding: The encoding to use when :meth:`.render` 183c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley is called. 184c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley See :ref:`usage_unicode` as well as :ref:`unicode_toplevel`. 185c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 186c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param preprocessor: Python callable which will be passed 187c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley the full template source before it is parsed. The return 188c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley result of the callable will be used as the template source 189c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley code. 190c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 191c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param lexer_cls: A :class:`.Lexer` class used to parse 192c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley the template. The :class:`.Lexer` class is used by 193c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley default. 194c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 195c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley .. versionadded:: 0.7.4 196c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 197c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param strict_undefined: Replaces the automatic usage of 198c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley ``UNDEFINED`` for any undeclared variables not located in 199c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley the :class:`.Context` with an immediate raise of 200c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley ``NameError``. The advantage is immediate reporting of 201c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley missing variables which include the name. 202c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 203c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley .. versionadded:: 0.3.6 204c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 205c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley :param uri: string URI or other identifier for this template. 206c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley If not provided, the ``uri`` is generated from the filesystem 207c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley path, or from the in-memory identity of a non-file-based 208c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley template. The primary usage of the ``uri`` is to provide a key 209c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley within :class:`.TemplateLookup`, as well as to generate the 210c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley file path of the generated Python module file, if 211c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley ``module_directory`` is specified. 212c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 213c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley """ 214c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 215c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley lexer_cls = Lexer 216c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 217c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def __init__(self, 218c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley text=None, 219c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley filename=None, 220c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley uri=None, 221c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley format_exceptions=False, 222c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley error_handler=None, 223c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley lookup=None, 224c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley output_encoding=None, 225c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley encoding_errors='strict', 226c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley module_directory=None, 227c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley cache_args=None, 228c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley cache_impl='beaker', 229c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley cache_enabled=True, 230c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley cache_type=None, 231c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley cache_dir=None, 232c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley cache_url=None, 233c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley module_filename=None, 234c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley input_encoding=None, 235c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley disable_unicode=False, 236c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley module_writer=None, 237c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley bytestring_passthrough=False, 238c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley default_filters=None, 239c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley buffer_filters=(), 240c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley strict_undefined=False, 241c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley imports=None, 242c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley future_imports=None, 243c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley enable_loop=True, 244c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley preprocessor=None, 245c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley lexer_cls=None): 246c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if uri: 247c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.module_id = re.sub(r'\W', "_", uri) 248c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.uri = uri 249c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley elif filename: 250c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.module_id = re.sub(r'\W', "_", filename) 251c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley drive, path = os.path.splitdrive(filename) 252c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley path = os.path.normpath(path).replace(os.path.sep, "/") 253c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.uri = path 254c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley else: 255c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.module_id = "memory:" + hex(id(self)) 256c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.uri = self.module_id 257c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 258c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley u_norm = self.uri 259c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if u_norm.startswith("/"): 260c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley u_norm = u_norm[1:] 261c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley u_norm = os.path.normpath(u_norm) 262c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if u_norm.startswith(".."): 263c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley raise exceptions.TemplateLookupException( 264c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley "Template uri \"%s\" is invalid - " 265c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley "it cannot be relative outside " 266c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley "of the root path." % self.uri) 267c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 268c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.input_encoding = input_encoding 269c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.output_encoding = output_encoding 270c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.encoding_errors = encoding_errors 271c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.disable_unicode = disable_unicode 272c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.bytestring_passthrough = bytestring_passthrough or disable_unicode 273c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.enable_loop = enable_loop 274c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.strict_undefined = strict_undefined 275c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.module_writer = module_writer 276c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 277c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if compat.py3k and disable_unicode: 278c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley raise exceptions.UnsupportedError( 279c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley "Mako for Python 3 does not " 280c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley "support disabling Unicode") 281c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley elif output_encoding and disable_unicode: 282c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley raise exceptions.UnsupportedError( 283c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley "output_encoding must be set to " 284c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley "None when disable_unicode is used.") 285c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if default_filters is None: 286c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if compat.py3k or self.disable_unicode: 287c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.default_filters = ['str'] 288c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley else: 289c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.default_filters = ['unicode'] 290c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley else: 291c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.default_filters = default_filters 292c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.buffer_filters = buffer_filters 293c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 294c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.imports = imports 295c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.future_imports = future_imports 296c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.preprocessor = preprocessor 297c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 298c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if lexer_cls is not None: 299c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.lexer_cls = lexer_cls 300c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 301c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley # if plain text, compile code in memory only 302c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if text is not None: 303c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley (code, module) = _compile_text(self, text, filename) 304c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self._code = code 305c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self._source = text 306c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley ModuleInfo(module, None, self, filename, code, text) 307c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley elif filename is not None: 308c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley # if template filename and a module directory, load 309c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley # a filesystem-based module file, generating if needed 310c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if module_filename is not None: 311c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley path = module_filename 312c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley elif module_directory is not None: 313c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley path = os.path.abspath( 314c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley os.path.join( 315c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley os.path.normpath(module_directory), 316c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley u_norm + ".py" 317c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley ) 318c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley ) 319c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley else: 320c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley path = None 321c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley module = self._compile_from_file(path, filename) 322c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley else: 323c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley raise exceptions.RuntimeException( 324c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley "Template requires text or filename") 325c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 326c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.module = module 327c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.filename = filename 328c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.callable_ = self.module.render_body 329c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.format_exceptions = format_exceptions 330c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.error_handler = error_handler 331c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.lookup = lookup 332c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 333c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.module_directory = module_directory 334c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 335c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self._setup_cache_args( 336c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley cache_impl, cache_enabled, cache_args, 337c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley cache_type, cache_dir, cache_url 338c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley ) 339c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 340c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 341c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley @util.memoized_property 342c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def reserved_names(self): 343c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if self.enable_loop: 344c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return codegen.RESERVED_NAMES 345c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley else: 346c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return codegen.RESERVED_NAMES.difference(['loop']) 347c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 348c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def _setup_cache_args(self, 349c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley cache_impl, cache_enabled, cache_args, 350c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley cache_type, cache_dir, cache_url): 351c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.cache_impl = cache_impl 352c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.cache_enabled = cache_enabled 353c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if cache_args: 354c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.cache_args = cache_args 355c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley else: 356c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.cache_args = {} 357c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 358c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley # transfer deprecated cache_* args 359c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if cache_type: 360c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.cache_args['type'] = cache_type 361c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if cache_dir: 362c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.cache_args['dir'] = cache_dir 363c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if cache_url: 364c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.cache_args['url'] = cache_url 365c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 366c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def _compile_from_file(self, path, filename): 367c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if path is not None: 368c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley util.verify_directory(os.path.dirname(path)) 369c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley filemtime = os.stat(filename)[stat.ST_MTIME] 370c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if not os.path.exists(path) or \ 371c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley os.stat(path)[stat.ST_MTIME] < filemtime: 372c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley data = util.read_file(filename) 373c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley _compile_module_file( 374c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self, 375c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley data, 376c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley filename, 377c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley path, 378c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.module_writer) 379c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley module = compat.load_module(self.module_id, path) 380c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley del sys.modules[self.module_id] 381c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if module._magic_number != codegen.MAGIC_NUMBER: 382c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley data = util.read_file(filename) 383c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley _compile_module_file( 384c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self, 385c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley data, 386c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley filename, 387c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley path, 388c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.module_writer) 389c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley module = compat.load_module(self.module_id, path) 390c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley del sys.modules[self.module_id] 391c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley ModuleInfo(module, path, self, filename, None, None) 392c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley else: 393c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley # template filename and no module directory, compile code 394c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley # in memory 395c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley data = util.read_file(filename) 396c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley code, module = _compile_text( 397c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self, 398c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley data, 399c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley filename) 400c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self._source = None 401c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self._code = code 402c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley ModuleInfo(module, None, self, filename, code, None) 403c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return module 404c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 405c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley @property 406c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def source(self): 407c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley """Return the template source code for this :class:`.Template`.""" 408c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 409c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return _get_module_info_from_callable(self.callable_).source 410c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 411c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley @property 412c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def code(self): 413c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley """Return the module source code for this :class:`.Template`.""" 414c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 415c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return _get_module_info_from_callable(self.callable_).code 416c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 417c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley @util.memoized_property 418c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def cache(self): 419c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return cache.Cache(self) 420c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 421c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley @property 422c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def cache_dir(self): 423c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return self.cache_args['dir'] 424c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley @property 425c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def cache_url(self): 426c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return self.cache_args['url'] 427c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley @property 428c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def cache_type(self): 429c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return self.cache_args['type'] 430c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 431c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def render(self, *args, **data): 432c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley """Render the output of this template as a string. 433c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 434c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley If the template specifies an output encoding, the string 435c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley will be encoded accordingly, else the output is raw (raw 436c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley output uses `cStringIO` and can't handle multibyte 437c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley characters). A :class:`.Context` object is created corresponding 438c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley to the given data. Arguments that are explicitly declared 439c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley by this template's internal rendering method are also 440c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley pulled from the given ``*args``, ``**data`` members. 441c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 442c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley """ 443c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return runtime._render(self, self.callable_, args, data) 444c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 445c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def render_unicode(self, *args, **data): 446c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley """Render the output of this template as a unicode object.""" 447c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 448c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return runtime._render(self, 449c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.callable_, 450c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley args, 451c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley data, 452c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley as_unicode=True) 453c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 454c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def render_context(self, context, *args, **kwargs): 455c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley """Render this :class:`.Template` with the given context. 456c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 457c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley The data is written to the context's buffer. 458c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 459c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley """ 460c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if getattr(context, '_with_template', None) is None: 461c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley context._set_with_template(self) 462c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley runtime._render_context(self, 463c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.callable_, 464c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley context, 465c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley *args, 466c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley **kwargs) 467c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 468c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def has_def(self, name): 469c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return hasattr(self.module, "render_%s" % name) 470c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 471c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def get_def(self, name): 472c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley """Return a def of this template as a :class:`.DefTemplate`.""" 473c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 474c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return DefTemplate(self, getattr(self.module, "render_%s" % name)) 475c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 476c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def _get_def_callable(self, name): 477c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return getattr(self.module, "render_%s" % name) 478c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 479c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley @property 480c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def last_modified(self): 481c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return self.module._modified_time 482c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 483c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowleyclass ModuleTemplate(Template): 484c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley """A Template which is constructed given an existing Python module. 485c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 486c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley e.g.:: 487c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 488c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley t = Template("this is a template") 489c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley f = file("mymodule.py", "w") 490c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley f.write(t.code) 491c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley f.close() 492c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 493c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley import mymodule 494c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 495c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley t = ModuleTemplate(mymodule) 496c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley print t.render() 497c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 498c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley """ 499c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 500c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def __init__(self, module, 501c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley module_filename=None, 502c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley template=None, 503c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley template_filename=None, 504c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley module_source=None, 505c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley template_source=None, 506c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley output_encoding=None, 507c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley encoding_errors='strict', 508c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley disable_unicode=False, 509c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley bytestring_passthrough=False, 510c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley format_exceptions=False, 511c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley error_handler=None, 512c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley lookup=None, 513c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley cache_args=None, 514c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley cache_impl='beaker', 515c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley cache_enabled=True, 516c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley cache_type=None, 517c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley cache_dir=None, 518c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley cache_url=None, 519c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley ): 520c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.module_id = re.sub(r'\W', "_", module._template_uri) 521c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.uri = module._template_uri 522c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.input_encoding = module._source_encoding 523c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.output_encoding = output_encoding 524c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.encoding_errors = encoding_errors 525c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.disable_unicode = disable_unicode 526c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.bytestring_passthrough = bytestring_passthrough or disable_unicode 527c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.enable_loop = module._enable_loop 528c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 529c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if compat.py3k and disable_unicode: 530c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley raise exceptions.UnsupportedError( 531c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley "Mako for Python 3 does not " 532c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley "support disabling Unicode") 533c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley elif output_encoding and disable_unicode: 534c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley raise exceptions.UnsupportedError( 535c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley "output_encoding must be set to " 536c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley "None when disable_unicode is used.") 537c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 538c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.module = module 539c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.filename = template_filename 540c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley ModuleInfo(module, 541c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley module_filename, 542c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self, 543c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley template_filename, 544c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley module_source, 545c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley template_source) 546c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 547c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.callable_ = self.module.render_body 548c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.format_exceptions = format_exceptions 549c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.error_handler = error_handler 550c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.lookup = lookup 551c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self._setup_cache_args( 552c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley cache_impl, cache_enabled, cache_args, 553c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley cache_type, cache_dir, cache_url 554c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley ) 555c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 556c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowleyclass DefTemplate(Template): 557c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley """A :class:`.Template` which represents a callable def in a parent 558c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley template.""" 559c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 560c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def __init__(self, parent, callable_): 561c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.parent = parent 562c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.callable_ = callable_ 563c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.output_encoding = parent.output_encoding 564c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.module = parent.module 565c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.encoding_errors = parent.encoding_errors 566c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.format_exceptions = parent.format_exceptions 567c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.error_handler = parent.error_handler 568c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.enable_loop = parent.enable_loop 569c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.lookup = parent.lookup 570c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.bytestring_passthrough = parent.bytestring_passthrough 571c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 572c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def get_def(self, name): 573c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return self.parent.get_def(name) 574c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 575c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowleyclass ModuleInfo(object): 576c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley """Stores information about a module currently loaded into 577c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley memory, provides reverse lookups of template source, module 578c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley source code based on a module's identifier. 579c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 580c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley """ 581c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley _modules = weakref.WeakValueDictionary() 582c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 583c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def __init__(self, 584c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley module, 585c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley module_filename, 586c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley template, 587c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley template_filename, 588c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley module_source, 589c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley template_source): 590c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.module = module 591c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.module_filename = module_filename 592c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.template_filename = template_filename 593c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.module_source = module_source 594c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.template_source = template_source 595c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self._modules[module.__name__] = template._mmarker = self 596c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if module_filename: 597c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self._modules[module_filename] = self 598c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 599c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley @classmethod 600c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def get_module_source_metadata(cls, module_source, full_line_map=False): 601c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley source_map = re.search( 602c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley r"__M_BEGIN_METADATA(.+?)__M_END_METADATA", 603c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley module_source, re.S).group(1) 604c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley source_map = compat.json.loads(source_map) 605c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley source_map['line_map'] = dict((int(k), int(v)) 606c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley for k, v in source_map['line_map'].items()) 607c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if full_line_map: 608c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley f_line_map = source_map['full_line_map'] = [] 609c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley line_map = source_map['line_map'] 610c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 611c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley curr_templ_line = 1 612c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley for mod_line in range(1, max(line_map)): 613c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if mod_line in line_map: 614c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley curr_templ_line = line_map[mod_line] 615c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley f_line_map.append(curr_templ_line) 616c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return source_map 617c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 618c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley @property 619c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def code(self): 620c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if self.module_source is not None: 621c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return self.module_source 622c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley else: 623c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return util.read_python_file(self.module_filename) 624c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 625c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley @property 626c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley def source(self): 627c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if self.template_source is not None: 628c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if self.module._source_encoding and \ 629c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley not isinstance(self.template_source, compat.text_type): 630c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return self.template_source.decode( 631c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley self.module._source_encoding) 632c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley else: 633c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return self.template_source 634c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley else: 635c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley data = util.read_file(self.template_filename) 636c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if self.module._source_encoding: 637c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return data.decode(self.module._source_encoding) 638c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley else: 639c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return data 640c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 641c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowleydef _compile(template, text, filename, generate_magic_comment): 642c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley lexer = template.lexer_cls(text, 643c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley filename, 644c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley disable_unicode=template.disable_unicode, 645c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley input_encoding=template.input_encoding, 646c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley preprocessor=template.preprocessor) 647c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley node = lexer.parse() 648c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley source = codegen.compile(node, 649c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley template.uri, 650c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley filename, 651c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley default_filters=template.default_filters, 652c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley buffer_filters=template.buffer_filters, 653c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley imports=template.imports, 654c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley future_imports=template.future_imports, 655c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley source_encoding=lexer.encoding, 656c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley generate_magic_comment=generate_magic_comment, 657c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley disable_unicode=template.disable_unicode, 658c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley strict_undefined=template.strict_undefined, 659c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley enable_loop=template.enable_loop, 660c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley reserved_names=template.reserved_names) 661c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return source, lexer 662c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 663c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowleydef _compile_text(template, text, filename): 664c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley identifier = template.module_id 665c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley source, lexer = _compile(template, text, filename, 666c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley generate_magic_comment=template.disable_unicode) 667c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 668c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley cid = identifier 669c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if not compat.py3k and isinstance(cid, compat.text_type): 670c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley cid = cid.encode() 671c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley module = types.ModuleType(cid) 672c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley code = compile(source, cid, 'exec') 673c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 674c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley # this exec() works for 2.4->3.3. 675c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley exec(code, module.__dict__, module.__dict__) 676c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return (source, module) 677c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 678c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowleydef _compile_module_file(template, text, filename, outputpath, module_writer): 679c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley source, lexer = _compile(template, text, filename, 680c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley generate_magic_comment=True) 681c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 682c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if isinstance(source, compat.text_type): 683c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley source = source.encode(lexer.encoding or 'ascii') 684c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 685c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if module_writer: 686c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley module_writer(source, outputpath) 687c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley else: 688c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley # make tempfiles in the same location as the ultimate 689c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley # location. this ensures they're on the same filesystem, 690c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley # avoiding synchronization issues. 691c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley (dest, name) = tempfile.mkstemp(dir=os.path.dirname(outputpath)) 692c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 693c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley os.write(dest, source) 694c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley os.close(dest) 695c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley shutil.move(name, outputpath) 696c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 697c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowleydef _get_module_info_from_callable(callable_): 698c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley if compat.py3k: 699c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return _get_module_info(callable_.__globals__['__name__']) 700c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley else: 701c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return _get_module_info(callable_.func_globals['__name__']) 702c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 703c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowleydef _get_module_info(filename): 704c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley return ModuleInfo._modules[filename] 705c6e67f5a9373e916a8d2333585cb5787aa5f7bb7Tim Rowley 706