[Python-modules-commits] [jinja2] 01/03: Import jinja2_2.9.5.orig.tar.gz
Piotr Ożarowski
piotr at moszumanska.debian.org
Tue Feb 7 21:37:15 UTC 2017
This is an automated email from the git hooks/post-receive script.
piotr pushed a commit to branch master
in repository jinja2.
commit b9cd64738061265fe816f7f8b8f9cf670a7bd2eb
Author: Piotr Ożarowski <piotr at debian.org>
Date: Tue Feb 7 22:27:35 2017 +0100
Import jinja2_2.9.5.orig.tar.gz
---
CHANGES | 18 +++++++
Jinja2.egg-info/PKG-INFO | 2 +-
PKG-INFO | 2 +-
docs/templates.rst | 49 ++++++++++++++++++
jinja2/__init__.py | 2 +-
jinja2/_stringdefs.py | 127 ++++++++++++-----------------------------------
jinja2/asyncsupport.py | 19 ++++++-
jinja2/compiler.py | 10 ++--
jinja2/filters.py | 9 +++-
jinja2/lexer.py | 27 +++++++---
jinja2/runtime.py | 72 +++++++++++++++++++++++----
setup.py | 2 +-
12 files changed, 219 insertions(+), 120 deletions(-)
diff --git a/CHANGES b/CHANGES
index f95f41a..fb14601 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,24 @@
Jinja2 Changelog
================
+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)
+
Version 2.9.4
-------------
(bugfix release, released on January 10th 2017)
diff --git a/Jinja2.egg-info/PKG-INFO b/Jinja2.egg-info/PKG-INFO
index 02ba56e..0dcd123 100644
--- a/Jinja2.egg-info/PKG-INFO
+++ b/Jinja2.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: Jinja2
-Version: 2.9.4
+Version: 2.9.5
Summary: A small but fast and easy to use stand-alone template engine written in pure python.
Home-page: http://jinja.pocoo.org/
Author: Armin Ronacher
diff --git a/PKG-INFO b/PKG-INFO
index 02ba56e..0dcd123 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: Jinja2
-Version: 2.9.4
+Version: 2.9.5
Summary: A small but fast and easy to use stand-alone template engine written in pure python.
Home-page: http://jinja.pocoo.org/
Author: Armin Ronacher
diff --git a/docs/templates.rst b/docs/templates.rst
index 48f1894..236590f 100644
--- a/docs/templates.rst
+++ b/docs/templates.rst
@@ -674,6 +674,12 @@ have more than one level of loops, we can rebind the variable `loop` by
writing `{% set outer_loop = loop %}` after the loop that we want to
use recursively. Then, we can call it using `{{ outer_loop(...) }}`
+Please note that assignments in loops will be cleared at the end of the
+iteration and cannot outlive the loop scope. Older versions of Jinja2 had
+a bug where in some circumstances it appeared that assignments would work.
+This is not supported. See :ref:`assignments` for more information about
+how to deal with this.
+
.. _if:
If
@@ -844,6 +850,31 @@ Assignments use the `set` tag and can have multiple targets::
{% set navigation = [('index.html', 'Index'), ('about.html', 'About')] %}
{% set key, value = call_something() %}
+.. admonition:: Scoping Behavior
+
+ Please keep in mind that it is not possible to set variables inside a
+ block and have them show up outside of it. This also applies to
+ loops. The only exception to that rule are if statements which do not
+ introduce a scope. As a result the following template is not going
+ to do what you might expect::
+
+ {% set iterated = false %}
+ {% for item in seq %}
+ {{ item }}
+ {% set iterated = true %}
+ {% endfor %}
+ {% if not iterated %} did not iterate {% endif %}
+
+ It is not possible with Jinja syntax to do this. Instead use
+ alternative constructs like the loop else block or the special `loop`
+ variable::
+
+ {% for item in seq %}
+ {{ item }}
+ {% else %}
+ did not iterate
+ {% endfor %}
+
Block Assignments
~~~~~~~~~~~~~~~~~
@@ -1484,6 +1515,24 @@ are equivalent::
{{ foo }}
{% endwith %}
+An important note on scoping here. In Jinja versions before 2.9 the
+behavior of referencing one variable to another had some unintended
+consequences. In particular one variable could refer to another defined
+in the same with block's opening statement. This caused issues with the
+cleaned up scoping behavior and has since been improved. In particular
+in newer Jinja2 versions the following code always refers to the variable
+`a` from outside the `with` block::
+
+ {% with a={}, b=a.attribute %}...{% endwith %}
+
+In earlier Jinja versions the `b` attribute would refer to the results of
+the first attribute. If you depend on this behavior you can rewrite it to
+use the ``set`` tag::
+
+ {% with a={} %}
+ {% set b = a.attribute %}
+ {% endwith %}
+
.. admonition:: Extension
In older versions of Jinja (before 2.9) it was required to enable this
diff --git a/jinja2/__init__.py b/jinja2/__init__.py
index 360b54f..2662818 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.9.4'
+__version__ = '2.9.5'
# high level interface
from jinja2.environment import Environment, Template
diff --git a/jinja2/_stringdefs.py b/jinja2/_stringdefs.py
index da5830e..a5689f6 100644
--- a/jinja2/_stringdefs.py
+++ b/jinja2/_stringdefs.py
@@ -9,93 +9,23 @@
Inspired by chartypes_create.py from the MoinMoin project, original
implementation from Pygments.
- :copyright: Copyright 2006-2009 by the Jinja team, see AUTHORS.
+ :copyright: Copyright 2006-2017 by the Jinja team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
-from jinja2._compat import unichr
+# Generated code start
-Cc = u'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f'
-
-Cf = u'\xad\u0600\u0601\u0602\u0603\u06dd\u070f\u17b4\u17b5\u200b\u200c\u200d\u200e\u200f\u202a\u202b\u202c\u202d\u202e\u2060\u2061\u2062\u2063\u206a\u206b\u206c\u206d\u206e\u206f\ufeff\ufff9\ufffa\ufffb'
-
-Cn = u'\u0242\u0243\u0244\u0245\u0246\u0247\u0248\u0249\u024a\u024b\u024c\u024d\u024e\u024f\u0370\u0371\u0372\u0373\u0376\u0377\u0378\u0379\u037b\u037c\u037d\u037f\u0380\u0381\u0382\u0383\u038b\u038d\u03a2\u03cf\u0487\u04cf\u04fa\u04fb\u04fc\u04fd\u04fe\u04ff\u0510\u0511\u0512\u0513\u0514\u0515\u0516\u0517\u0518\u0519\u051a\u051b\u051c\u051d\u051e\u051f\u0520\u0521\u0522\u0523\u0524\u0525\u0526\u0527\u0528\u0529\u052a\u052b\u052c\u052d\u052e\u052f\u0530\u0557\u0558\u0560\u0588\u058b\u058 [...]
-
-Co = u'\ue000\ue001\ue002\ue003\ue004\ue005\ue006\ue007\ue008\ue009\ue00a\ue00b\ue00c\ue00d\ue00e\ue00f\ue010\ue011\ue012\ue013\ue014\ue015\ue016\ue017\ue018\ue019\ue01a\ue01b\ue01c\ue01d\ue01e\ue01f\ue020\ue021\ue022\ue023\ue024\ue025\ue026\ue027\ue028\ue029\ue02a\ue02b\ue02c\ue02d\ue02e\ue02f\ue030\ue031\ue032\ue033\ue034\ue035\ue036\ue037\ue038\ue039\ue03a\ue03b\ue03c\ue03d\ue03e\ue03f\ue040\ue041\ue042\ue043\ue044\ue045\ue046\ue047\ue048\ue049\ue04a\ue04b\ue04c\ue04d\ue04e\ue04f\ue05 [...]
-
-try:
- Cs = eval(r"'\ud800\ud801\ud802\ud803\ud804\ud805\ud806\ud807\ud808\ud809\ud80a\ud80b\ud80c\ud80d\ud80e\ud80f\ud810\ud811\ud812\ud813\ud814\ud815\ud816\ud817\ud818\ud819\ud81a\ud81b\ud81c\ud81d\ud81e\ud81f\ud820\ud821\ud822\ud823\ud824\ud825\ud826\ud827\ud828\ud829\ud82a\ud82b\ud82c\ud82d\ud82e\ud82f\ud830\ud831\ud832\ud833\ud834\ud835\ud836\ud837\ud838\ud839\ud83a\ud83b\ud83c\ud83d\ud83e\ud83f\ud840\ud841\ud842\ud843\ud844\ud845\ud846\ud847\ud848\ud849\ud84a\ud84b\ud84c\ud84d\ud84e\ [...]
-except UnicodeDecodeError:
- Cs = '' # Jython can't handle isolated surrogates
-
-Ll = u'abcdefghijklmnopqrstuvwxyz\xaa\xb5\xba\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\u0101\u0103\u0105\u0107\u0109\u010b\u010d\u010f\u0111\u0113\u0115\u0117\u0119\u011b\u011d\u011f\u0121\u0123\u0125\u0127\u0129\u012b\u012d\u012f\u0131\u0133\u0135\u0137\u0138\u013a\u013c\u013e\u0140\u0142\u0144\u0146\u0148\u0149\u014b\u014d\u014f\u0151\u0153\u0155\u0157\u0159\u015b\u015d\u015f\u0161\u0163\u0165\u0167\ [...]
-
-Lm = u'\u02b0\u02b1\u02b2\u02b3\u02b4\u02b5\u02b6\u02b7\u02b8\u02b9\u02ba\u02bb\u02bc\u02bd\u02be\u02bf\u02c0\u02c1\u02c6\u02c7\u02c8\u02c9\u02ca\u02cb\u02cc\u02cd\u02ce\u02cf\u02d0\u02d1\u02e0\u02e1\u02e2\u02e3\u02e4\u02ee\u037a\u0559\u0640\u06e5\u06e6\u0e46\u0ec6\u10fc\u17d7\u1843\u1d2c\u1d2d\u1d2e\u1d2f\u1d30\u1d31\u1d32\u1d33\u1d34\u1d35\u1d36\u1d37\u1d38\u1d39\u1d3a\u1d3b\u1d3c\u1d3d\u1d3e\u1d3f\u1d40\u1d41\u1d42\u1d43\u1d44\u1d45\u1d46\u1d47\u1d48\u1d49\u1d4a\u1d4b\u1d4c\u1d4d\u1d4 [...]
-
-Lo = u'\u01bb\u01c0\u01c1\u01c2\u01c3\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\u05f0\u05f1\u05f2\u0621\u0622\u0623\u0624\u0625\u0626\u0627\u0628\u0629\u062a\u062b\u062c\u062d\u062e\u062f\u0630\u0631\u0632\u0633\u0634\u0635\u0636\u0637\u0638\u0639\u063a\u0641\u0642\u0643\u0644\u0645\u0646\u0647\u0648\u0649\u064a\u066e\u066f\u0671\u0672\u0673\u0674\u0675\u0676\u0677\u067 [...]
-
-Lt = u'\u01c5\u01c8\u01cb\u01f2\u1f88\u1f89\u1f8a\u1f8b\u1f8c\u1f8d\u1f8e\u1f8f\u1f98\u1f99\u1f9a\u1f9b\u1f9c\u1f9d\u1f9e\u1f9f\u1fa8\u1fa9\u1faa\u1fab\u1fac\u1fad\u1fae\u1faf\u1fbc\u1fcc\u1ffc'
-
-Lu = u'ABCDEFGHIJKLMNOPQRSTUVWXYZ\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xd9\xda\xdb\xdc\xdd\xde\u0100\u0102\u0104\u0106\u0108\u010a\u010c\u010e\u0110\u0112\u0114\u0116\u0118\u011a\u011c\u011e\u0120\u0122\u0124\u0126\u0128\u012a\u012c\u012e\u0130\u0132\u0134\u0136\u0139\u013b\u013d\u013f\u0141\u0143\u0145\u0147\u014a\u014c\u014e\u0150\u0152\u0154\u0156\u0158\u015a\u015c\u015e\u0160\u0162\u0164\u0166\u0168\u016a\u016c\u016e\u0170\u0 [...]
-
-Mc = u'\u0903\u093e\u093f\u0940\u0949\u094a\u094b\u094c\u0982\u0983\u09be\u09bf\u09c0\u09c7\u09c8\u09cb\u09cc\u09d7\u0a03\u0a3e\u0a3f\u0a40\u0a83\u0abe\u0abf\u0ac0\u0ac9\u0acb\u0acc\u0b02\u0b03\u0b3e\u0b40\u0b47\u0b48\u0b4b\u0b4c\u0b57\u0bbe\u0bbf\u0bc1\u0bc2\u0bc6\u0bc7\u0bc8\u0bca\u0bcb\u0bcc\u0bd7\u0c01\u0c02\u0c03\u0c41\u0c42\u0c43\u0c44\u0c82\u0c83\u0cbe\u0cc0\u0cc1\u0cc2\u0cc3\u0cc4\u0cc7\u0cc8\u0cca\u0ccb\u0cd5\u0cd6\u0d02\u0d03\u0d3e\u0d3f\u0d40\u0d46\u0d47\u0d48\u0d4a\u0d4b\u0d4 [...]
-
-Me = u'\u0488\u0489\u06de\u20dd\u20de\u20df\u20e0\u20e2\u20e3\u20e4'
-
-Mn = u'\u0300\u0301\u0302\u0303\u0304\u0305\u0306\u0307\u0308\u0309\u030a\u030b\u030c\u030d\u030e\u030f\u0310\u0311\u0312\u0313\u0314\u0315\u0316\u0317\u0318\u0319\u031a\u031b\u031c\u031d\u031e\u031f\u0320\u0321\u0322\u0323\u0324\u0325\u0326\u0327\u0328\u0329\u032a\u032b\u032c\u032d\u032e\u032f\u0330\u0331\u0332\u0333\u0334\u0335\u0336\u0337\u0338\u0339\u033a\u033b\u033c\u033d\u033e\u033f\u0340\u0341\u0342\u0343\u0344\u0345\u0346\u0347\u0348\u0349\u034a\u034b\u034c\u034d\u034e\u034f\u035 [...]
-
-Nd = u'0123456789\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u0966\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u09e6\u09e7\u09e8\u09e9\u09ea\u09eb\u09ec\u09ed\u09ee\u09ef\u0a66\u0a67\u0a68\u0a69\u0a6a\u0a6b\u0a6c\u0a6d\u0a6e\u0a6f\u0ae6\u0ae7\u0ae8\u0ae9\u0aea\u0aeb\u0aec\u0aed\u0aee\u0aef\u0b66\u0b67\u0b68\u0b69\u0b6a\u0b6b\u0b6c\u0b6d\u0b6e\u0b6f\u0be6\u0be7\u0be8\u0be9\u0bea\u0beb\u0bec\u0bed\u0bee\ [...]
-
-Nl = u'\u16ee\u16ef\u16f0\u2160\u2161\u2162\u2163\u2164\u2165\u2166\u2167\u2168\u2169\u216a\u216b\u216c\u216d\u216e\u216f\u2170\u2171\u2172\u2173\u2174\u2175\u2176\u2177\u2178\u2179\u217a\u217b\u217c\u217d\u217e\u217f\u2180\u2181\u2182\u2183\u3007\u3021\u3022\u3023\u3024\u3025\u3026\u3027\u3028\u3029\u3038\u3039\u303a'
-
-No = u'\xb2\xb3\xb9\xbc\xbd\xbe\u09f4\u09f5\u09f6\u09f7\u09f8\u09f9\u0bf0\u0bf1\u0bf2\u0f2a\u0f2b\u0f2c\u0f2d\u0f2e\u0f2f\u0f30\u0f31\u0f32\u0f33\u1369\u136a\u136b\u136c\u136d\u136e\u136f\u1370\u1371\u1372\u1373\u1374\u1375\u1376\u1377\u1378\u1379\u137a\u137b\u137c\u17f0\u17f1\u17f2\u17f3\u17f4\u17f5\u17f6\u17f7\u17f8\u17f9\u2070\u2074\u2075\u2076\u2077\u2078\u2079\u2080\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089\u2153\u2154\u2155\u2156\u2157\u2158\u2159\u215a\u215b\u215c\u215 [...]
-
-Pc = u'_\u203f\u2040\u2054\ufe33\ufe34\ufe4d\ufe4e\ufe4f\uff3f'
-
-Pd = u'-\u058a\u1806\u2010\u2011\u2012\u2013\u2014\u2015\u2e17\u301c\u3030\u30a0\ufe31\ufe32\ufe58\ufe63\uff0d'
-
-Pe = u')]}\u0f3b\u0f3d\u169c\u2046\u207e\u208e\u232a\u23b5\u2769\u276b\u276d\u276f\u2771\u2773\u2775\u27c6\u27e7\u27e9\u27eb\u2984\u2986\u2988\u298a\u298c\u298e\u2990\u2992\u2994\u2996\u2998\u29d9\u29db\u29fd\u3009\u300b\u300d\u300f\u3011\u3015\u3017\u3019\u301b\u301e\u301f\ufd3f\ufe18\ufe36\ufe38\ufe3a\ufe3c\ufe3e\ufe40\ufe42\ufe44\ufe48\ufe5a\ufe5c\ufe5e\uff09\uff3d\uff5d\uff60\uff63'
-
-Pf = u'\xbb\u2019\u201d\u203a\u2e03\u2e05\u2e0a\u2e0d\u2e1d'
-
-Pi = u'\xab\u2018\u201b\u201c\u201f\u2039\u2e02\u2e04\u2e09\u2e0c\u2e1c'
-
-Po = u'!"#%&\'*,./:;?@\\\xa1\xb7\xbf\u037e\u0387\u055a\u055b\u055c\u055d\u055e\u055f\u0589\u05be\u05c0\u05c3\u05c6\u05f3\u05f4\u060c\u060d\u061b\u061e\u061f\u066a\u066b\u066c\u066d\u06d4\u0700\u0701\u0702\u0703\u0704\u0705\u0706\u0707\u0708\u0709\u070a\u070b\u070c\u070d\u0964\u0965\u0970\u0df4\u0e4f\u0e5a\u0e5b\u0f04\u0f05\u0f06\u0f07\u0f08\u0f09\u0f0a\u0f0b\u0f0c\u0f0d\u0f0e\u0f0f\u0f10\u0f11\u0f12\u0f85\u0fd0\u0fd1\u104a\u104b\u104c\u104d\u104e\u104f\u10fb\u1361\u1362\u1363\u1364\u1365 [...]
-
-Ps = u'([{\u0f3a\u0f3c\u169b\u201a\u201e\u2045\u207d\u208d\u2329\u23b4\u2768\u276a\u276c\u276e\u2770\u2772\u2774\u27c5\u27e6\u27e8\u27ea\u2983\u2985\u2987\u2989\u298b\u298d\u298f\u2991\u2993\u2995\u2997\u29d8\u29da\u29fc\u3008\u300a\u300c\u300e\u3010\u3014\u3016\u3018\u301a\u301d\ufd3e\ufe17\ufe35\ufe37\ufe39\ufe3b\ufe3d\ufe3f\ufe41\ufe43\ufe47\ufe59\ufe5b\ufe5d\uff08\uff3b\uff5b\uff5f\uff62'
-
-Sc = u'$\xa2\xa3\xa4\xa5\u060b\u09f2\u09f3\u0af1\u0bf9\u0e3f\u17db\u20a0\u20a1\u20a2\u20a3\u20a4\u20a5\u20a6\u20a7\u20a8\u20a9\u20aa\u20ab\u20ac\u20ad\u20ae\u20af\u20b0\u20b1\u20b2\u20b3\u20b4\u20b5\ufdfc\ufe69\uff04\uffe0\uffe1\uffe5\uffe6'
-
-Sk = u'^`\xa8\xaf\xb4\xb8\u02c2\u02c3\u02c4\u02c5\u02d2\u02d3\u02d4\u02d5\u02d6\u02d7\u02d8\u02d9\u02da\u02db\u02dc\u02dd\u02de\u02df\u02e5\u02e6\u02e7\u02e8\u02e9\u02ea\u02eb\u02ec\u02ed\u02ef\u02f0\u02f1\u02f2\u02f3\u02f4\u02f5\u02f6\u02f7\u02f8\u02f9\u02fa\u02fb\u02fc\u02fd\u02fe\u02ff\u0374\u0375\u0384\u0385\u1fbd\u1fbf\u1fc0\u1fc1\u1fcd\u1fce\u1fcf\u1fdd\u1fde\u1fdf\u1fed\u1fee\u1fef\u1ffd\u1ffe\u309b\u309c\ua700\ua701\ua702\ua703\ua704\ua705\ua706\ua707\ua708\ua709\ua70a\ua70b\ua70 [...]
-
-Sm = u'+<=>|~\xac\xb1\xd7\xf7\u03f6\u2044\u2052\u207a\u207b\u207c\u208a\u208b\u208c\u2140\u2141\u2142\u2143\u2144\u214b\u2190\u2191\u2192\u2193\u2194\u219a\u219b\u21a0\u21a3\u21a6\u21ae\u21ce\u21cf\u21d2\u21d4\u21f4\u21f5\u21f6\u21f7\u21f8\u21f9\u21fa\u21fb\u21fc\u21fd\u21fe\u21ff\u2200\u2201\u2202\u2203\u2204\u2205\u2206\u2207\u2208\u2209\u220a\u220b\u220c\u220d\u220e\u220f\u2210\u2211\u2212\u2213\u2214\u2215\u2216\u2217\u2218\u2219\u221a\u221b\u221c\u221d\u221e\u221f\u2220\u2221\u2222\ [...]
-
-So = u'\xa6\xa7\xa9\xae\xb0\xb6\u0482\u060e\u060f\u06e9\u06fd\u06fe\u09fa\u0b70\u0bf3\u0bf4\u0bf5\u0bf6\u0bf7\u0bf8\u0bfa\u0f01\u0f02\u0f03\u0f13\u0f14\u0f15\u0f16\u0f17\u0f1a\u0f1b\u0f1c\u0f1d\u0f1e\u0f1f\u0f34\u0f36\u0f38\u0fbe\u0fbf\u0fc0\u0fc1\u0fc2\u0fc3\u0fc4\u0fc5\u0fc7\u0fc8\u0fc9\u0fca\u0fcb\u0fcc\u0fcf\u1360\u1390\u1391\u1392\u1393\u1394\u1395\u1396\u1397\u1398\u1399\u1940\u19e0\u19e1\u19e2\u19e3\u19e4\u19e5\u19e6\u19e7\u19e8\u19e9\u19ea\u19eb\u19ec\u19ed\u19ee\u19ef\u19f0\u19f [...]
-
-Zl = u'\u2028'
-
-Zp = u'\u2029'
-
-Zs = u' \xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
-
-cats = ['Cc', 'Cf', 'Cn', 'Co', 'Cs', 'Ll', 'Lm', 'Lo', 'Lt', 'Lu', 'Mc', 'Me', 'Mn', 'Nd', 'Nl', 'No', 'Pc', 'Pd', 'Pe', 'Pf', 'Pi', 'Po', 'Ps', 'Sc', 'Sk', 'Sm', 'So', 'Zl', 'Zp', 'Zs']
-
-def combine(*args):
- return u''.join([globals()[cat] for cat in args])
-
-xid_start = u'\u0041-\u005A\u005F\u0061-\u007A\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u01BA\u01BB\u01BC-\u01BF\u01C0-\u01C3\u01C4-\u0241\u0250-\u02AF\u02B0-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EE\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03CE\u03D0-\u03F5\u03F7-\u0481\u048A-\u04CE\u04D0-\u04F9\u0500-\u050F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0621-\u063A\u0640\u0641-\u064A\u066E-\u066F\u0671-\u06D3\u06D5\u06E5-\u06E6\u06EE-\u06EF\u06FA-\u06FC\u06FF\u0 [...]
-
-xid_continue = u'\u0030-\u0039\u0041-\u005A\u005F\u0061-\u007A\u00AA\u00B5\u00B7\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u01BA\u01BB\u01BC-\u01BF\u01C0-\u01C3\u01C4-\u0241\u0250-\u02AF\u02B0-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EE\u0300-\u036F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03CE\u03D0-\u03F5\u03F7-\u0481\u0483-\u0486\u048A-\u04CE\u04D0-\u04F9\u0500-\u050F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05B9\u05BB-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2 [...]
-
-def allexcept(*args):
- newcats = cats[:]
- for arg in args:
- newcats.remove(arg)
- return u''.join([globals()[cat] for cat in newcats])
+xid_start = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz\xaa\xb5\xba\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\u0100\u0101\u0102\u0103\u0104\u0105\u0106\u0107\u0108\u0109\u010a\u010b\u010c\u010d\u010e\u010f\u0110\u0111\u0112\u0113\u0114\u0115\u0116\u0117\u0118\u0119\u011a\u01 [...]
+xid_continue = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz\xaa\xb5\xb7\xba\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\u0100\u0101\u0102\u0103\u0104\u0105\u0106\u0107\u0108\u0109\u010a\u010b\u010c\u010d\u010e\u010f\u0110\u0111\u0112\u0113\u0114\u0115\u0116\u0117\u011 [...]
+# Generated code end
if __name__ == '__main__':
+ import sys
import unicodedata
+ if sys.version_info[0] < 3:
+ raise RuntimeError('This needs to run on python 3')
+
categories = {}
f = open(__file__.rstrip('co'))
@@ -104,29 +34,38 @@ if __name__ == '__main__':
finally:
f.close()
- header = content[:content.find('Cc =')]
- footer = content[content.find("def combine("):]
+ start = '# Generated code start\n'
+ header = content[:content.find(start) + len(start)] + '\n'
+ footer = content[content.find("# Generated code end\n"):]
for code in range(65535):
- c = unichr(code)
+ c = chr(code)
cat = unicodedata.category(c)
categories.setdefault(cat, []).append(c)
+ # from 8.0.0 PropList (Other_ID_Start) + underscore
+ id_start = set(u'_\u2118\u212E\u309B\u309C')
+ for cat in 'Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nl':
+ id_start.update(categories[cat])
+
+ # from 8.0.0 PropList (Other_ID_Continue)
+ id_continue = set(id_start)
+ id_continue.update(u'\u00B7\u0387\u1369\u1370\u1371\u19DA')
+ for cat in 'Mn', 'Mc', 'Nd', 'Pc':
+ id_continue.update(categories[cat])
+
+ xid_start = u''.join(sorted(c for c in id_continue if
+ unicodedata.normalize('NFKC', c)
+ in id_start))
+ xid_continue = u''.join(sorted(c for c in id_continue if
+ unicodedata.normalize('NFKC', c) in
+ id_continue))
+
f = open(__file__, 'w')
f.write(header)
- for cat in sorted(categories):
- val = u''.join(categories[cat])
- if cat == 'Cs':
- # Jython can't handle isolated surrogates
- f.write("""\
-try:
- Cs = eval(r"%r")
-except UnicodeDecodeError:
- Cs = '' # Jython can't handle isolated surrogates\n\n""" % val)
- else:
- f.write('%s = %r\n\n' % (cat, val))
- f.write('cats = %r\n\n' % sorted(categories.keys()))
+ f.write('xid_start = %s\nxid_continue = %s\n' % (ascii(xid_start),
+ ascii(xid_continue)))
f.write(footer)
f.close()
diff --git a/jinja2/asyncsupport.py b/jinja2/asyncsupport.py
index 6e82d75..f4f264a 100644
--- a/jinja2/asyncsupport.py
+++ b/jinja2/asyncsupport.py
@@ -96,6 +96,22 @@ def wrap_block_reference_call(original_call):
return update_wrapper(__call__, original_call)
+def wrap_macro_invoke(original_invoke):
+ @internalcode
+ async def async_invoke(self, arguments, autoescape):
+ rv = await self._func(*arguments)
+ if autoescape:
+ rv = Markup(rv)
+ return rv
+
+ @internalcode
+ def _invoke(self, arguments, autoescape):
+ if not self._environment.is_async:
+ return original_invoke(self, arguments, autoescape)
+ return async_invoke(self, arguments, autoescape)
+ return update_wrapper(_invoke, original_invoke)
+
+
@internalcode
async def get_default_module_async(self):
if self._module is not None:
@@ -138,9 +154,10 @@ def patch_template():
def patch_runtime():
- from jinja2.runtime import BlockReference
+ from jinja2.runtime import BlockReference, Macro
BlockReference.__call__ = wrap_block_reference_call(
BlockReference.__call__)
+ Macro._invoke = wrap_macro_invoke(Macro._invoke)
def patch_filters():
diff --git a/jinja2/compiler.py b/jinja2/compiler.py
index 48f3210..b2ab6fe 100644
--- a/jinja2/compiler.py
+++ b/jinja2/compiler.py
@@ -734,12 +734,13 @@ class CodeGenerator(NodeVisitor):
self.indent()
self.writeline('if parent_template is not None:')
self.indent()
- if supports_yield_from:
+ if supports_yield_from and not self.environment.is_async:
self.writeline('yield from parent_template.'
'root_render_func(context)')
else:
- self.writeline('for event in parent_template.'
- 'root_render_func(context):')
+ self.writeline('%sfor event in parent_template.'
+ 'root_render_func(context):' %
+ (self.environment.is_async and 'async ' or ''))
self.indent()
self.writeline('yield event')
self.outdent()
@@ -1040,6 +1041,9 @@ class CodeGenerator(NodeVisitor):
self.indent()
self.buffer(loop_frame)
+ # Use the same buffer for the else frame
+ else_frame.buffer = loop_frame.buffer
+
# make sure the loop variable is a special one and raise a template
# assertion error if a loop tries to write to loop
if extended_loop:
diff --git a/jinja2/filters.py b/jinja2/filters.py
index f4cd796..76e04db 100644
--- a/jinja2/filters.py
+++ b/jinja2/filters.py
@@ -18,7 +18,7 @@ from jinja2.utils import Markup, escape, pformat, urlize, soft_unicode, \
unicode_urlencode, htmlsafe_json_dumps
from jinja2.runtime import Undefined
from jinja2.exceptions import FilterArgumentError
-from jinja2._compat import imap, string_types, text_type, iteritems
+from jinja2._compat import imap, string_types, text_type, iteritems, PY2
_word_re = re.compile(r'\w+', re.UNICODE)
@@ -688,7 +688,14 @@ def do_round(value, precision=0, method='common'):
return func(value * (10 ** precision)) / (10 ** precision)
+# Use a regular tuple repr here. This is what we did in the past and we
+# really want to hide this custom type as much as possible. In particular
+# we do not want to accidentally expose an auto generated repr in case
+# people start to print this out in comments or something similar for
+# debugging.
_GroupTuple = namedtuple('_GroupTuple', ['grouper', 'list'])
+_GroupTuple.__repr__ = tuple.__repr__
+_GroupTuple.__str__ = tuple.__str__
@environmentfilter
def do_groupby(environment, value, attribute):
diff --git a/jinja2/lexer.py b/jinja2/lexer.py
index 13c62da..30e82fb 100644
--- a/jinja2/lexer.py
+++ b/jinja2/lexer.py
@@ -15,6 +15,7 @@
:license: BSD, see LICENSE for more details.
"""
import re
+import sys
from operator import itemgetter
from collections import deque
@@ -33,17 +34,29 @@ string_re = re.compile(r"('([^'\\]*(?:\\.[^'\\]*)*)'"
r'|"([^"\\]*(?:\\.[^"\\]*)*)")', re.S)
integer_re = re.compile(r'\d+')
-# we use the unicode identifier rule if this python version is able
-# to handle unicode identifiers, otherwise the standard ASCII one.
-try:
- compile('föö', '<unknown>', 'eval')
-except SyntaxError:
- name_re = re.compile(r'\b[a-zA-Z_][a-zA-Z0-9_]*\b')
-else:
+def _make_name_re():
+ try:
+ compile('föö', '<unknown>', 'eval')
+ except SyntaxError:
+ return re.compile(r'\b[a-zA-Z_][a-zA-Z0-9_]*\b')
+
+ import jinja2
from jinja2 import _stringdefs
name_re = re.compile(r'[%s][%s]*' % (_stringdefs.xid_start,
_stringdefs.xid_continue))
+ # Save some memory here
+ sys.modules.pop('jinja2._stringdefs')
+ del _stringdefs
+ del jinja2._stringdefs
+
+ return name_re
+
+# we use the unicode identifier rule if this python version is able
+# to handle unicode identifiers, otherwise the standard ASCII one.
+name_re = _make_name_re()
+del _make_name_re
+
float_re = re.compile(r'(?<!\.)\d+\.\d+')
newline_re = re.compile(r'(\r\n|\r|\n)')
diff --git a/jinja2/runtime.py b/jinja2/runtime.py
index 03e303f..2443001 100644
--- a/jinja2/runtime.py
+++ b/jinja2/runtime.py
@@ -17,7 +17,8 @@ from jinja2.utils import Markup, soft_unicode, escape, missing, concat, \
from jinja2.exceptions import UndefinedError, TemplateRuntimeError, \
TemplateNotFound
from jinja2._compat import imap, text_type, iteritems, \
- implements_iterator, implements_to_string, string_types, PY2
+ implements_iterator, implements_to_string, string_types, PY2, \
+ with_metaclass
# these variables are exported to the template runtime
@@ -90,7 +91,43 @@ class TemplateReference(object):
)
-class Context(object):
+def _get_func(x):
+ return getattr(x, '__func__', x)
+
+
+class ContextMeta(type):
+
+ def __new__(cls, name, bases, d):
+ rv = type.__new__(cls, name, bases, d)
+ if bases == ():
+ return rv
+
+ resolve = _get_func(rv.resolve)
+ default_resolve = _get_func(Context.resolve)
+ resolve_or_missing = _get_func(rv.resolve_or_missing)
+ default_resolve_or_missing = _get_func(Context.resolve_or_missing)
+
+ # If we have a changed resolve but no changed default or missing
+ # resolve we invert the call logic.
+ if resolve is not default_resolve and \
+ resolve_or_missing is default_resolve_or_missing:
+ rv._legacy_resolve_mode = True
+ elif resolve is default_resolve and \
+ resolve_or_missing is default_resolve_or_missing:
+ rv._fast_resolve_mode = True
+
+ return rv
+
+
+def resolve_or_missing(context, key, missing=missing):
+ if key in context.vars:
+ return context.vars[key]
+ if key in context.parent:
+ return context.parent[key]
+ return missing
+
+
+class Context(with_metaclass(ContextMeta)):
"""The template context holds the variables of a template. It stores the
values passed to the template and also the names the template exports.
Creating instances is neither supported nor useful as it's created
@@ -109,8 +146,10 @@ class Context(object):
method that doesn't fail with a `KeyError` but returns an
:class:`Undefined` object for missing variables.
"""
- __slots__ = ('parent', 'vars', 'environment', 'eval_ctx', 'exported_vars',
- 'name', 'blocks', '__weakref__')
+ # XXX: we want to eventually make this be a deprecation warning and
+ # remove it.
+ _legacy_resolve_mode = False
+ _fast_resolve_mode = False
def __init__(self, environment, parent, name, blocks):
self.parent = parent
@@ -125,6 +164,11 @@ class Context(object):
# from the template.
self.blocks = dict((k, [v]) for k, v in iteritems(blocks))
+ # In case we detect the fast resolve mode we can set up an alias
+ # here that bypasses the legacy code logic.
+ if self._fast_resolve_mode:
+ self.resolve_or_missing = resolve_or_missing
+
def super(self, name, current):
"""Render a parent block."""
try:
@@ -150,7 +194,10 @@ class Context(object):
"""Looks up a variable like `__getitem__` or `get` but returns an
:class:`Undefined` object with the name of the name looked up.
"""
- rv = self.resolve_or_missing(key)
+ if self._legacy_resolve_mode:
+ rv = resolve_or_missing(self, key)
+ else:
+ rv = self.resolve_or_missing(key)
if rv is missing:
return self.environment.undefined(name=key)
return rv
@@ -159,11 +206,12 @@ class Context(object):
"""Resolves a variable like :meth:`resolve` but returns the
special `missing` value if it cannot be found.
"""
- if key in self.vars:
- return self.vars[key]
- if key in self.parent:
- return self.parent[key]
- return missing
+ if self._legacy_resolve_mode:
+ rv = self.resolve(key)
+ if isinstance(rv, Undefined):
+ rv = missing
+ return rv
+ return resolve_or_missing(self, key)
def get_exported(self):
"""Get a new dict with the exported variables."""
@@ -496,6 +544,10 @@ class Macro(object):
raise TypeError('macro %r takes not more than %d argument(s)' %
(self.name, len(self.arguments)))
+ return self._invoke(arguments, autoescape)
+
+ def _invoke(self, arguments, autoescape):
+ """This method is being swapped out by the async implementation."""
rv = self._func(*arguments)
if autoescape:
rv = Markup(rv)
diff --git a/setup.py b/setup.py
index 3c74b64..391c140 100644
--- a/setup.py
+++ b/setup.py
@@ -40,7 +40,7 @@ from setuptools import setup
setup(
name='Jinja2',
- version='2.9.4',
+ version='2.9.5',
url='http://jinja.pocoo.org/',
license='BSD',
author='Armin Ronacher',
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/jinja2.git
More information about the Python-modules-commits
mailing list