diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml new file mode 100644 index 000000000..48eb1503a --- /dev/null +++ b/.azure-pipelines.yml @@ -0,0 +1,61 @@ +trigger: + - master + - '*.x' + +variables: + vmImage: ubuntu-latest + python.version: 3.7 + TOXENV: py,coverage-ci + hasTestResults: true + +strategy: + matrix: + Python 3.7 Linux: + vmImage: ubuntu-latest + Python 3.7 Windows: + vmImage: windows-latest + Python 3.7 Mac: + vmImage: macos-latest + PyPy 3 Linux: + python.version: pypy3 + Python 3.6 Linux: + python.version: 3.6 + Python 3.5 Linux: + python.version: 3.5 + Python 2.7 Linux: + python.version: 2.7 + Python 2.7 Windows: + python.version: 2.7 + vmImage: windows-latest + Docs: + TOXENV: docs-html + hasTestResults: false + +pool: + vmImage: $[ variables.vmImage ] + +steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: $(python.version) + displayName: Use Python $(python.version) + + - script: pip --disable-pip-version-check install -U tox + displayName: Install tox + + - script: tox -s false -- --junit-xml=test-results.xml + displayName: Run tox + + - task: PublishTestResults@2 + inputs: + testResultsFiles: test-results.xml + testRunTitle: $(Agent.JobName) + condition: eq(variables['hasTestResults'], 'true') + displayName: Publish test results + + - task: PublishCodeCoverageResults@1 + inputs: + codeCoverageTool: Cobertura + summaryFileLocation: coverage.xml + condition: eq(variables['hasTestResults'], 'true') + displayName: Publish coverage results diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 7cfb347de..000000000 --- a/.coveragerc +++ /dev/null @@ -1,11 +0,0 @@ -[run] -branch = True -source = - jinja2 - tests - -[paths] -source = - jinja2 - .tox/*/lib/python*/site-packages/jinja2 - .tox/pypy/site-packages/jinja2 diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 285333fd5..000000000 --- a/.travis.yml +++ /dev/null @@ -1,45 +0,0 @@ -sudo: false -language: python - -python: - - 3.6 - - 3.5 - - 3.4 - - 3.3 - - 2.7 - - 2.6 - - pypy - -env: - - TOXENV=py,codecov - -matrix: - include: - - python: nightly - env: TOXENV=py - - python: 3.6 - env: TOXENV=docs-html - -install: - - pip install tox - -script: - - tox - -cache: - - pip - -branches: - only: - - master - - /^.*-maintenance$/ - -notifications: - email: false - irc: - channels: - - "chat.freenode.net#pocoo" - on_success: change - on_failure: always - use_notice: true - skip_join: true diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index fd6dbfcbf..000000000 --- a/AUTHORS +++ /dev/null @@ -1,34 +0,0 @@ -Jinja is written and maintained by the Jinja Team and various -contributors: - -Lead Developer: - -- Armin Ronacher - -Developers: - -- Christoph Hack -- Georg Brandl - -Contributors: - -- Bryan McLemore -- Mickaël Guérin -- Cameron Knight -- Lawrence Journal-World. -- David Cramer -- Adrian Mönnich (ThiefMaster) - -Patches and suggestions: - -- Ronny Pfannschmidt -- Axel Böhm -- Alexey Melchakov -- Bryan McLemore -- Clovis Fabricio (nosklo) -- Cameron Knight -- Peter van Dijk (Habbie) -- Stefan Ebner -- Rene Leonhardt -- Thomas Waldmann -- Cory Benfield (Lukasa) diff --git a/CHANGES.rst b/CHANGES.rst index 28f32781d..1df6bfeda 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,5 +1,24 @@ -Jinja Changelog -=============== +.. currentmodule:: jinja2 + +Version 2.10.3 +-------------- + +Released 2019-10-24 + +- Fix a typo in Babel entry point in ``setup.py`` that was preventing + installation. + + +Version 2.10.2 +-------------- + +Released 2019-10-04 + +- Fix Python 3.7 deprecation warnings. +- Using ``range`` in the sandboxed environment uses ``xrange`` on + Python 2 to avoid memory use. :issue:`933` +- Use Python 3.7's better traceback support to avoid a core dump when + using debug builds of Python 3.7. :issue:`1050` Version 2.10.1 @@ -15,592 +34,600 @@ Released 2019-04-06 Version 2.10 ------------ -released on November 8th 2017 - -- Added a new extension node called ``OverlayScope`` which can be used to - create an unoptimized scope that will look up all variables from a - derived context. -- Added an ``in`` test that works like the in operator. This can be used - in combination with ``reject`` and ``select``. -- Added ``previtem`` and ``nextitem`` to loop contexts, providing access to the - previous/next item in the loop. If such an item does not exist, the value is - undefined. -- Added ``changed(*values)`` to loop contexts, providing an easy way of - checking whether a value has changed since the last iteration (or rather - since the last call of the method) -- Added a ``namespace`` function that creates a special object which allows - attribute assignment using the ``set`` tag. This can be used to carry data - across scopes, e.g. from a loop body to code that comes after the loop. -- Added a ``trimmed`` modifier to ``{% trans %}`` to strip linebreaks and - surrounding whitespace. Also added a new policy to enable this for all - ``trans`` blocks. -- The ``random`` filter is no longer incorrectly constant folded and will - produce a new random choice each time the template is rendered. (`#478`_) -- Added a ``unique`` filter. (`#469`_) -- Added ``min`` and ``max`` filters. (`#475`_) -- Added tests for all comparison operators: ``eq``, ``ne``, ``lt``, ``le``, - ``gt``, ``ge``. (`#665`_) -- ``import`` statement cannot end with a trailing comma. (`#617`_, `#618`_) -- ``indent`` filter will not indent blank lines by default. (`#685`_) -- Add ``reverse`` argument for ``dictsort`` filter. (`#692`_) -- Add a ``NativeEnvironment`` that renders templates to native Python types - instead of strings. (`#708`_) -- Added filter support to the block ``set`` tag. (`#489`_) -- ``tojson`` filter marks output as safe to match documented behavior. - (`#718`_) -- Resolved a bug where getting debug locals for tracebacks could - modify template context. -- Fixed a bug where having many ``{% elif ... %}`` blocks resulted in a - "too many levels of indentation" error. These blocks now compile to - native ``elif ..:`` instead of ``else: if ..:`` (`#759`_) - -.. _#469: https://github.com/pallets/jinja/pull/469 -.. _#475: https://github.com/pallets/jinja/pull/475 -.. _#478: https://github.com/pallets/jinja/pull/478 -.. _#489: https://github.com/pallets/jinja/pull/489 -.. _#617: https://github.com/pallets/jinja/pull/617 -.. _#618: https://github.com/pallets/jinja/pull/618 -.. _#665: https://github.com/pallets/jinja/pull/665 -.. _#685: https://github.com/pallets/jinja/pull/685 -.. _#692: https://github.com/pallets/jinja/pull/692 -.. _#708: https://github.com/pallets/jinja/pull/708 -.. _#718: https://github.com/pallets/jinja/pull/718 -.. _#759: https://github.com/pallets/jinja/pull/759 +Released 2017-11-08 + +- Added a new extension node called ``OverlayScope`` which can be used + to create an unoptimized scope that will look up all variables from + a derived context. +- Added an ``in`` test that works like the in operator. This can be + used in combination with ``reject`` and ``select``. +- Added ``previtem`` and ``nextitem`` to loop contexts, providing + access to the previous/next item in the loop. If such an item does + not exist, the value is undefined. +- Added ``changed(*values)`` to loop contexts, providing an easy way + of checking whether a value has changed since the last iteration (or + rather since the last call of the method) +- Added a ``namespace`` function that creates a special object which + allows attribute assignment using the ``set`` tag. This can be used + to carry data across scopes, e.g. from a loop body to code that + comes after the loop. +- Added a ``trimmed`` modifier to ``{% trans %}`` to strip linebreaks + and surrounding whitespace. Also added a new policy to enable this + for all ``trans`` blocks. +- The ``random`` filter is no longer incorrectly constant folded and + will produce a new random choice each time the template is rendered. + :pr:`478` +- Added a ``unique`` filter. :pr:`469` +- Added ``min`` and ``max`` filters. :pr:`475` +- Added tests for all comparison operators: ``eq``, ``ne``, ``lt``, + ``le``, ``gt``, ``ge``. :pr:`665` +- ``import`` statement cannot end with a trailing comma. :pr:`617`, + :pr:`618` +- ``indent`` filter will not indent blank lines by default. :pr:`685` +- Add ``reverse`` argument for ``dictsort`` filter. :pr:`692` +- Add a ``NativeEnvironment`` that renders templates to native Python + types instead of strings. :pr:`708` +- Added filter support to the block ``set`` tag. :pr:`489` +- ``tojson`` filter marks output as safe to match documented behavior. + :pr:`718` +- Resolved a bug where getting debug locals for tracebacks could + modify template context. +- Fixed a bug where having many ``{% elif ... %}`` blocks resulted in + a "too many levels of indentation" error. These blocks now compile + to native ``elif ..:`` instead of ``else: if ..:`` :issue:`759` Version 2.9.6 ------------- -(bugfix release, released on April 3rd 2017) +Released 2017-04-03 -- Fixed custom context behavior in fast resolve mode (#675) +- Fixed custom context behavior in fast resolve mode :issue:`675` Version 2.9.5 ------------- -(bugfix release, released on January 28th 2017) - -- Restored the original repr of the internal ``_GroupTuple`` because this - caused issues with ansible and it was an unintended change. (#654) -- Added back support for custom contexts that override the old ``resolve`` - method since it was hard for people to spot that this could cause a - regression. -- Correctly use the buffer for the else block of for loops. This caused - invalid syntax errors to be caused on 2.x and completely wrong behavior - on Python 3 (#669) -- Resolve an issue where the ``{% extends %}`` tag could not be used with - async environments. (#668) -- Reduce memory footprint slightly by reducing our unicode database dump - we use for identifier matching on Python 3 (#666) -- Fixed autoescaping not working for macros in async compilation mode. (#671) +Released 2017-01-28 + +- Restored the original repr of the internal ``_GroupTuple`` because + this caused issues with ansible and it was an unintended change. + :issue:`654` +- Added back support for custom contexts that override the old + ``resolve`` method since it was hard for people to spot that this + could cause a regression. +- Correctly use the buffer for the else block of for loops. This + caused invalid syntax errors to be caused on 2.x and completely + wrong behavior on Python 3 :issue:`669` +- Resolve an issue where the ``{% extends %}`` tag could not be used + with async environments. :issue:`668` +- Reduce memory footprint slightly by reducing our unicode database + dump we use for identifier matching on Python 3 :issue:`666` +- Fixed autoescaping not working for macros in async compilation mode. + :issue:`671` Version 2.9.4 ------------- -(bugfix release, released on January 10th 2017) +Released 2017-01-10 -- Solved some warnings for string literals. (#646) -- Increment the bytecode cache version which was not done due to an - oversight before. -- Corrected bad code generation and scoping for filtered loops. (#649) -- Resolved an issue where top-level output silencing after known extend - blocks could generate invalid code when blocks where contained in if - statements. (#651) -- Made the ``truncate.leeway`` default configurable to improve compatibility - with older templates. +- Solved some warnings for string literals. :issue:`646` +- Increment the bytecode cache version which was not done due to an + oversight before. +- Corrected bad code generation and scoping for filtered loops. + :issue:`649` +- Resolved an issue where top-level output silencing after known + extend blocks could generate invalid code when blocks where + contained in if statements. :issue:`651` +- Made the ``truncate.leeway`` default configurable to improve + compatibility with older templates. Version 2.9.3 ------------- -(bugfix release, released on January 8th 2017) - -- Restored the use of blocks in macros to the extend that was possible - before. On Python 3 it would render a generator repr instead of - the block contents. (#645) -- Set a consistent behavior for assigning of variables in inner scopes - when the variable is also read from an outer scope. This now sets the - intended behavior in all situations however it does not restore the - old behavior where limited assignments to outer scopes was possible. - For more information and a discussion see #641 -- Resolved an issue where ``block scoped`` would not take advantage of the - new scoping rules. In some more exotic cases a variable overriden in a - local scope would not make it into a block. -- Change the code generation of the ``with`` statement to be in line with the - new scoping rules. This resolves some unlikely bugs in edge cases. This - also introduces a new internal ``With`` node that can be used by extensions. +Released 2017-01-08 + +- Restored the use of blocks in macros to the extend that was possible + before. On Python 3 it would render a generator repr instead of the + block contents. :issue:`645` +- Set a consistent behavior for assigning of variables in inner scopes + when the variable is also read from an outer scope. This now sets + the intended behavior in all situations however it does not restore + the old behavior where limited assignments to outer scopes was + possible. For more information and a discussion see :issue:`641` +- Resolved an issue where ``block scoped`` would not take advantage of + the new scoping rules. In some more exotic cases a variable + overriden in a local scope would not make it into a block. +- Change the code generation of the ``with`` statement to be in line + with the new scoping rules. This resolves some unlikely bugs in edge + cases. This also introduces a new internal ``With`` node that can be + used by extensions. Version 2.9.2 ------------- -(bugfix release, released on January 8th 2017) +Released 2017-01-08 -- Fixed a regression that caused for loops to not be able to use the same - variable for the target as well as source iterator. (#640) -- Add support for a previously unknown behavior of macros. It used to be - possible in some circumstances to explicitly provide a caller argument - to macros. While badly buggy and unintended it turns out that this is a - common case that gets copy pasted around. To not completely break backwards - compatibility with the most common cases it's now possible to provide an - explicit keyword argument for caller if it's given an explicit default. - (#642) +- Fixed a regression that caused for loops to not be able to use the + same variable for the target as well as source iterator. + :issue:`640` +- Add support for a previously unknown behavior of macros. It used to + be possible in some circumstances to explicitly provide a caller + argument to macros. While badly buggy and unintended it turns out + that this is a common case that gets copy pasted around. To not + completely break backwards compatibility with the most common cases + it's now possible to provide an explicit keyword argument for caller + if it's given an explicit default. :issue:`642` Version 2.9.1 ------------- -(bugfix release, released on January 7th 2017) +Released 2017-01-07 -- Resolved a regression with call block scoping for macros. Nested caller - blocks that used the same identifiers as outer macros could refer to the - wrong variable incorrectly. +- Resolved a regression with call block scoping for macros. Nested + caller blocks that used the same identifiers as outer macros could + refer to the wrong variable incorrectly. Version 2.9 ----------- -(codename Derivation, released on January 7th 2017) - -- Change cache key definition in environment. This fixes a performance - regression introduced in 2.8. -- Added support for ``generator_stop`` on supported Python versions - (Python 3.5 and later) -- Corrected a long standing issue with operator precedence of math operations - not being what was expected. -- Added support for Python 3.6 async iterators through a new async mode. -- Added policies for filter defaults and similar things. -- urlize now sets "rel noopener" by default. -- Support attribute fallback for old-style classes in 2.x. -- Support toplevel set statements in extend situations. -- Restored behavior of Cycler for Python 3 users. -- Subtraction now follows the same behavior as other operators on undefined - values. -- ``map`` and friends will now give better error messages if you forgot to - quote the parameter. -- Depend on MarkupSafe 0.23 or higher. -- Improved the ``truncate`` filter to support better truncation in case - the string is barely truncated at all. -- Change the logic for macro autoescaping to be based on the runtime - autoescaping information at call time instead of macro define time. -- Ported a modified version of the ``tojson`` filter from Flask to Jinja2 - and hooked it up with the new policy framework. -- Block sets are now marked ``safe`` by default. -- On Python 2 the asciification of ASCII strings can now be disabled with - the ``compiler.ascii_str`` policy. -- Tests now no longer accept an arbitrary expression as first argument but - a restricted one. This means that you can now properly use multiple - tests in one expression without extra parentheses. In particular you can - now write ``foo is divisibleby 2 or foo is divisibleby 3`` - as you would expect. -- Greatly changed the scoping system to be more consistent with what template - designers and developers expect. There is now no more magic difference - between the different include and import constructs. Context is now always - propagated the same way. The only remaining differences is the defaults - for ``with context`` and ``without context``. -- The ``with`` and ``autoescape`` tags are now built-in. -- Added the new ``select_autoescape`` function which helps configuring better - autoescaping easier. -- Fixed a runtime error in the sandbox when attributes of async generators - were accessed. + +Released 2017-01-07, codename Derivation + +- Change cache key definition in environment. This fixes a performance + regression introduced in 2.8. +- Added support for ``generator_stop`` on supported Python versions + (Python 3.5 and later) +- Corrected a long standing issue with operator precedence of math + operations not being what was expected. +- Added support for Python 3.6 async iterators through a new async + mode. +- Added policies for filter defaults and similar things. +- Urlize now sets "rel noopener" by default. +- Support attribute fallback for old-style classes in 2.x. +- Support toplevel set statements in extend situations. +- Restored behavior of Cycler for Python 3 users. +- Subtraction now follows the same behavior as other operators on + undefined values. +- ``map`` and friends will now give better error messages if you + forgot to quote the parameter. +- Depend on MarkupSafe 0.23 or higher. +- Improved the ``truncate`` filter to support better truncation in + case the string is barely truncated at all. +- Change the logic for macro autoescaping to be based on the runtime + autoescaping information at call time instead of macro define time. +- Ported a modified version of the ``tojson`` filter from Flask to + Jinja2 and hooked it up with the new policy framework. +- Block sets are now marked ``safe`` by default. +- On Python 2 the asciification of ASCII strings can now be disabled + with the ``compiler.ascii_str`` policy. +- Tests now no longer accept an arbitrary expression as first argument + but a restricted one. This means that you can now properly use + multiple tests in one expression without extra parentheses. In + particular you can now write ``foo is divisibleby 2 or foo is + divisibleby 3`` as you would expect. +- Greatly changed the scoping system to be more consistent with what + template designers and developers expect. There is now no more magic + difference between the different include and import constructs. + Context is now always propagated the same way. The only remaining + differences is the defaults for ``with context`` and ``without + context``. +- The ``with`` and ``autoescape`` tags are now built-in. +- Added the new ``select_autoescape`` function which helps configuring + better autoescaping easier. +- Fixed a runtime error in the sandbox when attributes of async + generators were accessed. Version 2.8.1 ------------- -(bugfix release, released on December 29th 2016) +Released 2016-12-29 -- Fixed the ``for_qs`` flag for ``urlencode``. -- Fixed regression when applying ``int`` to non-string values. -- SECURITY: if the sandbox mode is used format expressions are now sandboxed - with the same rules as in Jinja. This solves various information leakage - problems that can occur with format strings. +- Fixed the ``for_qs`` flag for ``urlencode``. +- Fixed regression when applying ``int`` to non-string values. +- SECURITY: if the sandbox mode is used format expressions are now + sandboxed with the same rules as in Jinja. This solves various + information leakage problems that can occur with format strings. Version 2.8 ----------- -(codename Replacement, released on July 26th 2015) - -- Added ``target`` parameter to urlize function. -- Added support for ``followsymlinks`` to the file system loader. -- The truncate filter now counts the length. -- Added equalto filter that helps with select filters. -- Changed cache keys to use absolute file names if available - instead of load names. -- Fixed loop length calculation for some iterators. -- Changed how Jinja2 enforces strings to be native strings in - Python 2 to work when people break their default encoding. -- Added :func:`make_logging_undefined` which returns an undefined - object that logs failures into a logger. -- If unmarshalling of cached data fails the template will be - reloaded now. -- Implemented a block ``set`` tag. -- Default cache size was increased to 400 from a low 50. -- Fixed ``is number`` test to accept long integers in all Python versions. -- Changed ``is number`` to accept Decimal as a number. -- Added a check for default arguments followed by non-default arguments. This - change makes ``{% macro m(x, y=1, z) %}...{% endmacro %}`` a syntax error. - The previous behavior for this code was broken anyway (resulting in the - default value being applied to ``y``). -- Add ability to use custom subclasses of ``jinja2.compiler.CodeGenerator`` and - ``jinja2.runtime.Context`` by adding two new attributes to the environment - (``code_generator_class`` and ``context_class``) (pull request ``#404``). -- added support for context/environment/evalctx decorator functions on - the finalize callback of the environment. -- escape query strings for urlencode properly. Previously slashes were not - escaped in that place. -- Add 'base' parameter to 'int' filter. +Released 2015-07-26, codename Replacement + +- Added ``target`` parameter to urlize function. +- Added support for ``followsymlinks`` to the file system loader. +- The truncate filter now counts the length. +- Added equalto filter that helps with select filters. +- Changed cache keys to use absolute file names if available instead + of load names. +- Fixed loop length calculation for some iterators. +- Changed how Jinja2 enforces strings to be native strings in Python 2 + to work when people break their default encoding. +- Added :func:`make_logging_undefined` which returns an undefined + object that logs failures into a logger. +- If unmarshalling of cached data fails the template will be reloaded + now. +- Implemented a block ``set`` tag. +- Default cache size was increased to 400 from a low 50. +- Fixed ``is number`` test to accept long integers in all Python + versions. +- Changed ``is number`` to accept Decimal as a number. +- Added a check for default arguments followed by non-default + arguments. This change makes ``{% macro m(x, y=1, z) %}`` a syntax + error. The previous behavior for this code was broken anyway + (resulting in the default value being applied to ``y``). +- Add ability to use custom subclasses of + ``jinja2.compiler.CodeGenerator`` and ``jinja2.runtime.Context`` by + adding two new attributes to the environment + (``code_generator_class`` and ``context_class``) (pull request + ``:issue:`404```). +- Added support for context/environment/evalctx decorator functions on + the finalize callback of the environment. +- Escape query strings for urlencode properly. Previously slashes were + not escaped in that place. +- Add 'base' parameter to 'int' filter. Version 2.7.3 ------------- -(bugfix release, released on June 6th 2014) +Released 2014-06-06 -- Security issue: Corrected the security fix for the cache folder. This - fix was provided by RedHat. +- Security issue: Corrected the security fix for the cache folder. + This fix was provided by RedHat. Version 2.7.2 ------------- -(bugfix release, released on January 10th 2014) +Released 2014-01-10 -- Prefix loader was not forwarding the locals properly to - inner loaders. This is now fixed. -- Security issue: Changed the default folder for the filesystem cache to be - user specific and read and write protected on UNIX systems. See - `Debian bug 734747`_ for more information. +- Prefix loader was not forwarding the locals properly to inner + loaders. This is now fixed. +- Security issue: Changed the default folder for the filesystem cache + to be user specific and read and write protected on UNIX systems. + See `Debian bug 734747`_ for more information. -.. _Debian bug 734747: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=734747 +.. _Debian bug 734747: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=734747 Version 2.7.1 ------------- -(bugfix release, released on August 7th 2013) +Released 2013-08-07 -- Fixed a bug with ``call_filter`` not working properly on environment - and context filters. -- Fixed lack of Python 3 support for bytecode caches. -- Reverted support for defining blocks in included templates as this - broke existing templates for users. -- Fixed some warnings with hashing of undefineds and nodes if Python - is run with warnings for Python 3. -- Added support for properly hashing undefined objects. -- Fixed a bug with the title filter not working on already uppercase - strings. +- Fixed a bug with ``call_filter`` not working properly on environment + and context filters. +- Fixed lack of Python 3 support for bytecode caches. +- Reverted support for defining blocks in included templates as this + broke existing templates for users. +- Fixed some warnings with hashing of undefineds and nodes if Python + is run with warnings for Python 3. +- Added support for properly hashing undefined objects. +- Fixed a bug with the title filter not working on already uppercase + strings. Version 2.7 ----------- -(codename Translation, released on May 20th 2013) - -- Choice and prefix loaders now dispatch source and template lookup - separately in order to work in combination with module loaders as - advertised. -- Fixed filesizeformat. -- Added a non-silent option for babel extraction. -- Added ``urlencode`` filter that automatically quotes values for - URL safe usage with utf-8 as only supported encoding. If applications - want to change this encoding they can override the filter. -- Added ``keep-trailing-newline`` configuration to environments and - templates to optionally preserve the final trailing newline. -- Accessing ``last`` on the loop context no longer causes the iterator - to be consumed into a list. -- Python requirement changed: 2.6, 2.7 or >= 3.3 are required now, - supported by same source code, using the "six" compatibility library. -- Allow ``contextfunction`` and other decorators to be applied to ``__call__``. -- Added support for changing from newline to different signs in the ``wordwrap`` - filter. -- Added support for ignoring memcache errors silently. -- Added support for keeping the trailing newline in templates. -- Added finer grained support for stripping whitespace on the left side - of blocks. -- Added ``map``, ``select``, ``reject``, ``selectattr`` and ``rejectattr`` - filters. -- Added support for ``loop.depth`` to figure out how deep inside a recursive - loop the code is. -- Disabled py_compile for pypy and python 3. +Released 2013-05-20, codename Translation + +- Choice and prefix loaders now dispatch source and template lookup + separately in order to work in combination with module loaders as + advertised. +- Fixed filesizeformat. +- Added a non-silent option for babel extraction. +- Added ``urlencode`` filter that automatically quotes values for URL + safe usage with utf-8 as only supported encoding. If applications + want to change this encoding they can override the filter. +- Added ``keep-trailing-newline`` configuration to environments and + templates to optionally preserve the final trailing newline. +- Accessing ``last`` on the loop context no longer causes the iterator + to be consumed into a list. +- Python requirement changed: 2.6, 2.7 or >= 3.3 are required now, + supported by same source code, using the "six" compatibility + library. +- Allow ``contextfunction`` and other decorators to be applied to + ``__call__``. +- Added support for changing from newline to different signs in the + ``wordwrap`` filter. +- Added support for ignoring memcache errors silently. +- Added support for keeping the trailing newline in templates. +- Added finer grained support for stripping whitespace on the left + side of blocks. +- Added ``map``, ``select``, ``reject``, ``selectattr`` and + ``rejectattr`` filters. +- Added support for ``loop.depth`` to figure out how deep inside a + recursive loop the code is. +- Disabled py_compile for pypy and python 3. Version 2.6 ----------- -(codename Convolution, released on July 24th 2011) - -- internal attributes now raise an internal attribute error now instead - of returning an undefined. This fixes problems when passing undefined - objects to Python semantics expecting APIs. -- traceback support now works properly for PyPy. (Tested with 1.4) -- implemented operator intercepting for sandboxed environments. This - allows application developers to disable builtin operators for better - security. (For instance limit the mathematical operators to actual - integers instead of longs) -- groupby filter now supports dotted notation for grouping by attributes - of attributes. -- scoped blocks now properly treat toplevel assignments and imports. - Previously an import suddenly "disappeared" in a scoped block. -- automatically detect newer Python interpreter versions before loading code - from bytecode caches to prevent segfaults on invalid opcodes. The segfault - in earlier Jinja2 versions here was not a Jinja2 bug but a limitation in - the underlying Python interpreter. If you notice Jinja2 segfaulting in - earlier versions after an upgrade of the Python interpreter you don't have - to upgrade, it's enough to flush the bytecode cache. This just no longer - makes this necessary, Jinja2 will automatically detect these cases now. -- the sum filter can now sum up values by attribute. This is a backwards - incompatible change. The argument to the filter previously was the - optional starting index which defaults to zero. This now became the - second argument to the function because it's rarely used. -- like sum, sort now also makes it possible to order items by attribute. -- like sum and sort, join now also is able to join attributes of objects - as string. -- the internal eval context now has a reference to the environment. -- added a mapping test to see if an object is a dict or an object with - a similar interface. +Released 2011-07-24, codename Convolution + +- Internal attributes now raise an internal attribute error now + instead of returning an undefined. This fixes problems when passing + undefined objects to Python semantics expecting APIs. +- Traceback support now works properly for PyPy. (Tested with 1.4) +- Implemented operator intercepting for sandboxed environments. This + allows application developers to disable builtin operators for + better security. (For instance limit the mathematical operators to + actual integers instead of longs) +- Groupby filter now supports dotted notation for grouping by + attributes of attributes. +- Scoped blocks now properly treat toplevel assignments and imports. + Previously an import suddenly "disappeared" in a scoped block. +- Automatically detect newer Python interpreter versions before + loading code from bytecode caches to prevent segfaults on invalid + opcodes. The segfault in earlier Jinja2 versions here was not a + Jinja2 bug but a limitation in the underlying Python interpreter. If + you notice Jinja2 segfaulting in earlier versions after an upgrade + of the Python interpreter you don't have to upgrade, it's enough to + flush the bytecode cache. This just no longer makes this necessary, + Jinja2 will automatically detect these cases now. +- The sum filter can now sum up values by attribute. This is a + backwards incompatible change. The argument to the filter previously + was the optional starting index which defaults to zero. This now + became the second argument to the function because it's rarely used. +- Like sum, sort now also makes it possible to order items by + attribute. +- Like sum and sort, join now also is able to join attributes of + objects as string. +- The internal eval context now has a reference to the environment. +- Added a mapping test to see if an object is a dict or an object with + a similar interface. Version 2.5.5 ------------- -(re-release of 2.5.4 with built documentation removed for filesize. - Released on October 18th 2010) +Released 2010-10-18 -- built documentation is no longer part of release. +- Built documentation is no longer part of release. Version 2.5.4 ------------- -(bugfix release, released on October 17th 2010) +Released 2010-10-17 -- Fixed extensions not loading properly with overlays. -- Work around a bug in cpython for the debugger that causes segfaults - on 64bit big-endian architectures. +- Fixed extensions not loading properly with overlays. +- Work around a bug in cpython for the debugger that causes segfaults + on 64bit big-endian architectures. Version 2.5.3 ------------- -(bugfix release, released on October 17th 2010) +Released 2010-10-17 -- fixed an operator precedence error introduced in 2.5.2. Statements - like "-foo.bar" had their implicit parentheses applied around the - first part of the expression ("(-foo).bar") instead of the more - correct "-(foo.bar)". +- Fixed an operator precedence error introduced in 2.5.2. Statements + like "-foo.bar" had their implicit parentheses applied around the + first part of the expression ("(-foo).bar") instead of the more + correct "-(foo.bar)". Version 2.5.2 ------------- -(bugfix release, released on August 18th 2010) -- improved setup.py script to better work with assumptions people - might still have from it (``--with-speedups``). -- fixed a packaging error that excluded the new debug support. +Released 2010-08-18 + +- Improved setup.py script to better work with assumptions people + might still have from it (``--with-speedups``). +- Fixed a packaging error that excluded the new debug support. Version 2.5.1 ------------- -(bugfix release, released on August 17th 2010) +Released 2010-08-17 -- StopIteration exceptions raised by functions called from templates - are now intercepted and converted to undefineds. This solves a - lot of debugging grief. (StopIteration is used internally to - abort template execution) -- improved performance of macro calls slightly. -- babel extraction can now properly extract newstyle gettext calls. -- using the variable ``num`` in newstyle gettext for something else - than the pluralize count will no longer raise a :exc:`KeyError`. -- removed builtin markup class and switched to markupsafe. For backwards - compatibility the pure Python implementation still exists but is - pulled from markupsafe by the Jinja2 developers. The debug support - went into a separate feature called "debugsupport" and is disabled - by default because it is only relevant for Python 2.4 -- fixed an issue with unary operators having the wrong precedence. +- StopIteration exceptions raised by functions called from templates + are now intercepted and converted to undefineds. This solves a lot + of debugging grief. (StopIteration is used internally to abort + template execution) +- Improved performance of macro calls slightly. +- Babel extraction can now properly extract newstyle gettext calls. +- Using the variable ``num`` in newstyle gettext for something else + than the pluralize count will no longer raise a :exc:`KeyError`. +- Removed builtin markup class and switched to markupsafe. For + backwards compatibility the pure Python implementation still exists + but is pulled from markupsafe by the Jinja2 developers. The debug + support went into a separate feature called "debugsupport" and is + disabled by default because it is only relevant for Python 2.4 +- Fixed an issue with unary operators having the wrong precedence. Version 2.5 ----------- -(codename Incoherence, released on May 29th 2010) +Released 2010-05-29, codename Incoherence -- improved the sort filter (should have worked like this for a - long time) by adding support for case insensitive searches. -- fixed a bug for getattribute constant folding. -- support for newstyle gettext translations which result in a - nicer in-template user interface and more consistent - catalogs. (:ref:`newstyle-gettext`) -- it's now possible to register extensions after an environment - was created. +- Improved the sort filter (should have worked like this for a long + time) by adding support for case insensitive searches. +- Fixed a bug for getattribute constant folding. +- Support for newstyle gettext translations which result in a nicer + in-template user interface and more consistent catalogs. + (:ref:`newstyle-gettext`) +- It's now possible to register extensions after an environment was + created. Version 2.4.1 ------------- -(bugfix release, released on April 20th 2010) +Released 2010-04-20 -- fixed an error reporting bug for undefineds. +- Fixed an error reporting bug for undefined. Version 2.4 ----------- -(codename Correlation, released on April 13th 2010) +Released 2010-04-13, codename Correlation -- the environment template loading functions now transparently - pass through a template object if it was passed to it. This - makes it possible to import or extend from a template object - that was passed to the template. -- added a :class:`ModuleLoader` that can load templates from - precompiled sources. The environment now features a method - to compile the templates from a configured loader into a zip - file or folder. -- the _speedups C extension now supports Python 3. -- added support for autoescaping toggling sections and support - for evaluation contexts (:ref:`eval-context`). -- extensions have a priority now. +- The environment template loading functions now transparently pass + through a template object if it was passed to it. This makes it + possible to import or extend from a template object that was passed + to the template. +- Added a :class:`ModuleLoader` that can load templates from + precompiled sources. The environment now features a method to + compile the templates from a configured loader into a zip file or + folder. +- The _speedups C extension now supports Python 3. +- Added support for autoescaping toggling sections and support for + evaluation contexts (:ref:`eval-context`). +- Extensions have a priority now. Version 2.3.1 ------------- -(bugfix release, released on February 19th 2010) +Released 2010-02-19 -- fixed an error reporting bug on all python versions -- fixed an error reporting bug on Python 2.4 +- Fixed an error reporting bug on all python versions +- Fixed an error reporting bug on Python 2.4 Version 2.3 ----------- -(codename 3000 Pythons, released on February 10th 2010) - -- fixes issue with code generator that causes unbound variables - to be generated if set was used in if-blocks and other small - identifier problems. -- include tags are now able to select between multiple templates - and take the first that exists, if a list of templates is - given. -- fixed a problem with having call blocks in outer scopes that - have an argument that is also used as local variable in an - inner frame (#360). -- greatly improved error message reporting (#339) -- implicit tuple expressions can no longer be totally empty. - This change makes ``{% if %}...{% endif %}`` a syntax error - now. (#364) -- added support for translator comments if extracted via babel. -- added with-statement extension. -- experimental Python 3 support. +Released 2010-02-10, codename 3000 Pythons + +- Fixes issue with code generator that causes unbound variables to be + generated if set was used in if-blocks and other small identifier + problems. +- Include tags are now able to select between multiple templates and + take the first that exists, if a list of templates is given. +- Fixed a problem with having call blocks in outer scopes that have an + argument that is also used as local variable in an inner frame + :issue:`360`. +- Greatly improved error message reporting :pr:`339` +- Implicit tuple expressions can no longer be totally empty. This + change makes ``{% if %}`` a syntax error now. :issue:`364` +- Added support for translator comments if extracted via babel. +- Added with-statement extension. +- Experimental Python 3 support. Version 2.2.1 ------------- -(bugfix release, released on September 14th 2009) +Released 2009-09-14 -- fixes some smaller problems for Jinja2 on Jython. +- Fixes some smaller problems for Jinja2 on Jython. Version 2.2 ----------- -(codename Kong, released on September 13th 2009) - -- Include statements can now be marked with ``ignore missing`` to skip - non existing templates. -- Priority of ``not`` raised. It's now possible to write `not foo in bar` - as an alias to `foo not in bar` like in python. Previously the grammar - required parentheses (`not (foo in bar)`) which was odd. -- Fixed a bug that caused syntax errors when defining macros or using the - `{% call %}` tag inside loops. -- Fixed a bug in the parser that made ``{{ foo[1, 2] }}`` impossible. -- Made it possible to refer to names from outer scopes in included templates - that were unused in the callers frame (#327) -- Fixed a bug that caused internal errors if names where used as iteration - variable and regular variable *after* the loop if that variable was unused - *before* the loop. (#331) -- Added support for optional ``scoped`` modifier to blocks. -- Added support for line-comments. -- Added the ``meta`` module. -- Renamed (undocumented) attribute "overlay" to "overlayed" on the - environment because it was clashing with a method of the same name. -- speedup extension is now disabled by default. +Released 2009-09-13, codename Kong + +- Include statements can now be marked with ``ignore missing`` to skip + non existing templates. +- Priority of ``not`` raised. It's now possible to write ``not foo in + bar`` as an alias to ``foo not in bar`` like in python. Previously + the grammar required parentheses (``not (foo in bar)``) which was + odd. +- Fixed a bug that caused syntax errors when defining macros or using + the ``{% call %}`` tag inside loops. +- Fixed a bug in the parser that made ``{{ foo[1, 2] }}`` impossible. +- Made it possible to refer to names from outer scopes in included + templates that were unused in the callers frame :issue:`327` +- Fixed a bug that caused internal errors if names where used as + iteration variable and regular variable *after* the loop if that + variable was unused *before* the loop. :pr:`331` +- Added support for optional ``scoped`` modifier to blocks. +- Added support for line-comments. +- Added the ``meta`` module. +- Renamed (undocumented) attribute "overlay" to "overlayed" on the + environment because it was clashing with a method of the same name. +- Speedup extension is now disabled by default. Version 2.1.1 ------------- -(bugfix release, released on December 25th 2008) +Released 2008-12-25 -- Fixed a translation error caused by looping over empty recursive loops. +- Fixed a translation error caused by looping over empty recursive + loops. Version 2.1 ----------- -(codename Yasuzō, released on November 23rd 2008) - -- fixed a bug with nested loops and the special loop variable. Before the - change an inner loop overwrote the loop variable from the outer one after - iteration. -- fixed a bug with the i18n extension that caused the explicit pluralization - block to look up the wrong variable. -- fixed a limitation in the lexer that made ``{{ foo.0.0 }}`` impossible. -- index based subscribing of variables with a constant value returns an - undefined object now instead of raising an index error. This was a bug - caused by eager optimizing. -- the i18n extension looks up ``foo.ugettext`` now followed by ``foo.gettext`` - if an translations object is installed. This makes dealing with custom - translations classes easier. -- fixed a confusing behavior with conditional extending. loops were partially - executed under some conditions even though they were not part of a visible - area. -- added ``sort`` filter that works like ``dictsort`` but for arbitrary sequences. -- fixed a bug with empty statements in macros. -- implemented a bytecode cache system. (:ref:`bytecode-cache`) -- the template context is now weakref-able -- inclusions and imports "with context" forward all variables now, not only - the initial context. -- added a cycle helper called ``cycler``. -- added a joining helper called ``joiner``. -- added a ``compile_expression`` method to the environment that allows compiling - of Jinja expressions into callable Python objects. -- fixed an escaping bug in urlize +Released 2008-11-23, codename Yasuzō + +- Fixed a bug with nested loops and the special loop variable. Before + the change an inner loop overwrote the loop variable from the outer + one after iteration. +- Fixed a bug with the i18n extension that caused the explicit + pluralization block to look up the wrong variable. +- Fixed a limitation in the lexer that made ``{{ foo.0.0 }}`` + impossible. +- Index based subscribing of variables with a constant value returns + an undefined object now instead of raising an index error. This was + a bug caused by eager optimizing. +- The i18n extension looks up ``foo.ugettext`` now followed by + ``foo.gettext`` if an translations object is installed. This makes + dealing with custom translations classes easier. +- Fixed a confusing behavior with conditional extending. loops were + partially executed under some conditions even though they were not + part of a visible area. +- Added ``sort`` filter that works like ``dictsort`` but for arbitrary + sequences. +- Fixed a bug with empty statements in macros. +- Implemented a bytecode cache system. (:ref:`bytecode-cache`) +- The template context is now weakref-able +- Inclusions and imports "with context" forward all variables now, not + only the initial context. +- Added a cycle helper called ``cycler``. +- Added a joining helper called ``joiner``. +- Added a ``compile_expression`` method to the environment that allows + compiling of Jinja expressions into callable Python objects. +- Fixed an escaping bug in urlize Version 2.0 ----------- -(codename jinjavitus, released on July 17th 2008) - -- the subscribing of objects (looking up attributes and items) changed from - slightly. It's now possible to give attributes or items a higher priority - by either using dot-notation lookup or the bracket syntax. This also - changed the AST slightly. ``Subscript`` is gone and was replaced with - :class:`~jinja2.nodes.Getitem` and :class:`~jinja2.nodes.Getattr`. - - For more information see :ref:`the implementation details `. -- added support for preprocessing and token stream filtering for extensions. - This would allow extensions to allow simplified gettext calls in template - data and something similar. -- added :meth:`jinja2.environment.TemplateStream.dump`. -- added missing support for implicit string literal concatenation. - ``{{ "foo" "bar" }}`` is equivalent to ``{{ "foobar" }}`` -- ``else`` is optional for conditional expressions. If not given it evaluates - to ``false``. -- improved error reporting for undefined values by providing a position. -- ``filesizeformat`` filter uses decimal prefixes now per default and can be - set to binary mode with the second parameter. -- fixed bug in finalizer +Released 2008-07-17, codename Jinjavitus + +- The subscribing of objects (looking up attributes and items) changed + from slightly. It's now possible to give attributes or items a + higher priority by either using dot-notation lookup or the bracket + syntax. This also changed the AST slightly. ``Subscript`` is gone + and was replaced with :class:`~jinja2.nodes.Getitem` and + :class:`~jinja2.nodes.Getattr`. For more information see :ref:`the + implementation details `. +- Added support for preprocessing and token stream filtering for + extensions. This would allow extensions to allow simplified gettext + calls in template data and something similar. +- Added :meth:`jinja2.environment.TemplateStream.dump`. +- Added missing support for implicit string literal concatenation. + ``{{ "foo" "bar" }}`` is equivalent to ``{{ "foobar" }}`` +- ``else`` is optional for conditional expressions. If not given it + evaluates to ``false``. +- Improved error reporting for undefined values by providing a + position. +- ``filesizeformat`` filter uses decimal prefixes now per default and + can be set to binary mode with the second parameter. +- Fixed bug in finalizer Version 2.0rc1 -------------- -(no codename, released on June 9th 2008) +Released 2008-06-09 -- first release of Jinja2 +- First release of Jinja2 diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 000000000..bc9be7fb1 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,70 @@ +@Library("shared-jenkins")_ +pipeline { + + agent any + + options { + //Pipeline options + ansiColor('xterm') + timestamps() + buildDiscarder(logRotator(numToKeepStr: "25", artifactNumToKeepStr: "25")) + disableConcurrentBuilds() + } + stages { + + stage('Clean Workspace') { + + steps { + cleanWs() + dir('src') { + checkout scm + } + stash name: 'sources' + script { + GIT_COMMIT = sh(returnStdout:true, script:'cd src; git rev-parse HEAD').trim() + } + } + } + + stage("Build Project") { + + agent { + docker { + image 'python:3.5' + args '-u root:sudo -v /etc/passwd:/etc/passwd -v /etc/group:/etc/group' + } + } + + steps { + unstash 'sources' + echo "Building ${GIT_COMMIT}" + sh ''' + export HOME=$WORKSPACE + export PATH=$HOME/.local/bin:$PATH + pip install --upgrade pip + pip install markupsafe setuptools==30.3.0 + python3 setup.py sdist bdist_wheel + chown -R jenkins:jenkins . + ''' + sh '''pwd; ls; + ''' + stash includes: 'dist/Jinja2*.whl', name: 'wheel_artifacts' + } + } + + stage("Upload artifacts to nexus"){ + steps{ + unstash 'wheel_artifacts' + script { + utilities.uploadPython wheel: 'dist/Jinja2*.whl' + } + } + } + } + + post { + always { + cleanWs cleanWhenFailure: false + } + } +} diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 10145a264..000000000 --- a/LICENSE +++ /dev/null @@ -1,31 +0,0 @@ -Copyright (c) 2009 by the Jinja Team, see AUTHORS for more details. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/LICENSE.rst b/LICENSE.rst new file mode 100644 index 000000000..c37cae49e --- /dev/null +++ b/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2007 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/MANIFEST.in b/MANIFEST.in index 27bf519c1..8cae0c743 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,4 @@ -include AUTHORS CHANGES.rst LICENSE -global-exclude *.py[co] +include CHANGES.rst tox.ini graft artwork graft docs prune docs/_build diff --git a/Makefile b/Makefile deleted file mode 100644 index 3c12a8c97..000000000 --- a/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -test: - py.test tests --tb=short - -develop: - pip install --editable . - -tox-test: - @tox - -release: - python scripts/make-release.py - -upload-docs: - $(MAKE) -C docs html dirhtml latex - $(MAKE) -C docs/_build/latex all-pdf - cd docs/_build/; mv html jinja-docs; zip -r jinja-docs.zip jinja-docs; mv jinja-docs html - scp -r docs/_build/dirhtml/* flow.srv.pocoo.org:/srv/websites/jinja.pocoo.org/docs/ - scp -r docs/_build/latex/Jinja2.pdf flow.srv.pocoo.org:/srv/websites/jinja.pocoo.org/docs/jinja-docs.pdf - scp -r docs/_build/jinja-docs.zip flow.srv.pocoo.org:/srv/websites/jinja.pocoo.org/docs/ - -.PHONY: test diff --git a/README.rst b/README.rst index 8ac573f48..060b19efe 100644 --- a/README.rst +++ b/README.rst @@ -1,19 +1,50 @@ -Jinja2 -~~~~~~ +Jinja +===== -Jinja2 is a template engine written in pure Python. It provides a -`Django`_ inspired non-XML syntax but supports inline expressions and -an optional `sandboxed`_ environment. +Jinja is a fast, expressive, extensible templating engine. Special +placeholders in the template allow writing code similar to Python +syntax. Then the template is passed data to render the final document. -Nutshell --------- +It includes: -Here a small example of a Jinja template: +- Template inheritance and inclusion. +- Define and import macros within templates. +- HTML templates can use autoescaping to prevent XSS from untrusted + user input. +- A sandboxed environment can safely render untrusted templates. +- AsyncIO support for generating templates and calling async + functions. +- I18N support with Babel. +- Templates are compiled to optimized Python code just-in-time and + cached, or can be compiled ahead-of-time. +- Exceptions point to the correct line in templates to make debugging + easier. +- Extensible filters, tests, functions, and even syntax. + +Jinja's philosophy is that while application logic belongs in Python if +possible, it shouldn't make the template designer's job difficult by +restricting functionality too much. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install -U Jinja2 + +.. _pip: https://pip.pypa.io/en/stable/quickstart/ + + +In A Nutshell +------------- .. code-block:: jinja - {% extends 'base.html' %} - {% block title %}Memberlist{% endblock %} + {% extends "base.html" %} + {% block title %}Members{% endblock %} {% block content %}
    {% for user in users %} @@ -22,30 +53,14 @@ Here a small example of a Jinja template:
{% endblock %} -Philosophy ----------- - -Application logic is for the controller, but don't make the template designer's -life difficult by restricting functionality too much. - -For more information visit the new `Jinja2 webpage`_ and `documentation`_. - -The `Jinja2 tip`_ is installable via ``pip`` with ``pip install -https://github.com/pallets/jinja/zipball/master``. - -.. _sandboxed: https://en.wikipedia.org/wiki/Sandbox_(computer_security) -.. _Django: https://www.djangoproject.com/ -.. _Jinja2 webpage: http://jinja.pocoo.org/ -.. _documentation: http://jinja.pocoo.org/docs/ -.. _Jinja2 tip: http://jinja.pocoo.org/docs/intro/#as-a-python-egg-via-easy-install -Builds ------- +Links +----- -+---------------------+------------------------------------------------------------------------------+ -| ``master`` | .. image:: https://travis-ci.org/pallets/jinja.svg?branch=master | -| | :target: https://travis-ci.org/pallets/jinja | -+---------------------+------------------------------------------------------------------------------+ -| ``2.9-maintenance`` | .. image:: https://travis-ci.org/pallets/jinja.svg?branch=2.9-maintenance | -| | :target: https://travis-ci.org/pallets/jinja | -+---------------------+------------------------------------------------------------------------------+ +- Website: https://palletsprojects.com/p/jinja/ +- Documentation: https://jinja.palletsprojects.com/ +- Releases: https://pypi.org/project/Jinja2/ +- Code: https://github.com/pallets/jinja +- Issue tracker: https://github.com/pallets/jinja/issues +- Test status: https://dev.azure.com/pallets/jinja/_build +- Official chat: https://discord.gg/t6rrQZH diff --git a/docs/Makefile b/docs/Makefile index 52d78d9ef..51285967a 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -1,118 +1,19 @@ -# Makefile for Sphinx documentation +# Minimal makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build -PAPER = +SOURCEDIR = . BUILDDIR = _build -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp epub latex changes linkcheck doctest - +# Put it first so that "make" without argument is like "make help". help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Flask.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Flask.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) _build/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/Flask" - @echo "# ln -s _build/devhelp $$HOME/.local/share/devhelp/Flask" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ - "run these through (pdf)latex." - -latexpdf: latex - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex - @echo "Running LaTeX files through pdflatex..." - make -C _build/latex all-pdf - @echo "pdflatex finished; the PDF files are in _build/latex." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." +.PHONY: help Makefile -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/_build/.ignore b/docs/_build/.ignore deleted file mode 100644 index e69de29bb..000000000 diff --git a/docs/_static/.ignore b/docs/_static/.ignore deleted file mode 100644 index e69de29bb..000000000 diff --git a/docs/_static/jinja-small.png b/docs/_static/jinja-logo-sidebar.png similarity index 100% rename from docs/_static/jinja-small.png rename to docs/_static/jinja-logo-sidebar.png diff --git a/docs/_static/jinja-logo.png b/docs/_static/jinja-logo.png new file mode 100644 index 000000000..7f8ca5bbd Binary files /dev/null and b/docs/_static/jinja-logo.png differ diff --git a/docs/_templates/sidebarintro.html b/docs/_templates/sidebarintro.html deleted file mode 100644 index d642d1419..000000000 --- a/docs/_templates/sidebarintro.html +++ /dev/null @@ -1,20 +0,0 @@ -

About Jinja2

-

- Jinja2 is a full featured template engine for Python. It has full unicode - support, an optional integrated sandboxed execution environment, widely used - and BSD licensed. -

-

Other Formats

-

- You can download the documentation in other formats as well: -

- -

Useful Links

- diff --git a/docs/_templates/sidebarlogo.html b/docs/_templates/sidebarlogo.html deleted file mode 100644 index ca211c6a3..000000000 --- a/docs/_templates/sidebarlogo.html +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/docs/_themes/LICENSE b/docs/_themes/LICENSE deleted file mode 100644 index 8daab7ee6..000000000 --- a/docs/_themes/LICENSE +++ /dev/null @@ -1,37 +0,0 @@ -Copyright (c) 2010 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms of the theme, with or -without modification, are permitted provided that the following conditions -are met: - -* Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - -* The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -We kindly ask you to only use these themes in an unmodified manner just -for Flask and Flask-related products, not for unrelated projects. If you -like the visual style and want to use it for your own projects, please -consider making some larger changes to the themes (such as changing -font faces, sizes, colors or margins). - -THIS THEME IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS THEME, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. diff --git a/docs/_themes/README b/docs/_themes/README deleted file mode 100644 index b3292bdff..000000000 --- a/docs/_themes/README +++ /dev/null @@ -1,31 +0,0 @@ -Flask Sphinx Styles -=================== - -This repository contains sphinx styles for Flask and Flask related -projects. To use this style in your Sphinx documentation, follow -this guide: - -1. put this folder as _themes into your docs folder. Alternatively - you can also use git submodules to check out the contents there. -2. add this to your conf.py: - - sys.path.append(os.path.abspath('_themes')) - html_theme_path = ['_themes'] - html_theme = 'flask' - -The following themes exist: - -- 'flask' - the standard flask documentation theme for large - projects -- 'flask_small' - small one-page theme. Intended to be used by - very small addon libraries for flask. - -The following options exist for the flask_small theme: - - [options] - index_logo = '' filename of a picture in _static - to be used as replacement for the - h1 in the index.rst file. - index_logo_height = 120px height of the index logo - github_fork = '' repository name on github for the - "fork me" badge diff --git a/docs/_themes/jinja/layout.html b/docs/_themes/jinja/layout.html deleted file mode 100644 index a0c9cab04..000000000 --- a/docs/_themes/jinja/layout.html +++ /dev/null @@ -1,8 +0,0 @@ -{%- extends "basic/layout.html" %} -{%- block relbar2 %}{% endblock %} -{%- block footer %} - -{%- endblock %} diff --git a/docs/_themes/jinja/relations.html b/docs/_themes/jinja/relations.html deleted file mode 100644 index 3bbcde85b..000000000 --- a/docs/_themes/jinja/relations.html +++ /dev/null @@ -1,19 +0,0 @@ -

Related Topics

- diff --git a/docs/_themes/jinja/static/jinja.css_t b/docs/_themes/jinja/static/jinja.css_t deleted file mode 100644 index 3291ba6fd..000000000 --- a/docs/_themes/jinja/static/jinja.css_t +++ /dev/null @@ -1,396 +0,0 @@ -/* - * jinja.css_t - * ~~~~~~~~~~~ - * - * :copyright: Copyright 2011 by Armin Ronacher. - * :license: Flask Design License, see LICENSE for details. - */ - -@import url(http://fonts.googleapis.com/css?family=Crimson+Text); - -{% set page_width = '940px' %} -{% set sidebar_width = '220px' %} -{% set font_family = 'Georgia, serif' %} -{% set header_font_family = 'Crimson Text, ' ~ font_family %} - -@import url("basic.css"); - -/* -- page layout ----------------------------------------------------------- */ - -body { - font-family: {{ font_family }}; - font-size: 17px; - background-color: white; - color: #000; - margin: 0; - padding: 0; -} - -div.document { - width: {{ page_width }}; - margin: 30px auto 0 auto; -} - -div.documentwrapper { - float: left; - width: 100%; -} - -div.bodywrapper { - margin: 0 0 0 {{ sidebar_width }}; -} - -div.sphinxsidebar { - width: {{ sidebar_width }}; -} - -hr { - border: 1px solid #B1B4B6; -} - -div.body { - background-color: #ffffff; - color: #3E4349; - padding: 0 30px 0 30px; -} - -img.floatingflask { - padding: 0 0 10px 10px; - float: right; -} - -div.footer { - width: {{ page_width }}; - margin: 20px auto 30px auto; - font-size: 14px; - color: #888; - text-align: right; -} - -div.footer a { - color: #888; -} - -div.related { - display: none; -} - -div.sphinxsidebar a { - color: #444; - text-decoration: none; - border-bottom: 1px dotted #999; -} - -div.sphinxsidebar a:hover { - border-bottom: 1px solid #999; -} - -div.sphinxsidebar { - font-size: 15px; - line-height: 1.5; -} - -div.sphinxsidebarwrapper { - padding: 18px 10px; -} - -div.sphinxsidebarwrapper p.logo { - padding: 0 0 20px 0; - margin: 0; - text-align: center; -} - -div.sphinxsidebar h3, -div.sphinxsidebar h4 { - font-family: {{ font_family }}; - color: #444; - font-size: 24px; - font-weight: normal; - margin: 0 0 5px 0; - padding: 0; -} - -div.sphinxsidebar h4 { - font-size: 20px; -} - -div.sphinxsidebar h3 a { - color: #444; -} - -div.sphinxsidebar p.logo a, -div.sphinxsidebar h3 a, -div.sphinxsidebar p.logo a:hover, -div.sphinxsidebar h3 a:hover { - border: none; -} - -div.sphinxsidebar p { - color: #555; - margin: 10px 0; -} - -div.sphinxsidebar ul { - margin: 10px 0; - padding: 0; - color: #000; -} - -div.sphinxsidebar input { - border: 1px solid #ccc; - font-family: {{ font_family }}; - font-size: 14px; -} - -div.sphinxsidebar form.search input[name="q"] { - width: 130px; -} - -/* -- body styles ----------------------------------------------------------- */ - -a { - color: #aa0000; - text-decoration: underline; -} - -a:hover { - color: #dd0000; - text-decoration: underline; -} - -div.body h1, -div.body h2, -div.body h3, -div.body h4, -div.body h5, -div.body h6 { - font-family: {{ header_font_family }}; - font-weight: normal; - margin: 30px 0px 10px 0px; - padding: 0; - color: black; -} - -div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; } -div.body h2 { font-size: 180%; } -div.body h3 { font-size: 150%; } -div.body h4 { font-size: 130%; } -div.body h5 { font-size: 100%; } -div.body h6 { font-size: 100%; } - -a.headerlink { - color: #ddd; - padding: 0 4px; - text-decoration: none; -} - -a.headerlink:hover { - color: #444; - background: #eaeaea; -} - -div.body p, div.body dd, div.body li { - line-height: 1.4em; -} - -div.admonition { - background: #fafafa; - margin: 20px -30px; - padding: 10px 30px; - border-top: 1px solid #ccc; - border-bottom: 1px solid #ccc; -} - -div.admonition tt.xref, div.admonition a tt { - border-bottom: 1px solid #fafafa; -} - -dd div.admonition { - margin-left: -60px; - padding-left: 60px; -} - -div.admonition p.admonition-title { - font-family: {{ font_family }}; - font-weight: normal; - font-size: 24px; - margin: 0 0 10px 0; - padding: 0; - line-height: 1; -} - -div.admonition p.last { - margin-bottom: 0; -} - -div.highlight { - background-color: white; -} - -dt:target, .highlight { - background: #FAF3E8; -} - -div.note { - background-color: #eee; - border: 1px solid #ccc; -} - -div.seealso { - background-color: #ffc; - border: 1px solid #ff6; -} - -div.topic { - background-color: #eee; -} - -p.admonition-title { - display: inline; -} - -p.admonition-title:after { - content: ":"; -} - -pre, tt { - font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace; - font-size: 0.85em; -} - -img.screenshot { -} - -tt.descname, tt.descclassname { - font-size: 0.95em; -} - -tt.descname { - padding-right: 0.08em; -} - -img.screenshot { - -moz-box-shadow: 2px 2px 4px #eee; - -webkit-box-shadow: 2px 2px 4px #eee; - box-shadow: 2px 2px 4px #eee; -} - -table.docutils { - border: 1px solid #888; - -moz-box-shadow: 2px 2px 4px #eee; - -webkit-box-shadow: 2px 2px 4px #eee; - box-shadow: 2px 2px 4px #eee; -} - -table.docutils td, table.docutils th { - border: 1px solid #888; - padding: 0.25em 0.7em; -} - -table.field-list, table.footnote { - border: none; - -moz-box-shadow: none; - -webkit-box-shadow: none; - box-shadow: none; -} - -table.footnote { - margin: 15px 0; - width: 100%; - border: 1px solid #eee; - background: #fdfdfd; - font-size: 0.9em; -} - -table.footnote + table.footnote { - margin-top: -15px; - border-top: none; -} - -table.field-list th { - padding: 0 0.8em 0 0; -} - -table.field-list td { - padding: 0; -} - -table.footnote td.label { - width: 0px; - padding: 0.3em 0 0.3em 0.5em; -} - -table.footnote td { - padding: 0.3em 0.5em; -} - -dl { - margin: 0; - padding: 0; -} - -dl dd { - margin-left: 30px; -} - -blockquote { - margin: 0 0 0 30px; - padding: 0; -} - -ul, ol { - margin: 10px 0 10px 30px; - padding: 0; -} - -pre { - background: #eee; - padding: 7px 30px; - margin: 15px -30px; - line-height: 1.3em; -} - -dl pre, blockquote pre, li pre { - margin-left: -60px; - padding-left: 60px; -} - -dl dl pre { - margin-left: -90px; - padding-left: 90px; -} - -tt { - background-color: #E8EFF0; - color: #222; - /* padding: 1px 2px; */ -} - -tt.xref, a tt { - background-color: #E8EFF0; - border-bottom: 1px solid white; -} - -a.reference { - text-decoration: none; - border-bottom: 1px dotted #bb0000; -} - -a.reference:hover { - border-bottom: 1px solid #dd0000; -} - -a.footnote-reference { - text-decoration: none; - font-size: 0.7em; - vertical-align: top; - border-bottom: 1px dotted #bb0000; -} - -a.footnote-reference:hover { - border-bottom: 1px solid #dd0000; -} - -a:hover tt { - background: #EEE; -} diff --git a/docs/_themes/jinja/theme.conf b/docs/_themes/jinja/theme.conf deleted file mode 100644 index 10c7e56e8..000000000 --- a/docs/_themes/jinja/theme.conf +++ /dev/null @@ -1,3 +0,0 @@ -[theme] -inherit = basic -stylesheet = jinja.css diff --git a/docs/api.rst b/docs/api.rst index fedc1c73d..3f56e5ffd 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -19,7 +19,7 @@ Even if you are creating templates from strings by using the constructor of albeit a shared one. Most applications will create one :class:`Environment` object on application -initialization and use that to load templates. In some cases however, it's +initialization and use that to load templates. In some cases however, it's useful to have multiple environments side by side, if different configurations are in use. @@ -46,7 +46,7 @@ To load a template from this environment you just have to call the To render it with some variables, just call the :meth:`render` method:: - print template.render(the='variables', go='here') + print(template.render(the='variables', go='here')) Using a template loader rather than passing strings to :class:`Template` or :meth:`Environment.from_string` has multiple advantages. Besides being @@ -114,7 +114,7 @@ for everything else `unicode`: u'f\xf6\xf6' -.. _Unicode documentation: https://docs.python.org/dev/howto/unicode.html +.. _Unicode documentation: https://docs.python.org/3/howto/unicode.html High Level API -------------- @@ -213,7 +213,7 @@ useful if you want to dig deeper into Jinja2 or :ref:`develop extensions For a more complex example you can provide a hint. For example the :func:`first` filter creates an undefined object that way:: - return environment.undefined('no first item, sequence was empty') + return environment.undefined('no first item, sequence was empty') If it the `name` or `obj` is known (for example because an attribute was accessed) it should be passed to the undefined object, even if @@ -834,11 +834,11 @@ Here a simple test that checks if a variable is a prime number:: def is_prime(n): if n == 2: return True - for i in xrange(2, int(math.ceil(math.sqrt(n))) + 1): + for i in range(2, int(math.ceil(math.sqrt(n))) + 1): if n % i == 0: return False return True - + You can register it on the template environment by updating the :attr:`~Environment.tests` dict on the environment:: diff --git a/docs/cache_extension.py b/docs/cache_extension.py index ccdefa2ff..992b5951c 100644 --- a/docs/cache_extension.py +++ b/docs/cache_extension.py @@ -4,7 +4,7 @@ class FragmentCacheExtension(Extension): # a set of names that trigger the extension. - tags = set(['cache']) + tags = {'cache'} def __init__(self, environment): super(FragmentCacheExtension, self).__init__(environment) diff --git a/docs/changelog.rst b/docs/changelog.rst index b22e7beef..218fe3339 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,3 +1,4 @@ -.. module:: jinja2 +Changelog +========= .. include:: ../CHANGES.rst diff --git a/docs/conf.py b/docs/conf.py index 03169cd7a..01e530dc8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,160 +1,52 @@ -# -*- coding: utf-8 -*- -# -# Jinja2 documentation build configuration file, created by -# sphinx-quickstart on Sun Apr 27 21:42:41 2008. -# -# This file is execfile()d with the current directory set to its containing dir. -# -# The contents of this file are pickled, so don't put values in the namespace -# that aren't pickleable (module imports are okay, they're removed automatically). -# -# All configuration values have a default value; values that are commented out -# serve to show the default value. +from pallets_sphinx_themes import get_version +from pallets_sphinx_themes import ProjectLink -import sys, os +# Project -------------------------------------------------------------- -# If your extensions are in another directory, add it here. If the directory -# is relative to the documentation root, use os.path.abspath to make it -# absolute, like shown here. -sys.path.append(os.path.dirname(os.path.abspath(__file__))) +project = "Jinja" +copyright = "2007 Pallets" +author = "Pallets" +release, version = get_version("Jinja2") -# General configuration -# --------------------- +# General -------------------------------------------------------------- -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'jinjaext'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The master toctree document. -master_doc = 'index' - -# General substitutions. -project = 'Jinja2' -copyright = '2008, Armin Ronacher' - -# The default replacements for |version| and |release|, also used in various -# other places throughout the built documents. -# -# The short X.Y version. -import pkg_resources -try: - release = pkg_resources.get_distribution('Jinja2').version -except ImportError: - print('To build the documentation, The distribution information of Jinja2') - print('Has to be available. Either install the package into your') - print('development environment or run "setup.py develop" to setup the') - print('metadata. A virtualenv is recommended!') - sys.exit(1) -if 'dev' in release: - release = release.split('dev')[0] + 'dev' -version = '.'.join(release.split('.')[:2]) - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -today_fmt = '%B %d, %Y' - -# List of documents that shouldn't be included in the build. -#unused_docs = [] - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'jinjaext.JinjaStyle' - - -# Options for HTML output -# ----------------------- - -html_theme = 'jinja' -html_theme_path = ['_themes'] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# no modindex -html_use_modindex = False - -# If true, the reST sources are included in the HTML build as _sources/. -#html_copy_source = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. -#html_use_opensearch = False - -# Output file base name for HTML help builder. -htmlhelp_basename = 'Jinja2doc' - - -# Options for LaTeX output -# ------------------------ - -# The paper size ('letter' or 'a4'). -latex_paper_size = 'a4' - -# The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, document class [howto/manual]). -latex_documents = [ - ('latexindex', 'Jinja2.tex', 'Jinja2 Documentation', 'Armin Ronacher', - 'manual'), +master_doc = "index" +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.intersphinx", + "pallets_sphinx_themes", + "sphinxcontrib.log_cabinet", + "sphinx_issues", ] - -# Additional stuff for LaTeX -latex_elements = { - 'fontpkg': r'\usepackage{mathpazo}', - 'papersize': 'a4paper', - 'pointsize': '12pt', - 'preamble': r''' -\usepackage{jinjastyle} - -% i hate you latex -\DeclareUnicodeCharacter{14D}{o} -''' +intersphinx_mapping = {"python": ("https://docs.python.org/3/", None)} +issues_github_path = "pallets/jinja" + +# HTML ----------------------------------------------------------------- + +html_theme = "jinja" +html_theme_options = {"index_sidebar_logo": False} +html_context = { + "project_links": [ + ProjectLink("Donate to Pallets", "https://palletsprojects.com/donate"), + ProjectLink("Jinja Website", "https://palletsprojects.com/p/jinja/"), + ProjectLink("PyPI releases", "https://pypi.org/project/Jinja2/"), + ProjectLink("Source Code", "https://github.com/pallets/jinja/"), + ProjectLink("Issue Tracker", "https://github.com/pallets/jinja/issues/"), + ] } - -latex_use_parts = True - -latex_additional_files = ['jinjastyle.sty', 'logo.pdf'] - -# If false, no module index is generated. -latex_use_modindex = False - html_sidebars = { - 'index': ['sidebarlogo.html', 'sidebarintro.html', 'sourcelink.html', - 'searchbox.html'], - '**': ['sidebarlogo.html', 'localtoc.html', 'relations.html', - 'sourcelink.html', 'searchbox.html'] + "index": ["project.html", "localtoc.html", "searchbox.html"], + "**": ["localtoc.html", "relations.html", "searchbox.html"], } +singlehtml_sidebars = {"index": ["project.html", "localtoc.html"]} +html_static_path = ["_static"] +html_favicon = "_static/jinja-logo-sidebar.png" +html_logo = "_static/jinja-logo-sidebar.png" +html_title = "Jinja Documentation ({})".format(version) +html_show_sourcelink = False + +# LaTeX ---------------------------------------------------------------- + +latex_documents = [ + (master_doc, "Jinja-{}.tex".format(version), html_title, author, "manual") +] diff --git a/docs/contents.rst.inc b/docs/contents.rst.inc deleted file mode 100644 index 467d4cef4..000000000 --- a/docs/contents.rst.inc +++ /dev/null @@ -1,24 +0,0 @@ -Jinja2 Documentation --------------------- - -.. toctree:: - :maxdepth: 2 - - intro - api - sandbox - nativetypes - templates - extensions - integration - switching - tricks - -Additional Information ----------------------- - -.. toctree:: - :maxdepth: 2 - - faq - changelog diff --git a/docs/extensions.rst b/docs/extensions.rst index 3663060be..12c589076 100644 --- a/docs/extensions.rst +++ b/docs/extensions.rst @@ -106,7 +106,7 @@ current configuration. (For example by using `gettext.find`) The usage of the `i18n` extension for template designers is covered as part :ref:`of the template documentation `. -.. _gettext: https://docs.python.org/dev/library/gettext +.. _gettext: https://docs.python.org/3/library/gettext.html .. _Babel: http://babel.pocoo.org/ .. _newstyle-gettext: @@ -232,7 +232,7 @@ Example Extension ~~~~~~~~~~~~~~~~~ The following example implements a `cache` tag for Jinja2 by using the -`Werkzeug`_ caching contrib module: +`cachelib`_ library: .. literalinclude:: cache_extension.py :language: python @@ -240,7 +240,7 @@ The following example implements a `cache` tag for Jinja2 by using the And here is how you use it in an environment:: from jinja2 import Environment - from werkzeug.contrib.cache import SimpleCache + from cachelib import SimpleCache env = Environment(extensions=[FragmentCacheExtension]) env.fragment_cache = SimpleCache() @@ -256,7 +256,7 @@ following example caches a sidebar for 300 seconds: {% endcache %} -.. _Werkzeug: http://werkzeug.pocoo.org/ +.. _cachelib: https://github.com/pallets/cachelib Extension API ~~~~~~~~~~~~~ @@ -345,6 +345,6 @@ For more information have a look at the repr of :meth:`jinja2.Environment.parse` .. module:: jinja2.nodes -.. jinjanodes:: +.. jinja:nodes:: jinja2.nodes.Node .. autoexception:: Impossible diff --git a/docs/faq.rst b/docs/faq.rst index 624a797a4..743a6cbca 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -26,7 +26,7 @@ speaking the performance of a template engine doesn't matter much as the usual bottleneck in a web application is either the database or the application code. -.. _Mako: http://www.makotemplates.org/ +.. _Mako: https://www.makotemplates.org/ How Compatible is Jinja2 with Django? ------------------------------------- @@ -153,7 +153,7 @@ Why is there no Python 2.3/2.4/2.5/3.1/3.2 support? Python 2.3 is missing a lot of features that are used heavily in Jinja2. This decision was made as with the upcoming Python 2.6 and 3.0 versions it becomes harder to maintain the code for older Python versions. If you really need -Python 2.3 support you either have to use `Jinja 1`_ or other templating +Python 2.3 support you either have to use Jinja 1 or other templating engines that still support 2.3. Python 2.4/2.5/3.1/3.2 support was removed when we switched to supporting @@ -188,4 +188,4 @@ templates passing information to the parent template. To avoid this issue rename the macro or variable in the parent template to have an uncommon prefix. -.. _Jinja 1: http://jinja.pocoo.org/1/ +.. _Jinja 1: https://pypi.org/project/Jinja/ diff --git a/docs/index.rst b/docs/index.rst index a08d6281d..65d5d3d4a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,7 +1,13 @@ -Welcome to Jinja2 -================= +.. rst-class:: hide-header -Jinja2 is a modern and designer-friendly templating language for Python, +Jinja +===== + +.. image:: _static/jinja-logo.png + :align: center + :target: https://palletsprojects.com/p/jinja/ + +Jinja is a modern and designer-friendly templating language for Python, modelled after Django's templates. It is fast, widely used and secure with the optional sandboxed template execution environment: @@ -14,7 +20,7 @@ with the optional sandboxed template execution environment: {% endfor %} -**Features:** +Features: - sandboxed execution - powerful automatic HTML escaping system for XSS prevention @@ -25,10 +31,21 @@ with the optional sandboxed template execution environment: the correct line in the template. - configurable syntax -.. include:: contents.rst.inc - -If you can't find the information you're looking for, have a look at the -index or try to find it using the search function: +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + intro + api + sandbox + nativetypes + templates + extensions + integration + switching + tricks + faq + changelog * :ref:`genindex` * :ref:`search` diff --git a/docs/integration.rst b/docs/integration.rst index 3a4988b00..e84e5793a 100644 --- a/docs/integration.rst +++ b/docs/integration.rst @@ -76,7 +76,7 @@ snippet and add it into your `config/environment.py`:: config['pylons.strict_c'] = True -.. _Pylons: http://www.pylonshq.com/ +.. _Pylons: https://pylonshq.com/ TextMate -------- @@ -91,11 +91,11 @@ Vim A syntax plugin for `Vim`_ exists in the Vim-scripts directory as well as the `ext` folder at the root of the Jinja2 project. `The script -`_ supports Jinja1 and +`_ supports Jinja1 and Jinja2. Once installed two file types are available `jinja` and `htmljinja`. The first one for text based templates, the latter for HTML templates. Copy the files into your `syntax` folder. .. _Babel: http://babel.pocoo.org/ -.. _Vim: http://www.vim.org/ +.. _Vim: https://www.vim.org/ diff --git a/docs/intro.rst b/docs/intro.rst index 2df94d415..90636f57f 100644 --- a/docs/intro.rst +++ b/docs/intro.rst @@ -60,12 +60,12 @@ As an alternative to steps 4 you can also do ``python setup.py develop`` which will install the package via `distribute` in development mode. This also has the advantage that the C extensions are compiled. -.. _download page: https://pypi.python.org/pypi/Jinja2 -.. _distribute: https://pypi.python.org/pypi/distribute -.. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools -.. _easy_install: http://peak.telecommunity.com/DevCenter/EasyInstall -.. _pip: https://pypi.python.org/pypi/pip -.. _git: https://git-scm.org/ +.. _download page: https://pypi.org/project/Jinja2/ +.. _distribute: https://pypi.org/project/distribute/ +.. _setuptools: https://pypi.org/project/setuptools/ +.. _easy_install: https://setuptools.readthedocs.io/en/latest/easy_install.html +.. _pip: https://pypi.org/project/pip/ +.. _git: https://git-scm.com/ MarkupSafe Dependency @@ -75,7 +75,7 @@ As of version 2.7 Jinja2 depends on the `MarkupSafe`_ module. If you install Jinja2 via `pip` or `easy_install` it will be installed automatically for you. -.. _MarkupSafe: https://pypi.python.org/pypi/MarkupSafe +.. _MarkupSafe: https://markupsafe.palletsprojects.com/ Basic API Usage --------------- diff --git a/docs/jinjaext.py b/docs/jinjaext.py deleted file mode 100644 index bb5080892..000000000 --- a/docs/jinjaext.py +++ /dev/null @@ -1,206 +0,0 @@ -# -*- coding: utf-8 -*- -""" - Jinja Documentation Extensions - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Support for automatically documenting filters and tests. - - :copyright: Copyright 2008 by Armin Ronacher. - :license: BSD. -""" -import collections -import os -import re -import inspect - -import logging - -import jinja2 -from itertools import islice -from types import BuiltinFunctionType -from docutils import nodes -from docutils.statemachine import ViewList -from sphinx.ext.autodoc import prepare_docstring -from sphinx.application import TemplateBridge -from pygments.style import Style -from pygments.token import Keyword, Name, Comment, String, Error, \ - Number, Operator, Generic -from jinja2 import Environment, FileSystemLoader - - -def parse_rst(state, content_offset, doc): - node = nodes.section() - # hack around title style bookkeeping - surrounding_title_styles = state.memo.title_styles - surrounding_section_level = state.memo.section_level - state.memo.title_styles = [] - state.memo.section_level = 0 - state.nested_parse(doc, content_offset, node, match_titles=1) - state.memo.title_styles = surrounding_title_styles - state.memo.section_level = surrounding_section_level - return node.children - - -class JinjaStyle(Style): - title = 'Jinja Style' - default_style = "" - styles = { - Comment: 'italic #aaaaaa', - Comment.Preproc: 'noitalic #B11414', - Comment.Special: 'italic #505050', - - Keyword: 'bold #B80000', - Keyword.Type: '#808080', - - Operator.Word: 'bold #B80000', - - Name.Builtin: '#333333', - Name.Function: '#333333', - Name.Class: 'bold #333333', - Name.Namespace: 'bold #333333', - Name.Entity: 'bold #363636', - Name.Attribute: '#686868', - Name.Tag: 'bold #686868', - Name.Decorator: '#686868', - - String: '#AA891C', - Number: '#444444', - - Generic.Heading: 'bold #000080', - Generic.Subheading: 'bold #800080', - Generic.Deleted: '#aa0000', - Generic.Inserted: '#00aa00', - Generic.Error: '#aa0000', - Generic.Emph: 'italic', - Generic.Strong: 'bold', - Generic.Prompt: '#555555', - Generic.Output: '#888888', - Generic.Traceback: '#aa0000', - - Error: '#F00 bg:#FAA' - } - - -_sig_re = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*(\(.*?\))') - - -def format_function(name, aliases, func): - lines = inspect.getdoc(func).splitlines() - signature = '()' - if isinstance(func, BuiltinFunctionType): - match = _sig_re.match(lines[0]) - if match is not None: - del lines[:1 + bool(lines and not lines[0])] - signature = match.group(1) - else: - try: - argspec = inspect.getargspec(func) - if getattr(func, 'environmentfilter', False) or \ - getattr(func, 'contextfilter', False) or \ - getattr(func, 'evalcontextfilter', False): - del argspec[0][0] - signature = inspect.formatargspec(*argspec) - except: - pass - result = ['.. function:: %s%s' % (name, signature), ''] - result.extend(' ' + line for line in lines) - if aliases: - result.extend(('', ' :aliases: %s' % ', '.join( - '``%s``' % x for x in sorted(aliases)))) - return result - - -def dump_functions(mapping): - def directive( - dirname, arguments, options, content, lineno, content_offset, - block_text, state, state_machine - ): - reverse_mapping = {} - - for name, func in mapping.items(): - reverse_mapping.setdefault(func, []).append(name) - - filters = [] - compare_ops = set(('lt', 'le', 'eq', 'ne', 'ge', 'gt')) - - for func, names in reverse_mapping.items(): - aliases = sorted(names, key=len) - aliases = sorted(aliases, key=lambda x: x in compare_ops) - name = aliases.pop() - filters.append((name, aliases, func)) - - filters.sort() - result = ViewList() - - for name, aliases, func in filters: - for item in format_function(name, aliases, func): - result.append(item, '') - - node = nodes.paragraph() - state.nested_parse(result, content_offset, node) - return node.children - - return directive - - -from jinja2.defaults import DEFAULT_FILTERS, DEFAULT_TESTS -jinja_filters = dump_functions(DEFAULT_FILTERS) -jinja_tests = dump_functions(DEFAULT_TESTS) - - -def jinja_nodes(dirname, arguments, options, content, lineno, - content_offset, block_text, state, state_machine): - from jinja2.nodes import Node - doc = ViewList() - def walk(node, indent): - p = ' ' * indent - sig = ', '.join(node.fields) - doc.append(p + '.. autoclass:: %s(%s)' % (node.__name__, sig), '') - if node.abstract: - members = [] - for key, name in node.__dict__.items(): - if not key.startswith('_') and \ - not hasattr(node.__base__, key) and isinstance(name, collections.Callable): - members.append(key) - if members: - members.sort() - doc.append('%s :members: %s' % (p, ', '.join(members)), '') - if node.__base__ != object: - doc.append('', '') - doc.append('%s :Node type: :class:`%s`' % - (p, node.__base__.__name__), '') - doc.append('', '') - children = node.__subclasses__() - children.sort(key=lambda x: x.__name__.lower()) - for child in children: - walk(child, indent) - walk(Node, 0) - return parse_rst(state, content_offset, doc) - - -def inject_toc(app, doctree, docname): - titleiter = iter(doctree.traverse(nodes.title)) - try: - # skip first title, we are not interested in that one - next(titleiter) - title = next(titleiter) - # and check if there is at least another title - next(titleiter) - except StopIteration: - return - tocnode = nodes.section('') - tocnode['classes'].append('toc') - toctitle = nodes.section('') - toctitle['classes'].append('toctitle') - toctitle.append(nodes.title(text='Table Of Contents')) - tocnode.append(toctitle) - tocnode += doctree.document.settings.env.get_toc_for(docname)[0][1] - title.parent.insert(title.parent.children.index(title), tocnode) - - -def setup(app): - app.add_directive('jinjafilters', jinja_filters, 0, (0, 0, 0)) - app.add_directive('jinjatests', jinja_tests, 0, (0, 0, 0)) - app.add_directive('jinjanodes', jinja_nodes, 0, (0, 0, 0)) - # uncomment for inline toc. links are broken unfortunately - ##app.connect('doctree-resolved', inject_toc) diff --git a/docs/jinjastyle.sty b/docs/jinjastyle.sty deleted file mode 100644 index da811ce37..000000000 --- a/docs/jinjastyle.sty +++ /dev/null @@ -1,119 +0,0 @@ -\definecolor{TitleColor}{rgb}{0,0,0} -\definecolor{InnerLinkColor}{rgb}{0,0,0} -\definecolor{OuterLinkColor}{rgb}{0.8,0,0} - -\renewcommand{\maketitle}{% - \begin{titlepage}% - \let\footnotesize\small - \let\footnoterule\relax - \ifsphinxpdfoutput - \begingroup - % This \def is required to deal with multi-line authors; it - % changes \\ to ', ' (comma-space), making it pass muster for - % generating document info in the PDF file. - \def\\{, } - \pdfinfo{ - /Author (\@author) - /Title (\@title) - } - \endgroup - \fi - \begin{flushright}% - %\sphinxlogo% - {\center - \vspace*{3cm} - \includegraphics{logo.pdf} - \vspace{3cm} - \par - {\rm\Huge \@title \par}% - {\em\LARGE \py@release\releaseinfo \par} - {\large - \@date \par - \py@authoraddress \par - }}% - \end{flushright}%\par - \@thanks - \end{titlepage}% - \cleardoublepage% - \setcounter{footnote}{0}% - \let\thanks\relax\let\maketitle\relax - %\gdef\@thanks{}\gdef\@author{}\gdef\@title{} -} - -\fancypagestyle{normal}{ - \fancyhf{} - \fancyfoot[LE,RO]{{\thepage}} - \fancyfoot[LO]{{\nouppercase{\rightmark}}} - \fancyfoot[RE]{{\nouppercase{\leftmark}}} - \fancyhead[LE,RO]{{ \@title, \py@release}} - \renewcommand{\headrulewidth}{0.4pt} - \renewcommand{\footrulewidth}{0.4pt} -} - -\fancypagestyle{plain}{ - \fancyhf{} - \fancyfoot[LE,RO]{{\thepage}} - \renewcommand{\headrulewidth}{0pt} - \renewcommand{\footrulewidth}{0.4pt} -} - -\titleformat{\section}{\Large}% - {\py@TitleColor\thesection}{0.5em}{\py@TitleColor}{\py@NormalColor} -\titleformat{\subsection}{\large}% - {\py@TitleColor\thesubsection}{0.5em}{\py@TitleColor}{\py@NormalColor} -\titleformat{\subsubsection}{}% - {\py@TitleColor\thesubsubsection}{0.5em}{\py@TitleColor}{\py@NormalColor} -\titleformat{\paragraph}{\large}% - {\py@TitleColor}{0em}{\py@TitleColor}{\py@NormalColor} - -\ChNameVar{\raggedleft\normalsize} -\ChNumVar{\raggedleft \bfseries\Large} -\ChTitleVar{\raggedleft \rm\Huge} - -\renewcommand\thepart{\@Roman\c@part} -\renewcommand\part{% - \pagestyle{plain} - \if@noskipsec \leavevmode \fi - \cleardoublepage - \vspace*{6cm}% - \@afterindentfalse - \secdef\@part\@spart} - -\def\@part[#1]#2{% - \ifnum \c@secnumdepth >\m@ne - \refstepcounter{part}% - \addcontentsline{toc}{part}{\thepart\hspace{1em}#1}% - \else - \addcontentsline{toc}{part}{#1}% - \fi - {\parindent \z@ %\center - \interlinepenalty \@M - \normalfont - \ifnum \c@secnumdepth >\m@ne - \rm\Large \partname~\thepart - \par\nobreak - \fi - \MakeUppercase{\rm\Huge #2}% - \markboth{}{}\par}% - \nobreak - \vskip 8ex - \@afterheading} -\def\@spart#1{% - {\parindent \z@ %\center - \interlinepenalty \@M - \normalfont - \huge \bfseries #1\par}% - \nobreak - \vskip 3ex - \@afterheading} - -% use inconsolata font -\usepackage{inconsolata} - -% fix single quotes, for inconsolata. (does not work) -%%\usepackage{textcomp} -%%\begingroup -%% \catcode`'=\active -%% \g@addto@macro\@noligs{\let'\textsinglequote} -%% \endgroup -%%\endinput diff --git a/docs/latexindex.rst b/docs/latexindex.rst deleted file mode 100644 index 300e60d10..000000000 --- a/docs/latexindex.rst +++ /dev/null @@ -1,6 +0,0 @@ -:orphan: - -Jinja2 Documentation -==================== - -.. include:: contents.rst.inc diff --git a/docs/logo.pdf b/docs/logo.pdf deleted file mode 100644 index 3e8a9cf48..000000000 Binary files a/docs/logo.pdf and /dev/null differ diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 000000000..7893348a1 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 000000000..cfe1fd75e --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,4 @@ +Sphinx~=2.1.2 +Pallets-Sphinx-Themes~=1.2.0 +sphinxcontrib-log-cabinet~=1.0.1 +sphinx-issues~=1.2.0 diff --git a/docs/templates.rst b/docs/templates.rst index d10d5e672..4f6146980 100644 --- a/docs/templates.rst +++ b/docs/templates.rst @@ -390,7 +390,9 @@ this template "extends" another template. When the template system evaluates this template, it first locates the parent. The extends tag should be the first tag in the template. Everything before it is printed out normally and may cause confusion. For details about this behavior and how to take -advantage of it, see :ref:`null-master-fallback`. +advantage of it, see :ref:`null-master-fallback`. Also a block will always be +filled in regardless of whether the surrounding condition is evaluated to be true +or false. The filename of the template depends on the template loader. For example, the :class:`FileSystemLoader` allows you to access other templates by giving the @@ -572,7 +574,7 @@ As variables in templates retain their object properties, it is possible to iterate over containers like `dict`::
- {% for key, value in my_dict.iteritems() %} + {% for key, value in my_dict.items() %}
{{ key|e }}
{{ value|e }}
{% endfor %} @@ -1196,7 +1198,6 @@ but exists for completeness' sake. The following operators are supported: / Divide two numbers. The return value will be a floating point number. ``{{ 1 / 2 }}`` is ``{{ 0.5 }}``. - (Just like ``from __future__ import division``.) // Divide two numbers and return the truncated integer result. @@ -1309,11 +1310,33 @@ The general syntax is `` if else ``. The `else` part is optional. If not provided, the else block implicitly -evaluates into an undefined object:: +evaluates into an undefined object: .. sourcecode:: jinja - {{ '[%s]' % page.title if page.title }} + {{ "[{}]".format(page.title) if page.title }} + + +.. _python-methods: + +Python Methods +~~~~~~~~~~~~~~ + +You can also use any of the methods of defined on a variable's type. +The value returned from the method invocation is used as the value of the expression. +Here is an example that uses methods defined on strings (where ``page.title`` is a string): + +.. code-block:: text + + {{ page.title.capitalize() }} + +This also works for methods on user-defined types. +For example, if variable ``f`` of type ``Foo`` has a method ``bar`` defined on it, +you can do the following: + +.. code-block:: text + + {{ f.bar() }} .. _builtin-filters: @@ -1321,7 +1344,7 @@ evaluates into an undefined object:: List of Builtin Filters ----------------------- -.. jinjafilters:: +.. jinja:filters:: jinja2.defaults.DEFAULT_FILTERS .. _builtin-tests: @@ -1329,7 +1352,8 @@ List of Builtin Filters List of Builtin Tests --------------------- -.. jinjatests:: +.. jinja:tests:: jinja2.defaults.DEFAULT_TESTS + .. _builtin-globals: diff --git a/jinja2/__init__.py b/jinja2/__init__.py index 15e13b6f2..270dd4fe1 100644 --- a/jinja2/__init__.py +++ b/jinja2/__init__.py @@ -27,7 +27,7 @@ :license: BSD, see LICENSE for more details. """ __docformat__ = 'restructuredtext en' -__version__ = '2.10.1' +__version__ = "2.10.3+lastfm" # high level interface from jinja2.environment import Environment, Template diff --git a/jinja2/_compat.py b/jinja2/_compat.py index 61d85301a..4dbf6ea03 100644 --- a/jinja2/_compat.py +++ b/jinja2/_compat.py @@ -97,3 +97,9 @@ def __new__(cls, name, this_bases, d): from urllib.parse import quote_from_bytes as url_quote except ImportError: from urllib import quote as url_quote + + +try: + from collections import abc +except ImportError: + import collections as abc diff --git a/jinja2/bccache.py b/jinja2/bccache.py index 080e527ca..507a9b3de 100644 --- a/jinja2/bccache.py +++ b/jinja2/bccache.py @@ -296,9 +296,8 @@ class MemcachedBytecodeCache(BytecodeCache): Libraries compatible with this class: - - `werkzeug `_.contrib.cache - - `python-memcached `_ - - `cmemcache `_ + - `cachelib `_ + - `python-memcached `_ (Unfortunately the django cache interface is not compatible because it does not support storing binary data, only unicode. You can however pass diff --git a/jinja2/compiler.py b/jinja2/compiler.py index d534a8273..e319a9b41 100644 --- a/jinja2/compiler.py +++ b/jinja2/compiler.py @@ -547,8 +547,14 @@ def macro_body(self, node, frame): # macros are delayed, they never require output checks frame.require_output_check = False frame.symbols.analyze_node(node) - self.writeline('%s(%s):' % (self.func('macro'), ', '.join(args)), node) + self.writeline('outer_context = context') + self.writeline('%s(%s):' % + (self.func('macro'), ', '.join(['context'] + args)), + node) self.indent() + self.writeline('nonlocal outer_context') + self.writeline('context = context or outer_context') + self.writeline('resolve = context.resolve_or_missing') self.buffer(frame) self.enter_frame(frame) diff --git a/jinja2/debug.py b/jinja2/debug.py index b61139f0c..d3c1a3a87 100644 --- a/jinja2/debug.py +++ b/jinja2/debug.py @@ -365,8 +365,14 @@ def tb_set_next(tb, next): # proxies. tb_set_next = None if tproxy is None: - try: - tb_set_next = _init_ugly_crap() - except: - pass - del _init_ugly_crap + # traceback.tb_next can be modified since CPython 3.7 + if sys.version_info >= (3, 7): + def tb_set_next(tb, next): + tb.tb_next = next + else: + # On Python 3.6 and older, use ctypes + try: + tb_set_next = _init_ugly_crap() + except Exception: + pass +del _init_ugly_crap diff --git a/jinja2/runtime.py b/jinja2/runtime.py index f9d7a6806..1d2893e03 100644 --- a/jinja2/runtime.py +++ b/jinja2/runtime.py @@ -15,12 +15,12 @@ from jinja2.nodes import EvalContext, _context_function_types from jinja2.utils import Markup, soft_unicode, escape, missing, concat, \ - internalcode, object_type_repr, evalcontextfunction, Namespace + internalcode, object_type_repr, contextfunction, Namespace from jinja2.exceptions import UndefinedError, TemplateRuntimeError, \ TemplateNotFound from jinja2._compat import imap, text_type, iteritems, \ implements_iterator, implements_to_string, string_types, PY2, \ - with_metaclass + with_metaclass, abc # these variables are exported to the template runtime @@ -313,12 +313,7 @@ def __repr__(self): ) -# register the context as mapping if possible -try: - from collections import Mapping - Mapping.register(Context) -except ImportError: - pass +abc.Mapping.register(Context) class BlockReference(object): @@ -499,7 +494,7 @@ def __init__(self, environment, func, name, arguments, self._default_autoescape = default_autoescape @internalcode - @evalcontextfunction + @contextfunction def __call__(self, *args, **kwargs): # This requires a bit of explanation, In the past we used to # decide largely based on compile-time information if a macro is @@ -518,10 +513,12 @@ def __call__(self, *args, **kwargs): # argument to callables otherwise anwyays. Worst case here is # that if no eval context is passed we fall back to the compile # time autoescape flag. - if args and isinstance(args[0], EvalContext): - autoescape = args[0].autoescape + if args and isinstance(args[0], Context): + context = args[0] + autoescape = context.eval_ctx.autoescape args = args[1:] else: + context = None autoescape = self._default_autoescape # try to consume the positional arguments @@ -572,6 +569,7 @@ def __call__(self, *args, **kwargs): raise TypeError('macro %r takes not more than %d argument(s)' % (self.name, len(self.arguments))) + arguments = [context] + arguments return self._invoke(arguments, autoescape) def _invoke(self, arguments, autoescape): diff --git a/jinja2/sandbox.py b/jinja2/sandbox.py index 752e81289..08c22f4f1 100644 --- a/jinja2/sandbox.py +++ b/jinja2/sandbox.py @@ -14,10 +14,9 @@ """ import types import operator -from collections import Mapping from jinja2.environment import Environment from jinja2.exceptions import SecurityError -from jinja2._compat import string_types, PY2 +from jinja2._compat import string_types, PY2, abc, range_type from jinja2.utils import Markup from markupsafe import EscapeFormatter @@ -79,10 +78,9 @@ pass #: register Python 2.6 abstract base classes -from collections import MutableSet, MutableMapping, MutableSequence -_mutable_set_types += (MutableSet,) -_mutable_mapping_types += (MutableMapping,) -_mutable_sequence_types += (MutableSequence,) +_mutable_set_types += (abc.MutableSet,) +_mutable_mapping_types += (abc.MutableMapping,) +_mutable_sequence_types += (abc.MutableSequence,) _mutable_spec = ( @@ -103,7 +101,7 @@ ) -class _MagicFormatMapping(Mapping): +class _MagicFormatMapping(abc.Mapping): """This class implements a dummy wrapper to fix a bug in the Python standard library for string formatting. @@ -148,10 +146,14 @@ def safe_range(*args): """A range that can't generate ranges with a length of more than MAX_RANGE items. """ - rng = range(*args) + rng = range_type(*args) + if len(rng) > MAX_RANGE: - raise OverflowError('range too big, maximum size for range is %d' % - MAX_RANGE) + raise OverflowError( + "Range too big. The sandbox blocks ranges larger than" + " MAX_RANGE (%d)." % MAX_RANGE + ) + return rng diff --git a/jinja2/tests.py b/jinja2/tests.py index 0adc3d4db..bc99d66c8 100644 --- a/jinja2/tests.py +++ b/jinja2/tests.py @@ -10,9 +10,8 @@ """ import operator import re -from collections import Mapping from jinja2.runtime import Undefined -from jinja2._compat import text_type, string_types, integer_types +from jinja2._compat import text_type, string_types, integer_types, abc import decimal number_re = re.compile(r'^-?\d+(\.\d+)?$') @@ -84,7 +83,7 @@ def test_mapping(value): .. versionadded:: 2.6 """ - return isinstance(value, Mapping) + return isinstance(value, abc.Mapping) def test_number(value): diff --git a/jinja2/utils.py b/jinja2/utils.py index 502a311c0..db9c5d062 100644 --- a/jinja2/utils.py +++ b/jinja2/utils.py @@ -14,7 +14,7 @@ from collections import deque from threading import Lock from jinja2._compat import text_type, string_types, implements_iterator, \ - url_quote + url_quote, abc _word_split_re = re.compile(r'(\s+)') @@ -480,12 +480,7 @@ def __reversed__(self): __copy__ = copy -# register the LRU cache as mutable mapping if possible -try: - from collections import MutableMapping - MutableMapping.register(LRUCache) -except ImportError: - pass +abc.MutableMapping.register(LRUCache) def select_autoescape(enabled_extensions=('html', 'htm', 'xml'), diff --git a/setup.cfg b/setup.cfg index e9fc0a44c..dd4e62e0a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,9 +1,20 @@ -[bdist_wheel] -universal = 1 - [metadata] -license_file = LICENSE +license_file = LICENSE.rst + +[bdist_wheel] +universal = true [tool:pytest] -minversion = 3.0 testpaths = tests + +[coverage:run] +branch = True +source = + jinja2 + tests + +[coverage:paths] +source = + src/jinja2 + .tox/*/lib/python*/site-packages/jinja2 + .tox/*/site-packages/jinja2 diff --git a/setup.py b/setup.py index 3510b3769..55f0526e4 100644 --- a/setup.py +++ b/setup.py @@ -1,80 +1,53 @@ -# -*- coding: utf-8 -*- -""" -Jinja2 -~~~~~~ +import io +import re -Jinja2 is a template engine written in pure Python. It provides a -`Django`_ inspired non-XML syntax but supports inline expressions and -an optional `sandboxed`_ environment. - -Nutshell --------- - -Here a small example of a Jinja template:: - - {% extends 'base.html' %} - {% block title %}Memberlist{% endblock %} - {% block content %} - - {% endblock %} - -Philosophy ----------- - -Application logic is for the controller but don't try to make the life -for the template designer too hard by giving him too few functionality. - -For more informations visit the new `Jinja2 webpage`_ and `documentation`_. - -.. _sandboxed: https://en.wikipedia.org/wiki/Sandbox_(computer_security) -.. _Django: https://www.djangoproject.com/ -.. _Jinja2 webpage: http://jinja.pocoo.org/ -.. _documentation: http://jinja.pocoo.org/2/documentation/ -""" +from setuptools import find_packages from setuptools import setup +with io.open("README.rst", "rt", encoding="utf8") as f: + readme = f.read() + +with io.open("jinja2/__init__.py", "rt", encoding="utf8") as f: + version = re.search(r'__version__ = "(.*?)"', f.read(), re.M).group(1) setup( - name='Jinja2', - version='2.10.1', - url='http://jinja.pocoo.org/', - license='BSD', - author='Armin Ronacher', - author_email='armin.ronacher@active-4.com', - description='A small but fast and easy to use stand-alone template ' - 'engine written in pure python.', - long_description=__doc__, - # jinja is egg safe. But we hate eggs - zip_safe=False, + name="Jinja2", + version=version, + url="https://palletsprojects.com/p/jinja/", + project_urls={ + "Documentation": "https://jinja.palletsprojects.com/", + "Code": "https://github.com/pallets/jinja", + "Issue tracker": "https://github.com/pallets/jinja/issues", + }, + license="BSD-3-Clause", + author="Armin Ronacher", + author_email="armin.ronacher@active-4.com", + maintainer="Pallets", + maintainer_email="contact@palletsprojects.com", + description="A very fast and expressive template engine.", + long_description=readme, classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Environment :: Web Environment', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: BSD License', - 'Operating System :: OS Independent', - 'Programming Language :: Python', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.6', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', - 'Topic :: Software Development :: Libraries :: Python Modules', - 'Topic :: Text Processing :: Markup :: HTML' + "Development Status :: 5 - Production/Stable", + "Environment :: Web Environment", + "Intended Audience :: Developers", + "License :: OSI Approved :: BSD License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Internet :: WWW/HTTP :: Dynamic Content", + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: Text Processing :: Markup :: HTML", ], - packages=['jinja2'], - install_requires=['MarkupSafe>=0.23'], - extras_require={'i18n': ['Babel>=0.8']}, + packages=find_packages(), include_package_data=True, - entry_points=""" - [babel.extractors] - jinja2 = jinja2.ext:babel_extract[i18n] - """ + install_requires=["MarkupSafe>=0.23"], + extras_require={"i18n": ["Babel>=0.8"]}, + entry_points={"babel.extractors": ["jinja2 = jinja2.ext:babel_extract[i18n]"]}, ) diff --git a/tests/conftest.py b/tests/conftest.py index 04ac78443..107659b90 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -16,12 +16,54 @@ from jinja2 import Environment -def pytest_ignore_collect(path, config): +def pytest_ignore_collect(path): if 'async' in path.basename and not have_async_gen: return True return False +def pytest_configure(config): + '''Register custom marks for test categories.''' + custom_markers = [ + 'api', + 'byte_code_cache', + 'core_tags', + 'debug', + 'escapeUrlizeTarget', + 'ext', + 'extended', + 'filter', + 'for_loop', + 'helpers', + 'if_condition', + 'imports', + 'includes', + 'inheritance', + 'lexer', + 'lexnparse', + 'loaders', + 'lowlevel', + 'lrucache', + 'lstripblocks', + 'macros', + 'meta', + 'moduleloader', + 'parser', + 'regression', + 'sandbox', + 'set', + 'streaming', + 'syntax', + 'test_tests', + 'tokenstream', + 'undefined', + 'utils', + 'with_', + ] + for mark in custom_markers: + config.addinivalue_line('markers', mark + ': test category') + + @pytest.fixture def env(): '''returns a new environment. diff --git a/tests/test_api.py b/tests/test_api.py index 5708144fb..26dd4da53 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -68,7 +68,7 @@ def test_cycler_nextmethod(self, env): c.next() assert c.current == 2 c.reset() - assert c.current == 1 + assert c.current == 1 def test_expressions(self, env): expr = env.compile_expression("foo") @@ -104,6 +104,15 @@ def select_autoescape(name): t = env.from_string('{{ foo }}') assert t.render(foo='') == '' + def test_sandbox_max_range(self, env): + from jinja2.sandbox import SandboxedEnvironment, MAX_RANGE + + env = SandboxedEnvironment() + t = env.from_string("{% for item in range(total) %}{{ item }}{% endfor %}") + + with pytest.raises(OverflowError): + t.render(total=MAX_RANGE + 1) + @pytest.mark.api @pytest.mark.meta diff --git a/tests/test_async.py b/tests/test_async.py index 2f177473d..8d697be5f 100644 --- a/tests/test_async.py +++ b/tests/test_async.py @@ -126,21 +126,21 @@ class TestAsyncImports(object): def test_context_imports(self, test_env_async): t = test_env_async.from_string('{% import "module" as m %}{{ m.test() }}') - assert t.render(foo=42) == '[|23]' + assert t.render(foo=42) == '[42|23]' t = test_env_async.from_string( '{% import "module" as m without context %}{{ m.test() }}' ) - assert t.render(foo=42) == '[|23]' + assert t.render(foo=42) == '[42|23]' t = test_env_async.from_string( '{% import "module" as m with context %}{{ m.test() }}' ) assert t.render(foo=42) == '[42|23]' t = test_env_async.from_string('{% from "module" import test %}{{ test() }}') - assert t.render(foo=42) == '[|23]' + assert t.render(foo=42) == '[42|23]' t = test_env_async.from_string( '{% from "module" import test without context %}{{ test() }}' ) - assert t.render(foo=42) == '[|23]' + assert t.render(foo=42) == '[42|23]' t = test_env_async.from_string( '{% from "module" import test with context %}{{ test() }}' ) diff --git a/tests/test_imports.py b/tests/test_imports.py index 65aae43f2..7e33560fa 100644 --- a/tests/test_imports.py +++ b/tests/test_imports.py @@ -31,21 +31,21 @@ class TestImports(object): def test_context_imports(self, test_env): t = test_env.from_string('{% import "module" as m %}{{ m.test() }}') - assert t.render(foo=42) == '[|23]' + assert t.render(foo=42) == '[42|23]' t = test_env.from_string( '{% import "module" as m without context %}{{ m.test() }}' ) - assert t.render(foo=42) == '[|23]' + assert t.render(foo=42) == '[42|23]' t = test_env.from_string( '{% import "module" as m with context %}{{ m.test() }}' ) assert t.render(foo=42) == '[42|23]' t = test_env.from_string('{% from "module" import test %}{{ test() }}') - assert t.render(foo=42) == '[|23]' + assert t.render(foo=42) == '[42|23]' t = test_env.from_string( '{% from "module" import test without context %}{{ test() }}' ) - assert t.render(foo=42) == '[|23]' + assert t.render(foo=42) == '[42|23]' t = test_env.from_string( '{% from "module" import test with context %}{{ test() }}' ) diff --git a/tests/test_security.py b/tests/test_security.py index 5c8639c4e..bce6428b5 100644 --- a/tests/test_security.py +++ b/tests/test_security.py @@ -16,7 +16,7 @@ from jinja2 import Markup, escape from jinja2.exceptions import SecurityError, TemplateSyntaxError, \ TemplateRuntimeError -from jinja2.nodes import EvalContext +from jinja2.runtime import new_context from jinja2._compat import text_type @@ -121,7 +121,7 @@ def test_template_data(self, env): assert escape(t.module) == escaped_out assert t.module.say_hello('foo') == escaped_out assert escape(t.module.say_hello( - EvalContext(env), 'foo')) == escaped_out + new_context(env, 'name', {}), 'foo')) == escaped_out assert escape(t.module.say_hello( 'foo')) == escaped_out diff --git a/tox.ini b/tox.ini index 406eaebac..60b987642 100644 --- a/tox.ini +++ b/tox.ini @@ -1,41 +1,36 @@ [tox] envlist = - py{36,35,34,33,27,26,py} + py{37,36,35,27,py3,py} docs-html - coverage-report + coverage +skip_missing_interpreters = true [testenv] -passenv = LANG -usedevelop = true deps = - pytest>=3 coverage - -commands = coverage run -p -m pytest {posargs} + pytest +commands = coverage run -p -m pytest --tb=short -Werror --basetemp={envtmpdir} {posargs} [testenv:docs-html] -deps = sphinx -commands = sphinx-build -W -b html -d {envtmpdir}/doctrees docs docs/_build/html - -[testenv:docs-linkcheck] -deps = sphinx -commands = sphinx-build -W -b linkcheck -d {envtmpdir}/doctrees docs docs/_build/linkcheck +deps = + Sphinx + Pallets-Sphinx-Themes + sphinxcontrib-log-cabinet + sphinx-issues +commands = sphinx-build -b html -d {envtmpdir}/doctrees docs {envtmpdir}/html -[testenv:coverage-report] +[testenv:coverage] deps = coverage skip_install = true commands = coverage combine - coverage report coverage html + coverage report -[testenv:codecov] -passenv = CI TRAVIS TRAVIS_* -deps = codecov +[testenv:coverage-ci] +deps = coverage skip_install = true commands = - # install argparse for 2.6 - python -c 'import sys, pip; sys.version_info < (2, 7) and pip.main(["install", "argparse", "-q"])' coverage combine - coverage report - codecov + # Ignoring errors because 2.7.15 and 3.5.5 on Azure can't parse async files. + coverage xml --ignore-errors