From 126fce8b049e94ffda5adc3b1c3a301998923c98 Mon Sep 17 00:00:00 2001 From: David Lord Date: Fri, 10 Jan 2020 11:10:19 -0800 Subject: more relative imports _identifier exports a compiled regex instead of a string to avoid some tricky cleanup --- scripts/generate_identifier_pattern.py | 11 +++++++---- src/jinja2/_identifier.py | 6 +++++- src/jinja2/asyncsupport.py | 8 ++++---- src/jinja2/compiler.py | 2 +- src/jinja2/environment.py | 6 +++--- src/jinja2/exceptions.py | 4 ++-- src/jinja2/lexer.py | 17 ++++------------- src/jinja2/utils.py | 11 ++++++----- 8 files changed, 32 insertions(+), 33 deletions(-) diff --git a/scripts/generate_identifier_pattern.py b/scripts/generate_identifier_pattern.py index 845a441..5813199 100755 --- a/scripts/generate_identifier_pattern.py +++ b/scripts/generate_identifier_pattern.py @@ -58,17 +58,20 @@ def build_pattern(ranges): def main(): - """Build the regex pattern and write it to the file - :file:`jinja2/_identifier.py`.""" + """Build the regex pattern and write it to + ``jinja2/_identifier.py``. + """ pattern = build_pattern(collapse_ranges(get_characters())) filename = os.path.abspath( os.path.join(os.path.dirname(__file__), "..", "src", "jinja2", "_identifier.py") ) with open(filename, "w", encoding="utf8") as f: - f.write("") + f.write("import re\n\n") f.write("# generated by scripts/generate_identifier_pattern.py\n") - f.write('pattern = "{}" # noqa: B950\n'.format(pattern)) + f.write("pattern = re.compile(\n") + f.write(' r"[\\w{}]+" # noqa: B950\n'.format(pattern)) + f.write(")\n") if __name__ == "__main__": diff --git a/src/jinja2/_identifier.py b/src/jinja2/_identifier.py index 2490963..224d544 100644 --- a/src/jinja2/_identifier.py +++ b/src/jinja2/_identifier.py @@ -1,2 +1,6 @@ +import re + # generated by scripts/generate_identifier_pattern.py -pattern = "·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٟۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࣔ-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣঁ-ঃ়া-ৄেৈো-্ৗৢৣਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑੰੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣஂா-ூெ-ைொ-்ௗఀ-ఃా-ౄె-ైొ-్ౕౖౢౣಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣഁ-ഃാ-ൄെ-ൈൊ-്ൗൢൣංඃ්ා-ුූෘ-ෟෲෳัิ-ฺ็-๎ັິ-ູົຼ່-ໍ༹༘༙༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏႚ-ႝ፝-፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝᠋-᠍ᢅᢆᢩᤠ-ᤫᤰ-᤻ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼᪰-᪽ᬀ-ᬄ᬴-᭄᭫-᭳ᮀ-ᮂᮡ-ᮭ᯦-᯳ᰤ-᰷᳐-᳔᳒-᳨᳭ᳲ-᳴᳸᳹᷀-᷵᷻-᷿‿⁀⁔⃐-⃥⃜⃡-⃰℘℮⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꙯ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-ꣅ꣠-꣱ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀ꧥꨩ-ꨶꩃꩌꩍꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭ﬞ︀-️︠-︯︳︴﹍-﹏_𐇽𐋠𐍶-𐍺𐨁-𐨃𐨅𐨆𐨌-𐨏𐨸-𐨿𐨺𐫦𐫥𑀀-𑀂𑀸-𑁆𑁿-𑂂𑂰-𑂺𑄀-𑄂𑄧-𑅳𑄴𑆀-𑆂𑆳-𑇊𑇀-𑇌𑈬-𑈷𑈾𑋟-𑋪𑌀-𑌃𑌼𑌾-𑍄𑍇𑍈𑍋-𑍍𑍗𑍢𑍣𑍦-𑍬𑍰-𑍴𑐵-𑑆𑒰-𑓃𑖯-𑖵𑖸-𑗀𑗜𑗝𑘰-𑙀𑚫-𑚷𑜝-𑜫𑰯-𑰶𑰸-𑰿𑲒-𑲧𑲩-𑲶𖫰-𖫴𖬰-𖬶𖽑-𖽾𖾏-𖾒𛲝𛲞𝅥-𝅩𝅭-𝅲𝅻-𝆂𝆅-𝆋𝆪-𝆭𝉂-𝉄𝨀-𝨶𝨻-𝩬𝩵𝪄𝪛-𝪟𝪡-𝪯𞀀-𞀆𞀈-𞀘𞀛-𞀡𞀣𞀤𞀦-𞣐𞀪-𞣖𞥄-𞥊󠄀-󠇯" # noqa: B950 +pattern = re.compile( + r"[\w·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٟۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࣔ-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣঁ-ঃ়া-ৄেৈো-্ৗৢৣਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑੰੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣஂா-ூெ-ைொ-்ௗఀ-ఃా-ౄె-ైొ-్ౕౖౢౣಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣഁ-ഃാ-ൄെ-ൈൊ-്ൗൢൣංඃ්ා-ුූෘ-ෟෲෳัิ-ฺ็-๎ັິ-ູົຼ່-ໍ༹༘༙༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏႚ-ႝ፝-፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝᠋-᠍ᢅᢆᢩᤠ-ᤫᤰ-᤻ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼᪰-᪽ᬀ-ᬄ᬴-᭄᭫-᭳ᮀ-ᮂᮡ-ᮭ᯦-᯳ᰤ-᰷᳐-᳔᳒-᳨᳭ᳲ-᳴᳸᳹᷀-᷵᷻-᷿‿⁀⁔⃐-⃥⃜⃡-⃰℘℮⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꙯ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-ꣅ꣠-꣱ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀ꧥꨩ-ꨶꩃꩌꩍꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭ﬞ︀-️︠-︯︳︴﹍-﹏_𐇽𐋠𐍶-𐍺𐨁-𐨃𐨅𐨆𐨌-𐨏𐨸-𐨿𐨺𐫦𐫥𑀀-𑀂𑀸-𑁆𑁿-𑂂𑂰-𑂺𑄀-𑄂𑄧-𑅳𑄴𑆀-𑆂𑆳-𑇊𑇀-𑇌𑈬-𑈷𑈾𑋟-𑋪𑌀-𑌃𑌼𑌾-𑍄𑍇𑍈𑍋-𑍍𑍗𑍢𑍣𑍦-𑍬𑍰-𑍴𑐵-𑑆𑒰-𑓃𑖯-𑖵𑖸-𑗀𑗜𑗝𑘰-𑙀𑚫-𑚷𑜝-𑜫𑰯-𑰶𑰸-𑰿𑲒-𑲧𑲩-𑲶𖫰-𖫴𖬰-𖬶𖽑-𖽾𖾏-𖾒𛲝𛲞𝅥-𝅩𝅭-𝅲𝅻-𝆂𝆅-𝆋𝆪-𝆭𝉂-𝉄𝨀-𝨶𝨻-𝩬𝩵𝪄𝪛-𝪟𝪡-𝪯𞀀-𞀆𞀈-𞀘𞀛-𞀡𞀣𞀤𞀦-𞣐𞀪-𞣖𞥄-𞥊󠄀-󠇯]+" # noqa: B950 +) diff --git a/src/jinja2/asyncsupport.py b/src/jinja2/asyncsupport.py index b2fd6e4..7a0c2ea 100644 --- a/src/jinja2/asyncsupport.py +++ b/src/jinja2/asyncsupport.py @@ -142,7 +142,7 @@ async def make_module_async(self, vars=None, shared=False, locals=None): def patch_template(): - from jinja2 import Template + from . import Template Template.generate = wrap_generate_func(Template.generate) Template.generate_async = update_wrapper(generate_async, Template.generate_async) @@ -156,15 +156,15 @@ def patch_template(): def patch_runtime(): - from jinja2.runtime import BlockReference, Macro + from .runtime import BlockReference, Macro BlockReference.__call__ = wrap_block_reference_call(BlockReference.__call__) Macro._invoke = wrap_macro_invoke(Macro._invoke) def patch_filters(): - from jinja2.filters import FILTERS - from jinja2.asyncfilters import ASYNC_FILTERS + from .filters import FILTERS + from .asyncfilters import ASYNC_FILTERS FILTERS.update(ASYNC_FILTERS) diff --git a/src/jinja2/compiler.py b/src/jinja2/compiler.py index 068ad56..169687a 100644 --- a/src/jinja2/compiler.py +++ b/src/jinja2/compiler.py @@ -720,7 +720,7 @@ class CodeGenerator(NodeVisitor): assert frame is None, "no root frame allowed" eval_ctx = EvalContext(self.environment, self.name) - from jinja2.runtime import __all__ as exported + from .runtime import __all__ as exported self.writeline("from __future__ import %s" % ", ".join(code_features)) self.writeline("from jinja2.runtime import " + ", ".join(exported)) diff --git a/src/jinja2/environment.py b/src/jinja2/environment.py index 33a7b23..a50a6a8 100644 --- a/src/jinja2/environment.py +++ b/src/jinja2/environment.py @@ -367,7 +367,7 @@ class Environment(object): self.is_async = self.enable_async and have_async_gen if self.is_async: # runs patch_all() to enable async support - import jinja2.asyncsupport # noqa: F401 + from . import asyncsupport # noqa: F401 _environment_sanity_check(self) @@ -718,7 +718,7 @@ class Environment(object): .. versionadded:: 2.4 """ - from jinja2.loaders import ModuleLoader + from .loaders import ModuleLoader if log_function is None: @@ -832,7 +832,7 @@ class Environment(object): """Exception handling helper. This is used internally to either raise rewritten exceptions or return a rendered traceback for the template. """ - from jinja2.debug import rewrite_traceback_stack + from .debug import rewrite_traceback_stack reraise(*rewrite_traceback_stack(source=source)) diff --git a/src/jinja2/exceptions.py b/src/jinja2/exceptions.py index 1038370..8fa45c4 100644 --- a/src/jinja2/exceptions.py +++ b/src/jinja2/exceptions.py @@ -64,7 +64,7 @@ class TemplateNotFound(IOError, LookupError, TemplateError): IOError.__init__(self, name) if message is None: - from jinja2.runtime import Undefined + from .runtime import Undefined if isinstance(name, Undefined): name._fail_with_undefined_error() @@ -93,7 +93,7 @@ class TemplatesNotFound(TemplateNotFound): def __init__(self, names=(), message=None): if message is None: - from jinja2.runtime import Undefined + from .runtime import Undefined parts = [] diff --git a/src/jinja2/lexer.py b/src/jinja2/lexer.py index a9585ef..7c53d5d 100644 --- a/src/jinja2/lexer.py +++ b/src/jinja2/lexer.py @@ -55,24 +55,15 @@ try: # check if this Python supports Unicode identifiers compile("föö", "", "eval") except SyntaxError: - # no Unicode support, use ASCII identifiers + # Python 2, no Unicode support, use ASCII identifiers name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*") check_ident = False else: - # Unicode support, build a pattern to match valid characters, and set flag - # to use str.isidentifier to validate during lexing - from jinja2 import _identifier + # Unicode support, import generated re pattern and set flag to use + # str.isidentifier to validate during lexing. + from ._identifier import pattern as name_re - name_re = re.compile(r"[\w{0}]+".format(_identifier.pattern)) check_ident = True - # remove the pattern from memory after building the regex - import sys - - del sys.modules["jinja2._identifier"] - import jinja2 - - del jinja2._identifier - del _identifier # internal the tokens and keep references to them TOKEN_ADD = intern("add") diff --git a/src/jinja2/utils.py b/src/jinja2/utils.py index e429428..3d0051b 100644 --- a/src/jinja2/utils.py +++ b/src/jinja2/utils.py @@ -13,6 +13,8 @@ import os import re import warnings from collections import deque +from random import choice +from random import randrange from threading import Lock from markupsafe import escape @@ -105,7 +107,7 @@ def is_undefined(obj): return default return var """ - from jinja2.runtime import Undefined + from .runtime import Undefined return isinstance(obj, Undefined) @@ -122,8 +124,8 @@ def clear_caches(): the time. Normally you don't have to care about that but if you are measuring memory consumption you may want to clean the caches. """ - from jinja2.environment import _spontaneous_environments - from jinja2.lexer import _lexer_cache + from .environment import _spontaneous_environments + from .lexer import _lexer_cache _spontaneous_environments.clear() _lexer_cache.clear() @@ -260,8 +262,7 @@ def urlize(text, trim_url_limit=None, rel=None, target=None): def generate_lorem_ipsum(n=5, html=True, min=20, max=100): """Generate some lorem ipsum for the template.""" - from jinja2.constants import LOREM_IPSUM_WORDS - from random import choice, randrange + from .constants import LOREM_IPSUM_WORDS words = LOREM_IPSUM_WORDS.split() result = [] -- cgit v1.2.1