10000 Remove re._compile · python/cpython@4e06a9c · GitHub
[go: up one dir, main page]

Skip to content

Commit 4e06a9c

Browse files
committed
Remove re._compile
Move implementation directly into re.compile. Simplifies tracebacks and reduces call stack.
1 parent 8234419 commit 4e06a9c

File tree

2 files changed

+54
-55
lines changed

2 files changed

+54
-55
lines changed

Lib/re/__init__.py

Lines changed: 53 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -164,17 +164,17 @@ class RegexFlag:
164164
def match(pattern, string, flags=0):
165165
"""Try to apply the pattern at the start of the string, returning
166166
a Match object, or None if no match was found."""
167-
return _compile(pattern, flags).match(string)
167+
return compile(pattern, flags).match(string)
168168

169169
def fullmatch(pattern, string, flags=0):
170170
"""Try to apply the pattern to all of the string, returning
171171
a Match object, or None if no match was found."""
172-
return _compile(pattern, flags).fullmatch(string)
172+
return compile(pattern, flags).fullmatch(string)
173173

174174
def search(pattern, string, flags=0):
175175
"""Scan through string looking for a match to the pattern, returning
176176
a Match object, or None if no match was found."""
177-
return _compile(pattern, flags).search(string)
177+
return compile(pattern, flags).search(string)
178178

179179
class _ZeroSentinel(int):
180180
pass
@@ -205,7 +205,7 @@ def sub(pattern, repl, string, *args, count=_zero_sentinel, flags=_zero_sentinel
205205
DeprecationWarning, stacklevel=2
206206
)
207207

208-
return _compile(pattern, flags).sub(repl, string, count)
208+
return compile(pattern, flags).sub(repl, string, count)
209209
sub.__text_signature__ = '(pattern, repl, string, count=0, flags=0)'
210210

211211
def subn(pattern, repl, string, *args, count=_zero_sentinel, flags=_zero_sentinel):
@@ -235,7 +235,7 @@ def subn(pattern, repl, string, *args, count=_zero_sentinel, flags=_zero_sentine
235235
DeprecationWarning, stacklevel=2
236236
)
237237

238-
return _compile(pattern, flags).subn(repl, string, count)
238+
return compile(pattern, flags).subn(repl, string, count)
239239
subn.__text_signature__ = '(pattern, repl, string, count=0, flags=0)'
240240

241241
def split(pattern, string, *args, maxsplit=_zero_sentinel, flags=_zero_sentinel):
@@ -264,7 +264,7 @@ def split(pattern, string, *args, maxsplit=_zero_sentinel, flags=_zero_sentinel)
264264
DeprecationWarning, stacklevel=2
265265
)
266266

267-
return _compile(pattern, flags).split(string, maxsplit)
267+
return compile(pattern, flags).split(string, maxsplit)
268268
split.__text_signature__ = '(pattern, string, maxsplit=0, flags=0)'
269269

