summaryrefslogtreecommitdiffstats
path: root/patches/Django-1.8.7/0001-Fixed-25322-Lazily-compiled-core.validators-regular-.patch
blob: 3c3b0eac40d9efcdebabd3f8581f4095328aa145 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
From 1753a76267a4dda6858d117858f233c0ed662a7f Mon Sep 17 00:00:00 2001
From: Jonas Haag <jonas@lophus.org>
Date: Wed, 26 Aug 2015 09:12:05 +0200
Subject: [PATCH 1/1] Fixed #25322 -- Lazily compiled core.validators regular
 expressions.

This speeds up import of 'django.core.validators' which can save a
few hundred milliseconds when importing the module for the first
time. It can be a significant speedup to the django-admin command.
---
 django/core/validators.py | 34 +++++++++++++++++++++++-----------
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/django/core/validators.py b/django/core/validators.py
index 89d184f..7719b40 100644
--- a/django/core/validators.py
+++ b/django/core/validators.py
@@ -6,6 +6,7 @@ from django.core.exceptions import ValidationError
 from django.utils import six
 from django.utils.deconstruct import deconstructible
 from django.utils.encoding import force_text
+from django.utils.functional import SimpleLazyObject
 from django.utils.ipv6 import is_valid_ipv6_address
 from django.utils.six.moves.urllib.parse import urlsplit, urlunsplit
 from django.utils.translation import ugettext_lazy as _, ungettext_lazy
@@ -14,6 +15,18 @@ from django.utils.translation import ugettext_lazy as _, ungettext_lazy
 EMPTY_VALUES = (None, '', [], (), {})
 
 
+def _lazy_re_compile(regex, flags=0):
+    """Lazily compile a regex with flags."""
+    def _compile():
+        # Compile the regex if it was not passed pre-compiled.
+        if isinstance(regex, six.string_types):
+            return re.compile(regex, flags)
+        else:
+            assert not flags, "flags must be empty if regex is passed pre-compiled"
+            return regex
+    return SimpleLazyObject(_compile)
+
+
 @deconstructible
 class RegexValidator(object):
     regex = ''
@@ -36,9 +49,7 @@ class RegexValidator(object):
         if self.flags and not isinstance(self.regex, six.string_types):
             raise TypeError("If the flags are set, regex must be a regular expression string.")
 
-        # Compile the regex if it was not passed pre-compiled.
-        if isinstance(self.regex, six.string_types):
-            self.regex = re.compile(self.regex, self.flags)
+        self.regex = _lazy_re_compile(self.regex, self.flags)
 
     def __call__(self, value):
         """
@@ -77,7 +88,7 @@ class URLValidator(RegexValidator):
     tld_re = r'\.(?:[a-z' + ul + r']{2,}|xn--[a-z0-9]+)\.?'
     host_re = '(' + hostname_re + domain_re + tld_re + '|localhost)'
 
-    regex = re.compile(
+    regex = _lazy_re_compile(
         r'^(?:[a-z0-9\.\-]*)://'  # scheme is validated separately
         r'(?:\S+(?::\S*)?@)?'  # user:pass authentication
         r'(?:' + ipv4_re + '|' + ipv6_re + '|' + host_re + ')'
@@ -126,7 +137,7 @@ class URLValidator(RegexValidator):
             url = value
 
 integer_validator = RegexValidator(
-    re.compile('^-?\d+\Z'),
+    _lazy_re_compile('^-?\d+\Z'),
     message=_('Enter a valid integer.'),
     code='invalid',
 )
@@ -140,16 +151,17 @@ def validate_integer(value):
 class EmailValidator(object):
     message = _('Enter a valid email address.')
     code = 'invalid'
-    user_regex = re.compile(
+
+    user_regex = _lazy_re_compile(
         r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*\Z"  # dot-atom
         r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"\Z)',  # quoted-string
         re.IGNORECASE)
-    domain_regex = re.compile(
+    domain_regex = _lazy_re_compile(
         # max length of the domain is 249: 254 (max email length) minus one
         # period, two characters for the TLD, @ sign, & one character before @.
         r'(?:[A-Z0-9](?:[A-Z0-9-]{0,247}[A-Z0-9])?\.)+(?:[A-Z]{2,6}|[A-Z0-9-]{2,}(?<!-))\Z',
         re.IGNORECASE)
-    literal_regex = re.compile(
+    literal_regex = _lazy_re_compile(
         # literal form, ipv4 or ipv6 address (SMTP 4.1.3)
         r'\[([A-f0-9:\.]+)\]\Z',
         re.IGNORECASE)
@@ -209,14 +221,14 @@ class EmailValidator(object):
 
 validate_email = EmailValidator()
 
-slug_re = re.compile(r'^[-a-zA-Z0-9_]+\Z')
+slug_re = _lazy_re_compile(r'^[-a-zA-Z0-9_]+\Z')
 validate_slug = RegexValidator(
     slug_re,
     _("Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."),
     'invalid'
 )
 
-ipv4_re = re.compile(r'^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z')
+ipv4_re = _lazy_re_compile(r'^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z')
 validate_ipv4_address = RegexValidator(ipv4_re, _('Enter a valid IPv4 address.'), 'invalid')
 
 
@@ -257,7 +269,7 @@ def ip_address_validators(protocol, unpack_ipv4):
         raise ValueError("The protocol '%s' is unknown. Supported: %s"
                          % (protocol, list(ip_address_validator_map)))
 
-comma_separated_int_list_re = re.compile('^[\d,]+\Z')
+comma_separated_int_list_re = _lazy_re_compile('^[\d,]+\Z')
 validate_comma_separated_integer_list = RegexValidator(
     comma_separated_int_list_re,
     _('Enter only digits separated by commas.'),
-- 
2.6.4