NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #152 most downloaded on PyPI
A super-fast templating language that borrows the best ideas from the existing templating languages.
Last release 12 days ago
22 Sep 2026
Release timing varies
gaps range from 2 weeks to 12 months
Nearly every release is documented
notes for 60 of the last 60 stable releases
4 versions withdrawn
withdrawn after publishing
20 years old
83 releases · first in 2006
[bug] [tests] Fixed regression caused in 1.4.2 where tests added to the suite were unable to run directly on Windows, due to posix mechanics: the test
Released: Tue Sep 22 2026
[bug] [tests] Fixed regression caused in 1.4.2 where tests added to the suite were
unable to run directly on Windows, due to posix mechanics: the tests force
os.path to posixpath, whereas
TemplateLookup.get_template() converts the configured directory
using os.path.sep. These tests are now skipped on that platform,
where the traversal check is instead exercised against ntpath
natively.
References: #441
[bug] [tests] Adjusted the test suite to accommodate for a change in Pygments 2.21.0 where the HtmlFormatter now renders " and ' characters literally
Released: Tue Sep 22 2026
[bug] [tests] Adjusted the test suite to accommodate for a change in Pygments 2.21.0
where the HtmlFormatter now renders " and ' characters
literally rather than as HTML entities, which caused failures in tests
that assert against the rendered output of
html_error_template().
References: #440
[bug] [template] Fixed issue in TemplateLookup where a URI beginning with a drive
designator (e.g. C:/../../secret.txt) could bypass the directory
traversal check on Windows, allowing reads of arbitrary files outside of
the template directory. The check in Template normalized the URI
using os.path, which on Windows is ntpath; as ntpath splits the
drive designator off and treats the remainder as rooted, the ..
segments were absorbed before the check could inspect them. Normalization
is now performed with posixpath, which is the same module used by
TemplateLookup.get_template() to resolve the URI to a file.
References: #441
One column per quarter.
[bug] [installation] Fixed issue in the 1.4.0 packaging where the repository's internal tools/ directory was detected by setuptools package discovery
Released: Wed Aug 5 2026
[bug] [installation] Fixed issue in the 1.4.0 packaging where the repository's internal
tools/ directory was detected by setuptools package discovery and
installed as a top-level tools package into site-packages, shadowing
unrelated tools packages belonging to other applications. Package
discovery is now limited to the mako package explicitly.
References: #438
Lingua 4.16 resolves entry points using importlib.metadata, so no deprecated pkg_resources usage remains.
Released: Tue Aug 4 2026
[changed] [examples] The examples/bench folder has been removed as it used mostly
long-obsolete template engines. The examples/wsgi/run_wsgi.py example
has been updated to remove the use of the removed-in-Python-3.13 cgi
module, and to be runnable as a module from the project root.
[changed] [installation] Minimum MarkupSafe dependency version bumped from 0.9.2 to 2.0.
[changed] [tests] The test suite now runs via nox. The old tox.ini remains however nox will be the only system that's maintained.
[changed] [installation] Project metadata has been migrated to PEP 621 pyproject.toml-based
configuration. setup.cfg remains only for the [mako_testing]
section used by Mako's own test suite. The build requirements
now set the minimum setuptools version at 77.0.0 in order to build Mako
from source.
[changed] [installation] Minimum Python version is now 3.10. Mako 1.4.0 has been tested up through Python 3.15.0b4.
[bug] [ext] The minimum Lingua version supported by LinguaMakoExtractor is
now 4.16. The test suite had continued to pin Lingua below 4 long after
the extractor itself was repaired to work with Lingua 4 in version 1.2.0,
with the result that the plugin was no longer covered by tests at all; the
pinned version additionally imports pkg_resources at startup, which is
not present in current setuptools releases and left the package
unimportable. Lingua 4.16 resolves entry points using
importlib.metadata, so no deprecated pkg_resources usage remains.
References: #393
[bug] [exceptions] Fixed issue where formatting a traceback for an exception raised inside a
template compiled from a string would emit DeprecationWarning: Module globals is missing a __spec__.loader on Python 3.15. Modules for such
templates were created without a module spec, which Python's
linecache module consults for every frame while a traceback is
being built; the warning was raised from within traceback formatting
itself, disrupting the error report for applications that configure
warnings as errors. These modules are now given a spec with a loader that
provides the generated module source, which additionally allows the
generated source lines to be displayed in tracebacks produced by the
standard library where previously no source was available.
References: #437
[bug] [exceptions] A series of fixes involving syntax warnings and exceptions found during template lexing / compilation:
- Warnings raised while a template is compiled, which in practice means
`SyntaxWarning`, now report the filename and line number of the
template rather than a line within the generated module, and are no
longer reported twice. This applies equally to templates compiled from a
string, from a file, and to a module file in a
`Template.module_directory`, as does a warning raised while
the module level code of a `<%! %>` block runs. Warnings raised while
a template renders continue to report the location within the generated
module.
To do this, Mako replaces `warnings.showwarning` while a template is
compiled. As that name is global to the process, an unrelated warning
displayed by another thread during that window may also be passed through
Mako's hook, which shows any warning it does not recognize unchanged.
([#430](https://github.com/sqlalchemy/mako/issues/430))
- The `SyntaxException` raised for a syntax error in Python code spanning
several lines of a template, such as that within a `<% %>` or `<%! %>`
block, is now reported against the line the error is on, rather than
against the line on which the block begins. The line reported for code
that occupies a single line, such as an expression or a control line, is
unchanged. ([#245](https://github.com/sqlalchemy/mako/issues/245))
- The `SyntaxException` raised for a tag or expression that is never
closed is now reported against the line the construct begins on, rather
than the point at which the search for the closing token gave up, which
for an unclosed construct is the end of the template. The message of the
exception is amended to indicate that the position given is where the
unterminated construct begins. ([#428](https://github.com/sqlalchemy/mako/issues/428))
[bug] [template] Fixed issue in TemplateLookup where a URI with backslash path separators (e.g. \..\secret.txt) could bypass the directory traversal c
Released: Tue Apr 28 2026
[bug] [template] Fixed issue in TemplateLookup where a URI with backslash path
separators (e.g. \..\secret.txt) could bypass the directory traversal
check on Windows, allowing reads of arbitrary files outside of the template
directory. Backslash characters in URIs are now normalized to forward
slashes before path resolution.
References: #435
[bug] [template] Fixed issue in TemplateLookup where a URI with a double-slash prefix (e.g. //../../) could bypass the directory traversal check in Te
Released: Tue Apr 14 2026
[bug] [template] Fixed issue in TemplateLookup where a URI with a double-slash
prefix (e.g. //../../) could bypass the directory traversal check in
Template, allowing reads of arbitrary files outside of the
template directory. The issue was caused by an inconsistency in how leading
slashes were stripped between TemplateLookup.get_template() and
Template initialization.
References: #434
[bug] [lexer] Fix undefined variable errors when strict_undefined=True when using a nested list comprehension. Pull request courtesy Sébastien Granjou
Released: Thu Apr 10 2025
[bug] [lexer] Fix undefined variable errors when strict_undefined=True when using a
nested list comprehension. Pull request courtesy Sébastien Granjoux.
References: #418
[bug] [tests] Fixed test suite to not rely upon ancient "future division" statement to test the Template.future_imports feature. The test is replaced
Released: Tue Feb 4 2025
[bug] [tests] Fixed test suite to not rely upon ancient "future division" statement to
test the Template.future_imports feature. The test is
replaced with one that tests only the rendering, not the ultimate effect.
References: #408
[bug] [lexer] Reverted the fix for #140 released in Mako 1.3.7 as it produced regressions in existing user code.
[bug] [codegen] [lexer] During the lexical analysis phase, add an additional prefix for undeclared identifiers that have the same name as built-in fla
Released: Tue Dec 3 2024
[bug] [codegen] [lexer] During the lexical analysis phase, add an additional prefix for undeclared identifiers that have the same name as built-in flags, and determine the final filter to be used during the code generation phase based on the context provided by the user. Pull request by Hai Zhu.
References: #140
[bug] [lexer] Support the direct passing of dictionary literals when calling functions and fix the errors caused by nested braces. This revises the fix that was released in 1.3.4 and then reverted in 1.3.5. Pull request by Hai Zhu and Jose Galvez.
[bug] [lexer] Fixed long standing bug where the sequence <& would be misinterpreted by the lexer. It's not clear why the ampersand character was part
Released: Mon Oct 21 2024
[bug] [lexer] Fixed long standing bug where the sequence <& would be misinterpreted
by the lexer. It's not clear why the ampersand character was part of the
characters being consumed here and it may have been an inadvertent bit of
code from one of Mako's predecessor languages.
References: #412
[bug] [lexer] [regression] Reverted the fix for #400 as it caused new issues when traversing some bracketed situations.
[bug] [parser] Fixed regression caused by the fix for #320 where new logic added to interpret list and dictionary comprehensions would fail for expres
Released: Mon May 13 2024
[bug] [parser] Fixed regression caused by the fix for #320 where new logic added to interpret list and dictionary comprehensions would fail for expression oriented keys. As the parsing in question was not necessary for these keys, it's been removed. Pull request courtesy Sébastien Granjoux.
References: #398
[bug] [lexer] Fixed issue where a parsed expression which contained sub-brackets, such as dictionary literals, would fail to be interpreted correctly even though the initial parsing is correct. Pull request courtesy Jose Galvez.
References: #400
[bug] [codegen] Fixed unexpected error when use control lines which the first control block with no bodies other than comments, as pass is now added t
Released: Wed Apr 10 2024
[bug] [codegen] Fixed unexpected error when use control lines which the first control block with no bodies other than comments, as pass is now added to the first empty block. Pull request courtesy Hai Zhu.
References: #146
[bug] [parser] Fixed unexpected syntax error in strict_undefined mode that occurred when using comprehensions within a function in a Mako Python code block. Now, the local variable in comprehensions won't be added to the checklist when using strict_undefined mode. Pull request courtesy Hai Zhu.
References: #320
[bug] [lexer] Fixed parsing issue where attempting to render a single percent sign % using an escaped percent %% would not function correctly if the e
Released: Tue Jan 30 2024
[bug] [lexer] Fixed parsing issue where attempting to render a single percent sign % using an escaped percent %% would not function correctly if the escaped percent were not the first character on a line. Note that this is a revised version of a similar change made in Mako 1.3.1 which caused unexpected parsing regressions, resulting in the release being yanked. Pull request courtesy Hai Zhu.
References: #323
[bug] [lexer] Fixed parsing issue where attempting to render a single percent sign % using an escaped percent %% would not function correctly if the e
Released: Mon Jan 22 2024
[bug] [lexer] Fixed parsing issue where attempting to render a single percent sign %
using an escaped percent %% would not function correctly if the escaped
percent were not the first character on a line. Pull request courtesy Hai
Zhu.
References: #323
[change] [installation] Mako 1.3.0 bumps the minimum Python version to 3.8, as 3.7 is EOL as of 2023-06-27. Python 3.12 is now supported explicitly.
Released: Wed Nov 8 2023
[bug] [codegen] Fixed issue where unpacking nested tuples in a for loop using would raise a "couldn't apply loop context" error if the loop context wa
Released: Tue Nov 15 2022
[bug] [codegen] Fixed issue where unpacking nested tuples in a for loop using would raise a "couldn't apply loop context" error if the loop context was used. The regex used to match the for loop expression now allows the list of loop variables to contain parenthesized sub-tuples. Pull request courtesy Matt Trescott.
References: #368
[bug] [lexer] Fixed issue in lexer in the same category as that of #366 where the regexp used to match an end tag didn't correctly organize for matchi
Released: Thu Sep 22 2022
[bug] [lexer] Fixed issue in lexer in the same category as that of #366 where the regexp used to match an end tag didn't correctly organize for matching characters surrounded by whitespace, leading to high memory / interpreter hang if a closing tag incorrectly had a large amount of unterminated space in it. Credit to Sebastian Chnelik for locating the issue.
As Mako templates inherently render and directly invoke arbitrary Python code from the template source, it is never appropriate to create templates that contain untrusted input.
References: #367
[bug] [lexer] Fixed issue in lexer where the regexp used to match tags would not correctly interpret quoted sections individually. While this parsing
Released: Mon Aug 29 2022
[bug] [lexer] Fixed issue in lexer where the regexp used to match tags would not correctly interpret quoted sections individually. While this parsing issue still produced the same expected tag structure later on, the mis-handling of quoted sections was also subject to a regexp crash if a tag had a large number of quotes within its quoted sections.
References: #366
[bug] [tests] Various fixes to the test suite in the area of exception message rendering to accommodate for variability in Python versions as well as
Released: Thu Jun 30 2022
[bug] [tests] Various fixes to the test suite in the area of exception message rendering to accommodate for variability in Python versions as well as Pygments.
References: #360
[performance] Optimized some codepaths within the lexer/Python code generation process, improving performance for generation of templates prior to their being cached. Pull request courtesy Takuto Ikuta.
References: #361
[changed] [py3k] Corrected "universal wheel" directive in setup.cfg so that building a wheel does not target Python 2.
Released: Thu Mar 10 2022
[changed] [py3k] Corrected "universal wheel" directive in setup.cfg so that building a
wheel does not target Python 2.
References: #351
[changed] [py3k] The bytestring_passthrough template argument is removed, as this
flag only applied to Python 2.
[changed] [py3k] With the removal of Python 2's cStringIO, Mako now uses its own
internal FastEncodingBuffer exclusively.
[changed] [py3k] Removed disable_unicode flag, that's no longer used in Python 3.
[changed] Refactored test utilities into mako.testing module. Removed
unittest.TestCase dependency in favor of pytest.
References: #349
[changed] [setup] Replaced the use of pkg_resources with the importlib library.
For Python < 3.8 the library importlib_metadata is used.
[changed] [py3k] Removed support for Python 2 and Python 3.6. Mako now requires Python >= 3.7.
raise from, correctly
identifying underlying exception conditions when it raises its own
exceptions. Pull request courtesy Ram Rachum.[bug] [lexer] Fixed issue where control statements on multi lines with a backslash would not parse correctly if the template itself contained CR/LF pa
Released: Wed Nov 17 2021
[bug] [lexer] Fixed issue where control statements on multi lines with a backslash would not parse correctly if the template itself contained CR/LF pairs as on Windows. Pull request courtesy Charles Pigott.
References: #346
[bug] [tests] Fixed some issues with running the test suite which would be revealed by running tests in random order.
Released: Fri Aug 20 2021
[bug] [tests] Fixed some issues with running the test suite which would be revealed by running tests in random order.
References: #338
[bug] [py3k] Fixed Python deprecation issues related to module importing, as well as file access within the Lingua plugin, for deprecated APIs that be…
Released: Thu Jan 14 2021
[bug] [py3k] Fixed Python deprecation issues related to module importing, as well as file access within the Lingua plugin, for deprecated APIs that began to emit warnings under Python 3.10. Pull request courtesy Petr Viktorin.
References: #328
[bug] [templates] The default template encoding is now utf-8. Previously, the encoding was "ascii", which was standard throughout Python 2. This allow
Released: Fri May 29 2020
[bug] [templates] The default template encoding is now utf-8. Previously, the encoding was "ascii", which was standard throughout Python 2. This allows that "magic encoding comment" for utf-8 templates is no longer required.
References: #267
[feature] [commands] Added --output-file argument to the Mako command line runner, which allows a specific output file to be selected. Pull request co
Released: Sun Mar 1 2020
[feature] [commands] Added --output-file argument to the Mako command line runner, which allows a specific output file to be selected. Pull request courtesy Björn Dahlgren.
References: #283
…ago in Python 2.5, as "parser.suite" is emitting deprecation warnings in Python 3.9.
Released: Mon Jan 20 2020
[bug] [py3k] Replaced usage of the long-superseded "parser.suite" module in the mako.util package for parsing the python magic encoding comment with the "ast.parse" function introduced many years ago in Python 2.5, as "parser.suite" is emitting deprecation warnings in Python 3.9.
References: #310
[bug] [ext] Added "babel" and "lingua" dependency entries to the setuptools entrypoints for the babel and lingua extensions, so that pkg_resources can check that these extra dependencies are available, raising an informative exception if not. Pull request courtesy sinoroc.
References: #304
[bug] [py3k] Replaced usage of inspect.getfullargspec() with the vendored version used by SQLAlchemy, Alembic to avoid future deprecation warnings. Al…
Released: Thu Aug 1 2019
[bug] [py3k] [windows] Replaced usage of time.clock() on windows as well as time.time() elsewhere for microsecond timestamps with timeit.default_timer(), as time.clock() is being removed in Python 3.8. Pull request courtesy Christoph Reiter.
References: #301
[bug] [py3k] Replaced usage of inspect.getfullargspec() with the vendored version
used by SQLAlchemy, Alembic to avoid future deprecation warnings. Also
cleans up an additional version of the same function that's apparently
been floating around for some time.
References: #295
[changed] [setup] Removed the "python setup.py test" feature in favor of a straight run of "tox". Per Pypa / pytest developers, "setup.py" commands are in general headed towards deprecation in favor of tox. The tox.ini script has been updated such that running "tox" with no arguments will perform a single run of the test suite against the default installed Python interpreter.
References: #303
[changed] [installer] [py3k] Mako 1.1 now supports Python versions:
- 2.7
- 3.4 and higher
This includes that setup.py no longer includes any conditionals, allowing for a pure Python wheel build, however this is not necessarily part of the Pypi release process as of yet. The test suite also raises for Python deprecation warnings.
References: #249
[feature] [template] The n filter is now supported in the <%page> tag. This allows a template to omit the default expression filters throughout a whol
Released: Sat Jul 20 2019
[feature] [template] The n filter is now supported in the <%page> tag. This allows a
template to omit the default expression filters throughout a whole
template, for those cases where a template-wide filter needs to have
default filtering disabled. Pull request courtesy Martin von Gagern.
[bug] [exceptions] Fixed issue where the correct file URI would not be shown in the template-formatted exception traceback if the template filename were not known. Additionally fixes an issue where stale filenames would be displayed if a stack trace alternated between different templates. Pull request courtesy Martin von Gagern.
[bug] [exceptions] Improved the line-number tracking for source lines inside of Python <% ... %> blocks, such that text- and HTML-formatted exception
Released: Mon Jul 1 2019
<% ... %> blocks, such that text- and HTML-formatted exception traces such
as that of html_error_template() now report the correct source line
inside the block, rather than the first line of the block itself.
Exceptions in <%! ... %> blocks which get raised while loading the
module are still not reported correctly, as these are handled before the
Mako code is generated. Pull request courtesy Martin von Gagern.[bug] [py3k] Fixed regression where import refactors in Mako 1.0.11 caused broken imports on Python 3.8.
Released: Wed Jun 5 2019
[bug] [py3k] Fixed regression where import refactors in Mako 1.0.11 caused broken imports on Python 3.8.
References: #296
[changed] Updated for additional project metadata in setup.py. Additionally, the code has been reformatted using Black and zimports.
Released: Fri May 31 2019
[bug] [py3k] Added a default encoding of "utf-8" when the RichTraceback object retrieves Python source lines from a Python traceback; as these are byt
Released: Fri May 10 2019
[bug] [py3k] Added a default encoding of "utf-8" when the RichTraceback
object retrieves Python source lines from a Python traceback; as these
are bytes in Python 3 they need to be decoded so that they can be
formatted in the template.
References: #293
[bug] Further corrected the previous fix for #287 as it relied upon an attribute that is monkeypatched by Python's ast module for some reason, which f
Released: Mon Apr 15 2019
[bug] Further corrected the previous fix for #287 as it relied upon
an attribute that is monkeypatched by Python's ast module for some
reason, which fails if ast hasn't been imported; the correct
attribute Constant.value is now used. Also note the issue
was mis-numbered in the previous changelog note.
References: #287
[bug] Fixed an element in the AST Python generator which changed for Python 3.8, causing expression generation to fail.
Released: Wed Mar 20 2019
[bug] Fixed an element in the AST Python generator which changed for Python 3.8, causing expression generation to fail.
References: #287
[feature] Added --output-encoding flag to the mako-render script.
Pull request courtesy lacsaP.
References: #271
[bug] Removed unnecessary "usage" prefix from mako-render script. Pull request courtesy Hugo.
[bug] Changed the "print" in the mako-render command to sys.stdout.write(), avoiding the extra newline at the end of the template output. Pull request
Released: Thu Jul 13 2017
[feature] Added new parameter Template.include_error_handler . This works like Template.error_handler but indicates the handler should take place when
Released: Wed Nov 9 2016
Template.include_error_handler .
This works like Template.error_handler but indicates the
handler should take place when this template is included within another
template via the <%include> tag. Pull request courtesy
Huayi Zhang.[bug] Updated the Sphinx documentation builder to work with recent versions of Sphinx.
Released: Wed Nov 2 2016
[feature] [test] The default test runner is now py.test. Running "python setup.py test" will make use of py.test instead of nose. nose still works as
Released: Thu Mar 10 2016
[feature] [test] The default test runner is now py.test. Running "python setup.py test" will make use of py.test instead of nose. nose still works as a test runner as well, however.
[bug] [lexer] Major improvements to lexing of intricate Python sections which may contain complex backslash sequences, as well as support for the bitwise operator (e.g. pipe symbol) inside of expression sections distinct from the Mako "filter" operator, provided the operator is enclosed within parentheses or brackets. Pull request courtesy Daniel Martin.
References: pull request github:19
[feature] Added new method Template.list_defs(). Pull request courtesy
Jonathan Vanasco.
[babel] [bug] Fixed an issue where the Babel plugin would not handle a translation symbol that contained non-ascii characters. Pull request courtesy R
Released: Tue Oct 27 2015
…(seems to be called from the TG plugin) to avoid deprecation warnings.
Released: Wed Aug 26 2015
[bug] [installation] The "universal wheel" marker is removed from setup.cfg, because our setup.py currently makes use of conditional dependencies. In #249, the discussion is ongoing on how to correct our setup.cfg / setup.py fully so that we can handle the per-version dependency changes while still maintaining optimal wheel settings, so this issue is not yet fully resolved.
References: #249
[bug] [py3k] Repair some calls within the ast module that no longer work on Python3.5;
additionally replace the use of inspect.getargspec() under
Python 3 (seems to be called from the TG plugin) to avoid deprecation
warnings.
References: #250
[bug] Update the Lingua translation extraction plugin to correctly handle templates mixing Python control statements (such as if, for and while) with template fragments. Pull request courtesy Laurent Daverio.
[feature] Added STOP_RENDERING keyword for returning/exiting from a
template early, which is a synonym for an empty string "".
Previously, the docs suggested a bare
return, but this could cause None to appear in the
rendered template result.
References: #236
[feature] Added support for Lingua, a translation extraction system as an alternative to Babel. Pull request courtesy Wichert Akkerman.
Released: Thu Jan 22 2015
[feature] Added support for Lingua, a translation extraction system as an alternative to Babel. Pull request courtesy Wichert Akkerman.
[bug] [py3k] Modernized the examples/wsgi/run_wsgi.py file for Py3k. Pull requset courtesy Cody Taylor.
[bug] [py2k] Improved the error re-raise operation when a custom Template.error_handler is used that does not handle the exception; the original stack
Released: Sun Jun 8 2014
[bug] [py2k] Improved the error re-raise operation when a custom
Template.error_handler is used that does not handle
the exception; the original stack trace etc. is now preserved.
Pull request courtesy Manfred Haltner.
[bug] [filters] [py2k] Added an html_escape filter that works in "non unicode" mode.
Previously, when using disable_unicode=True, the u filter
would fail to handle non-ASCII bytes properly. Pull request
courtesy George Xie.
[general] Compatibility changes; in order to modernize the codebase, Mako is now dropping support for Python 2.4 and Python 2.5 altogether. The source base is now targeted at Python 2.6 and forwards.
[feature] Template modules now generate a JSON "metadata" structure at the bottom of the source file which includes parseable information about the templates' source file, encoding etc. as well as a mapping of module source lines to template lines, thus replacing the "# SOURCE LINE" markers throughout the source code. The structure also indicates those lines that are explicitly not part of the template's source; the goal here is to allow better integration with coverage and other tools.
[bug] [py3k] Fixed bug in decode.<encoding> filter where a non-string object
would not be correctly interpreted in Python 3.
[bug] [py3k] Fixed bug in Python parsing logic which would fail on Python 3 when a "try/except" targeted a tuple of exception types, rather than a single exception.
References: #227
[feature] mako-render is now implemented as a setuptools entrypoint script; a standalone mako.cmd.cmdline() callable is now available, and the system also uses argparse now instead of optparse. Pull request courtesy Derek Harland.
[feature] The mako-render script will now catch exceptions and run them into the text error handler, and exit with a non-zero exit code. Pull request courtesy Derek Harland.
[bug] A rework of the mako-render script allows the script to run
correctly when given a file pathname that is outside of the current
directory, e.g. mako-render ../some_template.mako. In this case,
the "template root" defaults to the directory in which the template
is located, instead of ".". The script also accepts a new argument
--template-dir which can be specified multiple times to establish
template lookup directories. Standard input for templates also works
now too. Pull request courtesy Derek Harland.
[feature] [py3k] Support is added for Python 3 "keyword only" arguments, as used in defs. Pull request courtesy Eevee.
References: pull request github:7
[bug] Fixed bug in Babel plugin where translator comments would be lost if intervening text nodes were encountered. Fix courtesy Ned Batchelder.
Released: Thu Dec 26 2013
[bug] Fixed bug in Babel plugin where translator comments would be lost if intervening text nodes were encountered. Fix courtesy Ned Batchelder.
References: #225
[bug] Fixed TGPlugin.render method to support unicode template names in Py2K - courtesy Vladimir Magamedov.
[bug] Fixed an AST issue that was preventing correct operation under alpha versions of Python 3.4. Pullreq courtesy Zer0-.
[bug] Changed the format of the "source encoding" header output
by the code generator to use the format # -*- coding:%s -*-
instead of # -*- encoding:%s -*-; the former is more common
and compatible with emacs. Courtesy Martin Geisler.
[bug] Fixed issue where an old lexer rule prevented a template line which looked like "#*" from being correctly parsed.
References: #224
Code that's subject to babel escapes in here needs to be specified as a Python expression, not a literal. This change is backwards incompatible vs. co…
Released: Tue Aug 27 2013
[bug] The Context.locals_() method becomes a private underscored method, as this method has a specific internal use. The purpose of Context.kwargs has been clarified, in that it only delivers top level keyword arguments originally passed to template.render().
References: #219
[bug] Fixed the babel plugin to properly interpret ${} sections inside of a "call" tag, i.e. <%self:some_tag attr="${_('foo')}"/>. Code that's subject to babel escapes in here needs to be specified as a Python expression, not a literal. This change is backwards incompatible vs. code that is relying upon a _('') translation to be working within a call tag.
[bug] The Babel plugin has been repaired to work on Python 3.
References: #187
[bug] Using <%namespace import="*" module="somemodule"/> now skips over module elements that are not explcitly callable, avoiding TypeError when trying to produce partials.
References: #207
[bug] Fixed Py3K bug where a "lambda" expression was not interpreted correctly within a template tag; also fixed in Py2.4.
References: #190
[bug] Cleaned up all the various deprecation/ file warnings when running the tests under various Pythons with warnings turned on.
Released: Fri May 24 2013
[bug] Changed setup.py to skip installing markupsafe if Python version is < 2.6 or is between 3.0 and less than 3.3, as Markupsafe now only supports 2.6->2.X, 3.3->3.X.
References: #216
[bug] Fixed regression where "entity" filter wasn't converted for py3k properly (added tests.)
References: #214
[bug] Fixed bug where mako-render script wasn't compatible with Py3k.
References: #212
[bug] Cleaned up all the various deprecation/ file warnings when running the tests under various Pythons with warnings turned on.
References: #213
[feature] Performance improvement to the "legacy" HTML escape feature, used for XML escaping and when markupsafe isn't present, courtesy George Xie.
Released: Wed Apr 10 2013
[feature] Performance improvement to the "legacy" HTML escape feature, used for XML escaping and when markupsafe isn't present, courtesy George Xie.
[bug] Fixed bug whereby an exception in Python 3 against a module compiled to the filesystem would fail trying to produce a RichTraceback due to the content being in bytes.
References: #209
[bug] Change default for compile()->reserved_names from tuple to frozenset, as this is expected to be a set by default.
References: #208
[feature] Code has been reworked to support Python 2.4-> Python 3.xx in place. 2to3 no longer needed.
[feature] Added lexer_cls argument to Template, TemplateLookup, allows alternate Lexer classes to be used.
[feature] Added future_imports parameter to Template and TemplateLookup, renders the future header with desired capabilities at the top of the generated template module. Courtesy Ben Trofatter.
[bug] legacy_html_escape function, used when Markupsafe isn't installed, was using an inline-compiled regexp which causes major slowdowns on Python 3.
Released: Wed Nov 7 2012
[bug] legacy_html_escape function, used when Markupsafe isn't installed, was using an inline-compiled regexp which causes major slowdowns on Python 3.3; is now precompiled.
[bug] AST supporting now supports tuple-packed function arguments inside pure-python def or lambda expressions.
References: #201
[bug] Fixed Py3K bug in the Babel extension.
[bug] Fixed the "filter" attribute of the <%text> tag so that it pulls locally specified identifiers from the context the same way as that of <%block> and <%filter>.
[bug] Fixed bug in plugin loader to correctly raise exception when non-existent plugin is specified.
[bug] Fixed regression in 0.7.1 where AST parsing for Py2.4 was broken.
Released: Fri Jul 20 2012
[bug] Fixed regression in 0.7.1 where AST parsing for Py2.4 was broken.
References: #193
[feature] Control lines with no bodies will now succeed, as "pass" is added for these when no statements are otherwise present. Courtesy Ben Trofatter
Released: Sun Jul 8 2012
[feature] Control lines with no bodies will now succeed, as "pass" is added for these when no statements are otherwise present. Courtesy Ben Trofatter
References: #146
[bug] Fixed some long-broken scoping behavior involving variables declared in defs and such, which only became apparent when the strict_undefined flag was turned on.
References: #192
[bug] Can now use strict_undefined at the same time args passed to def() are used by other elements of the <%def> tag.
References: #191
[feature] Added new "loop" variable to templates, is provided within a % for block to provide info about the loop such as index, first/last, odd/even,
Released: Fri Mar 30 2012
[feature] Added new "loop" variable to templates, is provided within a % for block to provide info about the loop such as index, first/last, odd/even, etc. A migration path is also provided for legacy templates via the "enable_loop" argument available on Template, TemplateLookup, and <%page>. Thanks to Ben Trofatter for all the work on this
References: #125
[feature] Added a real check for "reserved" names, that is names which are never pulled from the context and cannot be passed to the template.render() method. Current names are "context", "loop", "UNDEFINED".
[feature] The html_error_template() will now apply Pygments highlighting to the source code displayed in the traceback, if Pygments if available. Courtesy Ben Trofatter
References: #95
[feature] Added support for context managers, i.e. "% with x as e:/ % endwith" support. Courtesy Ben Trofatter
References: #147
[feature] Added class-level flag to CacheImpl "pass_context"; when True, the keyword argument 'context' will be passed to get_or_create() containing the Mako Context object.
References: #185
[bug] Fixed some Py3K resource warnings due to filehandles being implicitly closed.
References: #182
[bug] Fixed endless recursion bug when nesting multiple def-calls with content. Thanks to Jeff Dairiki.
References: #186
[feature] Added Jinja2 to the example benchmark suite, courtesy Vincent Férotin
[bug] The ${{"foo":"bar"}} parsing issue is fixed!! The legendary Eevee has slain the dragon!. Also fixes quoting issue at.
[bug] Added special compatibility for the 0.5.0 Cache() constructor, which was preventing file version checks and not allowing Mako 0.6 to recompile t
Released: Sat Jan 28 2012
The cache_dir, cache_url, cache_type, cache_timeout arguments are deprecated (will probably never be removed, however) and can be passed now as cache_…
Released: Sat Jan 21 2012
[feature] Template caching has been converted into a plugin system, whereby the usage of Beaker is just the default plugin. Template and TemplateLookup now accept a string "cache_impl" parameter which refers to the name of a cache plugin, defaulting to the name 'beaker'. New plugins can be registered as pkg_resources entrypoints under the group "mako.cache", or registered directly using mako.cache.register_plugin(). The core plugin is the mako.cache.CacheImpl class.
[feature] Added support for Beaker cache regions in templates. Usage of regions should be considered as superseding the very obsolete idea of passing in backend options, timeouts, etc. within templates.
[feature] The 'put' method on Cache is now 'set'. 'put' is there for backwards compatibility.
[feature] The <%def>, <%block> and <%page> tags now accept any argument named "cache_*", and the key minus the "cache_" prefix will be passed as keyword arguments to the CacheImpl methods.
[feature] Template and TemplateLookup now accept an argument cache_args, which refers to a dictionary containing cache parameters. The cache_dir, cache_url, cache_type, cache_timeout arguments are deprecated (will probably never be removed, however) and can be passed now as cache_args={'url':<some url>, 'type':'memcached', 'timeout':50, 'dir':'/path/to/some/directory'}
[feature/bug] Can now refer to context variables within extra arguments to <%block>, <%def>, i.e. <%block name="foo" cache_key="${somekey}">. Filters can also be used in this way, i.e. <%def name="foo()" filter="myfilter"> then template.render(myfilter=some_callable)
References: #180
[feature] Added "--var name=value" option to the mako-render script, allows passing of kw to the template from the command line.
References: #178
[feature] Added module_writer argument to Template, TemplateLookup, allows a callable to be passed which takes over the writing of the template's module source file, so that special environment-specific steps can be taken.
References: #181
[bug] The exception message in the html_error_template is now escaped with the HTML filter.
References: #142
[bug] Added "white-space:pre" style to html_error_template() for code blocks so that indentation is preserved
References: #173
[bug] The "benchmark" example is now Python 3 compatible (even though several of those old template libs aren't available on Py3K, so YMMV)
References: #175
A Template is explicitly disallowed from having a url that normalizes to relative outside of the root. That is, if the Lookup is based at /home/mytemp
Released: Wed Sep 28 2011
A Template is explicitly disallowed from having a url that normalizes to relative outside of the root. That is, if the Lookup is based at /home/mytemplates, an include that would place the ultimate template at /home/mytemplates/../some_other_directory, i.e. outside of /home/mytemplates, is disallowed. This usage was never intended despite the lack of an explicit check. The main issue this causes is that module files can be written outside of the module root (or raise an error, if file perms aren't set up), and can also lead to the same template being cached in the lookup under multiple, relative roots. TemplateLookup instead has always supported multiple file roots for this purpose.
References: #174
Fixed bug regarding <%call>/def calls w/ content whereby the identity of the "caller" callable inside the <%def> would be corrupted by the presence of
New tag: <%block>. A variant on <%def> that evaluates its contents in-place. Can be named or anonymous, the named version is intended for inheritance
Released: Wed Apr 6 2011
New tag: <%block>. A variant on <%def> that evaluates its contents in-place. Can be named or anonymous, the named version is intended for inheritance layouts where any given section can be surrounded by the <%block> tag in order for it to become overrideable by inheriting templates, without the need to specify a top-level <%def> plus explicit call. Modified scoping and argument rules as well as a more strictly enforced usage scheme make it ideal for this purpose without at all replacing most other things that defs are still good for. Lots of new docs.
References: #164
a slight adjustment to the "highlight" logic for generating template bound stacktraces. Will stick to known template source lines without any extra guessing.
References: #165
A 20% speedup for a basic two-page inheritance setup rendering a table of escaped data (see http://techspot.zzzeek.org/2010/11/19/quick-mako-vs.-jinja
Released: Sun Mar 6 2011
A 20% speedup for a basic two-page inheritance setup rendering a table of escaped data (see http://techspot.zzzeek.org/2010/11/19/quick-mako-vs.-jinja-speed-test/). A few configurational changes which affect those in the I-don't-do-unicode camp should be noted below.
The FastEncodingBuffer is now used by default instead of cStringIO or StringIO, regardless of whether output_encoding is set to None or not. FEB is faster than both. Only StringIO allows bytestrings of unknown encoding to pass right through, however - while it is of course not recommended to send bytestrings of unknown encoding to the output stream, this mode of usage can be re-enabled by setting the flag bytestring_passthrough to True.
disable_unicode mode requires that output_encoding be set to None - it also forces the bytestring_passthrough flag to True.
the <%namespace> tag raises an error if the 'template' and 'module' attributes are specified at the same time in one tag. A different class is used for each case which allows a reduction in runtime conditional logic and function call overhead.
References: #156
the keys() in the Context, as well as it's internal _data dictionary, now include just what was specified to render() as well as Mako builtins 'caller', 'capture'. The contents of builtin are no longer copied. Thanks to Daniel Lopez for pointing this out.
References: #159
Beaker is now part of "extras" in setup.py instead of "install_requires". This to produce a lighter weight install for those who don't use the caching
Released: Sat Nov 13 2010
Documentation is on Sphinx.
References: #126
Beaker is now part of "extras" in setup.py instead of "install_requires". This to produce a lighter weight install for those who don't use the caching as well as to conform to Pyramid deployment practices.
References: #154
The Beaker import (or attempt thereof) is delayed until actually needed; this to remove the performance penalty from startup, particularly for "single execution" environments such as shell scripts.
References: #153
Patch to lexer to not generate an empty '' write in the case of backslash-ended lines.
References: #155
Fixed missing **extra collection in setup.py which prevented setup.py from running 2to3 on install.
References: #148
New flag on Template, TemplateLookup - strict_undefined=True, will cause variables not found in the context to raise a NameError immediately, instead of defaulting to the UNDEFINED value.
The range of Python identifiers that are considered "undefined", meaning they are pulled from the context, has been trimmed back to not include variables declared inside of expressions (i.e. from list comprehensions), as well as in the argument list of lambdas. This to better support the strict_undefined feature. The change should be fully backwards-compatible but involved a little bit of tinkering in the AST code, which hadn't really been touched for a couple of years, just FYI.
Your coding agent can read these notes before it upgrades. Set up the MCP server →