270270
def findall(pattern, string, flags=0):< 10000 /div>
@@ -275,60 +275,17 @@ def findall(pattern, string, flags=0):
275275
has more than one group.
276276
277277
Empty matches are included in the result."""
278-
return _compile(pattern, flags).findall(string)
278+
return compile(pattern, flags).findall(string)
279279

280280
def finditer(pattern, string, flags=0):
281281
"""Return an iterator over all non-overlapping matches in the
282282
string. For each match, the iterator returns a Match object.
283283
284284
Empty matches are included in the result."""
285-
return _compile(pattern, flags).finditer(string)
285+
return compile(pattern, flags).finditer(string)
286286

287287
def compile(pattern, flags=0):
288-
"Compile a regular expression pattern, returning a Pattern object."
289-
return _compile(pattern, flags)
290-
291-
def purge():
292-
"Clear the regular expression caches"
293-
_cache.clear()
294-
_cache2.clear()
295-
_compile_template.cache_clear()
296-
297-
298-
# SPECIAL_CHARS
299-
# closing ')', '}' and ']'
300-
# '-' (a range in character set)
301-
# '&', '~', (extended character set operations)
302-
# '#' (comment) and WHITESPACE (ignored) in verbose mode
303-
_special_chars_map = {i: '\\' + chr(i) for i in b'()[]{}?*+-|^$\\.&~# \t\n\r\v\f'}
304-
305-
def escape(pattern):
306-
"""
307-
Escape special characters in a string.
308-
"""
309-
if isinstance(pattern, str):
310-
return pattern.translate(_special_chars_map)
311-
else:
312-
pattern = str(pattern, 'latin1')
313-
return pattern.translate(_special_chars_map).encode('latin1')
314-
315-
Pattern = type(_compiler.compile('', 0))
316-
Match = type(_compiler.compile('', 0).match(''))
317-
318-
# --------------------------------------------------------------------
319-
# internals
320-
321-
# Use the fact that dict keeps the insertion order.
322-
# _cache2 uses the simple FIFO policy which has better latency.
323-
# _cache uses the LRU policy which has better hit rate.
324-
_cache = {} # LRU
325-
_cache2 = {} # FIFO
326-
_MAXCACHE = 512
327-
_MAXCACHE2 = 256
328-
assert _MAXCACHE2 < _MAXCACHE
329-
330-
def _compile(pattern, flags):
331-
# internal: compile pattern
288+
"""Compile a regular expression pattern, returning a Pattern object."""
332289
if isinstance(flags, RegexFlag):
333290
flags = flags.value
334291
try:
@@ -371,6 +328,45 @@ def _compile(pattern, flags):
371328
_cache2[key] = p
372329
return p
373330

331+
def purge():
332+
"Clear the regular expression caches"
333+
_cache.clear()
334+
_cache2.clear()
335+
_compile_template.cache_clear()
336+
337+
338+
# SPECIAL_CHARS
339+
# closing ')', '}' and ']'
340+
# '-' (a range in character set)
341+
# '&', '~', (extended character set operations)
342+
# '#' (comment) and WHITESPACE (ignored) in verbose mode
343+
_special_chars_map = {i: '\\' + chr(i) for i in b'()[]{}?*+-|^$\\.&~# \t\n\r\v\f'}
344+
345+
def escape(pattern):
346+
"""
347+
Escape special characters in a string.
348+
"""
349+
if isinstance(pattern, str):
350+
return pattern.translate(_special_chars_map)
351+
else:
352+
pattern = str(pattern, 'latin1')
353+
return pattern.translate(_special_chars_map).encode('latin1')
354+
355+
Pattern = type(_compiler.compile('', 0))
356+
Match = type(_compiler.compile('', 0).match(''))
357+
358+
# --------------------------------------------------------------------
359+
# internals
360+
361+
# Use the fact that dict keeps the insertion order.
362+
# _cache2 uses the simple FIFO policy which has better latency.
363+
# _cache uses the LRU policy which has better hit rate.
364+
_cache = {} # LRU
365+
_cache2 = {} # FIFO
366+
_MAXCACHE = 512
367+
_MAXCACHE2 = 256
368+
assert _MAXCACHE2 < _MAXCACHE
369+
374370
@functools.lru_cache(_MAXCACHE)
375371
def _compile_template(pattern, repl):
376372
# internal: compile replacement pattern
@@ -381,9 +377,12 @@ def _compile_template(pattern, repl):
381377
import copyreg
382378

383379
def _pickle(p):
384-
return _compile, (p.pattern, p.flags)
380+
return compile, (p.pattern, p.flags)
381+
382+
# compatibility alias to deserialize old pickles
383+
_compile = compile
385384

386-
copyreg.pickle(Pattern, _pickle, _compile)
385+
copyreg.pickle(Pattern, _pickle, compile)
387386

388387
# --------------------------------------------------------------------
389388
# experimental stuff (see python-dev discussions for details)

Lib/test/test_re.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1227,7 +1227,7 @@ def test_pickling(self):
12271227
pickled = pickle.dumps(oldpat, proto)
12281228
newpat = pickle.loads(pickled)
12291229
self.assertEqual(newpat, oldpat)
1230-
# current pickle expects the _compile() reconstructor in re module
1230+
# previous pickles may expect the _compile() reconstructor in re module
12311231
from re import _compile # noqa: F401
12321232

12331233
def test_copying(self):

0 commit comments

Comments
 (0)
0