diff options
| author | Hasan Ramezani <hasan.r67@gmail.com> | 2019-10-26 16:42:32 +0200 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2019-10-29 09:22:26 +0100 |
| commit | e3d0b4d5501c6d0bc39f035e4345e5bdfde12e41 (patch) | |
| tree | a8ddbafdf4a38a87df6f65fc4d02dba08c725096 /django/utils | |
| parent | 39a34d4bf94bc8325119bc23b64f3a041a85dd2d (diff) | |
Fixed #30899 -- Lazily compiled import time regular expressions.
Diffstat (limited to 'django/utils')
| -rw-r--r-- | django/utils/cache.py | 4 | ||||
| -rw-r--r-- | django/utils/dateformat.py | 6 | ||||
| -rw-r--r-- | django/utils/dateparse.py | 14 | ||||
| -rw-r--r-- | django/utils/datetime_safe.py | 5 | ||||
| -rw-r--r-- | django/utils/html.py | 12 | ||||
| -rw-r--r-- | django/utils/http.py | 11 | ||||
| -rw-r--r-- | django/utils/text.py | 15 | ||||
| -rw-r--r-- | django/utils/translation/__init__.py | 4 | ||||
| -rw-r--r-- | django/utils/translation/template.py | 16 | ||||
| -rw-r--r-- | django/utils/translation/trans_real.py | 7 |
10 files changed, 51 insertions, 43 deletions
diff --git a/django/utils/cache.py b/django/utils/cache.py index 14e8256b94..df9c4c755a 100644 --- a/django/utils/cache.py +++ b/django/utils/cache.py @@ -17,7 +17,6 @@ An example: i18n middleware would need to distinguish caches by the "Accept-language" header. """ import hashlib -import re import time from collections import defaultdict @@ -29,10 +28,11 @@ from django.utils.http import ( http_date, parse_etags, parse_http_date_safe, quote_etag, ) from django.utils.log import log_response +from django.utils.regex_helper import _lazy_re_compile from django.utils.timezone import get_current_timezone_name from django.utils.translation import get_language -cc_delim_re = re.compile(r'\s*,\s*') +cc_delim_re = _lazy_re_compile(r'\s*,\s*') def patch_cache_control(response, **kwargs): diff --git a/django/utils/dateformat.py b/django/utils/dateformat.py index d3f586aacf..836b40a70a 100644 --- a/django/utils/dateformat.py +++ b/django/utils/dateformat.py @@ -12,17 +12,17 @@ Usage: """ import calendar import datetime -import re import time from django.utils.dates import ( MONTHS, MONTHS_3, MONTHS_ALT, MONTHS_AP, WEEKDAYS, WEEKDAYS_ABBR, ) +from django.utils.regex_helper import _lazy_re_compile from django.utils.timezone import get_default_timezone, is_aware, is_naive from django.utils.translation import gettext as _ -re_formatchars = re.compile(r'(?<!\\)([aAbBcdDeEfFgGhHiIjlLmMnNoOPrsStTUuwWyYzZ])') -re_escaped = re.compile(r'\\(.)') +re_formatchars = _lazy_re_compile(r'(?<!\\)([aAbBcdDeEfFgGhHiIjlLmMnNoOPrsStTUuwWyYzZ])') +re_escaped = _lazy_re_compile(r'\\(.)') class Formatter: diff --git a/django/utils/dateparse.py b/django/utils/dateparse.py index f90d952581..d142e161b6 100644 --- a/django/utils/dateparse.py +++ b/django/utils/dateparse.py @@ -6,27 +6,27 @@ # - The date/datetime/time constructors produce friendlier error messages. import datetime -import re +from django.utils.regex_helper import _lazy_re_compile from django.utils.timezone import get_fixed_timezone, utc -date_re = re.compile( +date_re = _lazy_re_compile( r'(?P<year>\d{4})-(?P<month>\d{1,2})-(?P<day>\d{1,2})$' ) -time_re = re.compile( +time_re = _lazy_re_compile( r'(?P<hour>\d{1,2}):(?P<minute>\d{1,2})' r'(?::(?P<second>\d{1,2})(?:\.(?P<microsecond>\d{1,6})\d{0,6})?)?' ) -datetime_re = re.compile( +datetime_re = _lazy_re_compile( r'(?P<year>\d{4})-(?P<month>\d{1,2})-(?P<day>\d{1,2})' r'[T ](?P<hour>\d{1,2}):(?P<minute>\d{1,2})' r'(?::(?P<second>\d{1,2})(?:\.(?P<microsecond>\d{1,6})\d{0,6})?)?' r'(?P<tzinfo>Z|[+-]\d{2}(?::?\d{2})?)?$' ) -standard_duration_re = re.compile( +standard_duration_re = _lazy_re_compile( r'^' r'(?:(?P<days>-?\d+) (days?, )?)?' r'(?P<sign>-?)' @@ -39,7 +39,7 @@ standard_duration_re = re.compile( # Support the sections of ISO 8601 date representation that are accepted by # timedelta -iso8601_duration_re = re.compile( +iso8601_duration_re = _lazy_re_compile( r'^(?P<sign>[-+]?)' r'P' r'(?:(?P<days>\d+(.\d+)?)D)?' @@ -54,7 +54,7 @@ iso8601_duration_re = re.compile( # Support PostgreSQL's day-time interval format, e.g. "3 days 04:05:06". The # year-month and mixed intervals cannot be converted to a timedelta and thus # aren't accepted. -postgres_interval_re = re.compile( +postgres_interval_re = _lazy_re_compile( r'^' r'(?:(?P<days>-?\d+) (days? ?))?' r'(?:(?P<sign>[-+])?' diff --git a/django/utils/datetime_safe.py b/django/utils/datetime_safe.py index 7eaa5c21ce..ade2dca610 100644 --- a/django/utils/datetime_safe.py +++ b/django/utils/datetime_safe.py @@ -7,12 +7,13 @@ # >>> datetime_safe.date(10, 8, 2).strftime("%Y/%m/%d was a %A") # '0010/08/02 was a Monday' -import re import time as ttime from datetime import ( date as real_date, datetime as real_datetime, time as real_time, ) +from django.utils.regex_helper import _lazy_re_compile + class date(real_date): def strftime(self, fmt): @@ -54,7 +55,7 @@ def new_datetime(d): # This library does not support strftime's "%s" or "%y" format strings. # Allowed if there's an even number of "%"s because they are escaped. -_illegal_formatting = re.compile(r"((^|[^%])(%%)*%[sy])") +_illegal_formatting = _lazy_re_compile(r"((^|[^%])(%%)*%[sy])") def _findall(text, substr): diff --git a/django/utils/html.py b/django/utils/html.py index 94aa0ff35e..2b8f2a8c89 100644 --- a/django/utils/html.py +++ b/django/utils/html.py @@ -11,6 +11,7 @@ from urllib.parse import ( from django.utils.encoding import punycode from django.utils.functional import Promise, keep_lazy, keep_lazy_text from django.utils.http import RFC3986_GENDELIMS, RFC3986_SUBDELIMS +from django.utils.regex_helper import _lazy_re_compile from django.utils.safestring import SafeData, SafeString, mark_safe from django.utils.text import normalize_newlines @@ -21,10 +22,13 @@ WRAPPING_PUNCTUATION = [('(', ')'), ('[', ']')] # List of possible strings used for bullets in bulleted lists. DOTS = ['·', '*', '\u2022', '•', '•', '•'] -unencoded_ampersands_re = re.compile(r'&(?!(\w+|#\d+);)') -word_split_re = re.compile(r'''([\s<>"']+)''') -simple_url_re = re.compile(r'^https?://\[?\w', re.IGNORECASE) -simple_url_2_re = re.compile(r'^www\.|^(?!http)\w[^@]+\.(com|edu|gov|int|mil|net|org)($|/.*)$', re.IGNORECASE) +unencoded_ampersands_re = _lazy_re_compile(r'&(?!(\w+|#\d+);)') +word_split_re = _lazy_re_compile(r'''([\s<>"']+)''') +simple_url_re = _lazy_re_compile(r'^https?://\[?\w', re.IGNORECASE) +simple_url_2_re = _lazy_re_compile( + r'^www\.|^(?!http)\w[^@]+\.(com|edu|gov|int|mil|net|org)($|/.*)$', + re.IGNORECASE +) @keep_lazy(str, SafeString) diff --git a/django/utils/http.py b/django/utils/http.py index ff2f08ac1e..709ce60e1f 100644 --- a/django/utils/http.py +++ b/django/utils/http.py @@ -16,9 +16,10 @@ from django.core.exceptions import TooManyFieldsSent from django.utils.datastructures import MultiValueDict from django.utils.deprecation import RemovedInDjango40Warning from django.utils.functional import keep_lazy_text +from django.utils.regex_helper import _lazy_re_compile # based on RFC 7232, Appendix C -ETAG_MATCH = re.compile(r''' +ETAG_MATCH = _lazy_re_compile(r''' \A( # start of string and capture group (?:W/)? # optional weak indicator " # opening quote @@ -34,14 +35,14 @@ __M = r'(?P<mon>\w{3})' __Y = r'(?P<year>\d{4})' __Y2 = r'(?P<year>\d{2})' __T = r'(?P<hour>\d{2}):(?P<min>\d{2}):(?P<sec>\d{2})' -RFC1123_DATE = re.compile(r'^\w{3}, %s %s %s %s GMT$' % (__D, __M, __Y, __T)) -RFC850_DATE = re.compile(r'^\w{6,9}, %s-%s-%s %s GMT$' % (__D, __M, __Y2, __T)) -ASCTIME_DATE = re.compile(r'^\w{3} %s %s %s %s$' % (__M, __D2, __T, __Y)) +RFC1123_DATE = _lazy_re_compile(r'^\w{3}, %s %s %s %s GMT$' % (__D, __M, __Y, __T)) +RFC850_DATE = _lazy_re_compile(r'^\w{6,9}, %s-%s-%s %s GMT$' % (__D, __M, __Y2, __T)) +ASCTIME_DATE = _lazy_re_compile(r'^\w{3} %s %s %s %s$' % (__M, __D2, __T, __Y)) RFC3986_GENDELIMS = ":/?#[]@" RFC3986_SUBDELIMS = "!$&'()*+,;=" -FIELDS_MATCH = re.compile('[&;]') +FIELDS_MATCH = _lazy_re_compile('[&;]') @keep_lazy_text diff --git a/django/utils/text.py b/django/utils/text.py index 03e2d05177..5e1409116e 100644 --- a/django/utils/text.py +++ b/django/utils/text.py @@ -7,6 +7,7 @@ from io import BytesIO from django.utils.deprecation import RemovedInDjango40Warning from django.utils.functional import SimpleLazyObject, keep_lazy_text, lazy +from django.utils.regex_helper import _lazy_re_compile from django.utils.translation import gettext as _, gettext_lazy, pgettext @@ -17,11 +18,11 @@ def capfirst(x): # Set up regular expressions -re_words = re.compile(r'<[^>]+?>|([^<>\s]+)', re.S) -re_chars = re.compile(r'<[^>]+?>|(.)', re.S) -re_tag = re.compile(r'<(/)?(\S+?)(?:(\s*/)|\s.*?)?>', re.S) -re_newlines = re.compile(r'\r\n|\r') # Used in normalize_newlines -re_camel_case = re.compile(r'(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))') +re_words = _lazy_re_compile(r'<[^>]+?>|([^<>\s]+)', re.S) +re_chars = _lazy_re_compile(r'<[^>]+?>|(.)', re.S) +re_tag = _lazy_re_compile(r'<(/)?(\S+?)(?:(\s*/)|\s.*?)?>', re.S) +re_newlines = _lazy_re_compile(r'\r\n|\r') # Used in normalize_newlines +re_camel_case = _lazy_re_compile(r'(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))') @keep_lazy_text @@ -306,7 +307,7 @@ def compress_sequence(sequence): # Expression to match some_token and some_token="with spaces" (and similarly # for single-quoted strings). -smart_split_re = re.compile(r""" +smart_split_re = _lazy_re_compile(r""" ((?: [^\s'"]* (?: @@ -355,7 +356,7 @@ def _replace_entity(match): return match.group(0) -_entity_re = re.compile(r"&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8}));") +_entity_re = _lazy_re_compile(r"&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8}));") @keep_lazy_text diff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py index e48c7d245d..728286c78e 100644 --- a/django/utils/translation/__init__.py +++ b/django/utils/translation/__init__.py @@ -1,7 +1,6 @@ """ Internationalization support. """ -import re import warnings from contextlib import ContextDecorator from decimal import ROUND_UP, Decimal @@ -9,6 +8,7 @@ from decimal import ROUND_UP, Decimal from django.utils.autoreload import autoreload_started, file_changed from django.utils.deprecation import RemovedInDjango40Warning from django.utils.functional import lazy +from django.utils.regex_helper import _lazy_re_compile __all__ = [ 'activate', 'deactivate', 'override', 'deactivate_all', @@ -328,7 +328,7 @@ def get_language_info(lang_code): return info -trim_whitespace_re = re.compile(r'\s*\n\s*') +trim_whitespace_re = _lazy_re_compile(r'\s*\n\s*') def trim_whitespace(s): diff --git a/django/utils/translation/template.py b/django/utils/translation/template.py index aa849b0937..979ae1ade6 100644 --- a/django/utils/translation/template.py +++ b/django/utils/translation/template.py @@ -1,12 +1,12 @@ -import re import warnings from io import StringIO from django.template.base import TRANSLATOR_COMMENT_MARK, Lexer, TokenType +from django.utils.regex_helper import _lazy_re_compile from . import TranslatorCommentWarning, trim_whitespace -dot_re = re.compile(r'\S') +dot_re = _lazy_re_compile(r'\S') def blankout(src, char): @@ -17,8 +17,8 @@ def blankout(src, char): return dot_re.sub(char, src) -context_re = re.compile(r"""^\s+.*context\s+((?:"[^"]*?")|(?:'[^']*?'))\s*""") -inline_re = re.compile( +context_re = _lazy_re_compile(r"""^\s+.*context\s+((?:"[^"]*?")|(?:'[^']*?'))\s*""") +inline_re = _lazy_re_compile( # Match the trans 'some text' part r"""^\s*trans\s+((?:"[^"]*?")|(?:'[^']*?'))""" # Match and ignore optional filters @@ -26,10 +26,10 @@ inline_re = re.compile( # Match the optional context part r"""(\s+.*context\s+((?:"[^"]*?")|(?:'[^']*?')))?\s*""" ) -block_re = re.compile(r"""^\s*blocktrans(\s+.*context\s+((?:"[^"]*?")|(?:'[^']*?')))?(?:\s+|$)""") -endblock_re = re.compile(r"""^\s*endblocktrans$""") -plural_re = re.compile(r"""^\s*plural$""") -constant_re = re.compile(r"""_\(((?:".*?")|(?:'.*?'))\)""") +block_re = _lazy_re_compile(r"""^\s*blocktrans(\s+.*context\s+((?:"[^"]*?")|(?:'[^']*?')))?(?:\s+|$)""") +endblock_re = _lazy_re_compile(r"""^\s*endblocktrans$""") +plural_re = _lazy_re_compile(r"""^\s*plural$""") +constant_re = _lazy_re_compile(r"""_\(((?:".*?")|(?:'.*?'))\)""") def templatize(src, origin=None): diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py index e089597ccb..d852675360 100644 --- a/django/utils/translation/trans_real.py +++ b/django/utils/translation/trans_real.py @@ -14,6 +14,7 @@ from django.conf.locale import LANG_INFO from django.core.exceptions import AppRegistryNotReady from django.core.signals import setting_changed from django.dispatch import receiver +from django.utils.regex_helper import _lazy_re_compile from django.utils.safestring import SafeData, mark_safe from . import to_language, to_locale @@ -31,18 +32,18 @@ CONTEXT_SEPARATOR = "\x04" # Format of Accept-Language header values. From RFC 2616, section 14.4 and 3.9 # and RFC 3066, section 2.1 -accept_language_re = re.compile(r''' +accept_language_re = _lazy_re_compile(r''' ([A-Za-z]{1,8}(?:-[A-Za-z0-9]{1,8})*|\*) # "en", "en-au", "x-y-z", "es-419", "*" (?:\s*;\s*q=(0(?:\.\d{,3})?|1(?:\.0{,3})?))? # Optional "q=1.00", "q=0.8" (?:\s*,\s*|$) # Multiple accepts per header. ''', re.VERBOSE) -language_code_re = re.compile( +language_code_re = _lazy_re_compile( r'^[a-z]{1,8}(?:-[a-z0-9]{1,8})*(?:@[a-z0-9]{1,20})?$', re.IGNORECASE ) -language_code_prefix_re = re.compile(r'^/(\w+([@-]\w+)?)(/|$)') +language_code_prefix_re = _lazy_re_compile(r'^/(\w+([@-]\w+)?)(/|$)') @receiver(setting_changed) |
