[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