From ef52a1326dba8f9becadca052cb0db49b440f10a Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 29 Mar 2022 18:59:54 +0300 Subject: [PATCH 1/9] bpo-47152: Convert the re module into a package --- Doc/library/modulefinder.rst | 6 +-- Doc/library/profile.rst | 8 +-- Lib/{re.py => re/__init__.py} | 51 +++++++++---------- Lib/{sre_compile.py => re/_compiler.py} | 8 +-- Lib/{sre_constants.py => re/_constants.py} | 4 +- Lib/{sre_parse.py => re/_parser.py} | 2 +- Lib/test/test_pyclbr.py | 2 +- Lib/test/test_re.py | 9 ++-- Lib/test/test_site.py | 2 +- .../2022-03-29-19-14-53.bpo-47152.5rl5ZK.rst | 3 ++ Modules/sre_constants.h | 4 +- 11 files changed, 50 insertions(+), 49 deletions(-) rename Lib/{re.py => re/__init__.py} (90%) rename Lib/{sre_compile.py => re/_compiler.py} (99%) rename Lib/{sre_constants.py => re/_constants.py} (98%) rename Lib/{sre_parse.py => re/_parser.py} (99%) create mode 100644 Misc/NEWS.d/next/Library/2022-03-29-19-14-53.bpo-47152.5rl5ZK.rst diff --git a/Doc/library/modulefinder.rst b/Doc/library/modulefinder.rst index 7b39ce7d1aae5d..526f0ff868c2b7 100644 --- a/Doc/library/modulefinder.rst +++ b/Doc/library/modulefinder.rst @@ -96,14 +96,14 @@ Sample output (may vary depending on the architecture):: Loaded modules: _types: copyreg: _inverted_registry,_slotnames,__all__ - sre_compile: isstring,_sre,_optimize_unicode + re._compiler: isstring,_sre,_optimize_unicode _sre: - sre_constants: REPEAT_ONE,makedict,AT_END_LINE + re._constants: REPEAT_ONE,makedict,AT_END_LINE sys: re: __module__,finditer,_expand itertools: __main__: re,itertools,baconhameggs - sre_parse: _PATTERNENDERS,SRE_FLAG_UNICODE + re._parser: _PATTERNENDERS,SRE_FLAG_UNICODE array: types: __module__,IntType,TypeType --------------------------------------------------- diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index cf324a57e79fdf..514c209b05a265 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -74,10 +74,10 @@ the following:: 1 0.000 0.000 0.001 0.001 :1() 1 0.000 0.000 0.001 0.001 re.py:212(compile) 1 0.000 0.000 0.001 0.001 re.py:268(_compile) - 1 0.000 0.000 0.000 0.000 sre_compile.py:172(_compile_charset) - 1 0.000 0.000 0.000 0.000 sre_compile.py:201(_optimize_charset) - 4 0.000 0.000 0.000 0.000 sre_compile.py:25(_identityfunction) - 3/1 0.000 0.000 0.000 0.000 sre_compile.py:33(_compile) + 1 0.000 0.000 0.000 0.000 _compiler.py:172(_compile_charset) + 1 0.000 0.000 0.000 0.000 _compiler.py:201(_optimize_charset) + 4 0.000 0.000 0.000 0.000 _compiler.py:25(_identityfunction) + 3/1 0.000 0.000 0.000 0.000 _compiler.py:33(_compile) The first line indicates that 197 calls were monitored. Of those calls, 192 were :dfn:`primitive`, meaning that the call was not induced via recursion. The diff --git a/Lib/re.py b/Lib/re/__init__.py similarity index 90% rename from Lib/re.py rename to Lib/re/__init__.py index e9a745dc581a69..c47a2650e32f5f 100644 --- a/Lib/re.py +++ b/Lib/re/__init__.py @@ -122,8 +122,7 @@ """ import enum -import sre_compile -import sre_parse +from . import _compiler, _parser import functools try: import _locale @@ -146,21 +145,21 @@ @enum._simple_enum(enum.IntFlag, boundary=enum.KEEP) class RegexFlag: NOFLAG = 0 - ASCII = A = sre_compile.SRE_FLAG_ASCII # assume ascii "locale" - IGNORECASE = I = sre_compile.SRE_FLAG_IGNORECASE # ignore case - LOCALE = L = sre_compile.SRE_FLAG_LOCALE # assume current 8-bit locale - UNICODE = U = sre_compile.SRE_FLAG_UNICODE # assume unicode "locale" - MULTILINE = M = sre_compile.SRE_FLAG_MULTILINE # make anchors look for newline - DOTALL = S = sre_compile.SRE_FLAG_DOTALL # make dot match newline - VERBOSE = X = sre_compile.SRE_FLAG_VERBOSE # ignore whitespace and comments + ASCII = A = _compiler.SRE_FLAG_ASCII # assume ascii "locale" + IGNORECASE = I = _compiler.SRE_FLAG_IGNORECASE # ignore case + LOCALE = L = _compiler.SRE_FLAG_LOCALE # assume current 8-bit locale + UNICODE = U = _compiler.SRE_FLAG_UNICODE # assume unicode "locale" + MULTILINE = M = _compiler.SRE_FLAG_MULTILINE # make anchors look for newline + DOTALL = S = _compiler.SRE_FLAG_DOTALL # make dot match newline + VERBOSE = X = _compiler.SRE_FLAG_VERBOSE # ignore whitespace and comments # sre extensions (experimental, don't rely on these) - TEMPLATE = T = sre_compile.SRE_FLAG_TEMPLATE # disable backtracking - DEBUG = sre_compile.SRE_FLAG_DEBUG # dump pattern after compilation + TEMPLATE = T = _compiler.SRE_FLAG_TEMPLATE # disable backtracking + DEBUG = _compiler.SRE_FLAG_DEBUG # dump pattern after compilation __str__ = object.__str__ _numeric_repr_ = hex # sre exception -error = sre_compile.error +error = _compiler.error # -------------------------------------------------------------------- # public interface @@ -257,8 +256,8 @@ def escape(pattern): pattern = str(pattern, 'latin1') return pattern.translate(_special_chars_map).encode('latin1') -Pattern = type(sre_compile.compile('', 0)) -Match = type(sre_compile.compile('', 0).match('')) +Pattern = type(_compiler.compile('', 0)) +Match = type(_compiler.compile('', 0).match('')) # -------------------------------------------------------------------- # internals @@ -279,9 +278,9 @@ def _compile(pattern, flags): raise ValueError( "cannot process flags argument with a compiled pattern") return pattern - if not sre_compile.isstring(pattern): + if not _compiler.isstring(pattern): raise TypeError("first argument must be string or compiled pattern") - p = sre_compile.compile(pattern, flags) + p = _compiler.compile(pattern, flags) if not (flags & DEBUG): if len(_cache) >= _MAXCACHE: # Drop the oldest item @@ -295,12 +294,12 @@ def _compile(pattern, flags): @functools.lru_cache(_MAXCACHE) def _compile_repl(repl, pattern): # internal: compile replacement pattern - return sre_parse.parse_template(repl, pattern) + return _parser.parse_template(repl, pattern) def _expand(pattern, match, template): # internal: Match.expand implementation hook - template = sre_parse.parse_template(template, pattern) - return sre_parse.expand_template(template, match) + template = _parser.parse_template(template, pattern) + return _parser.expand_template(template, match) def _subx(pattern, template): # internal: Pattern.sub/subn implementation helper @@ -309,7 +308,7 @@ def _subx(pattern, template): # literal replacement return template[1][0] def filter(match, template=template): - return sre_parse.expand_template(template, match) + return _parser.expand_template(template, match) return filter # register myself for pickling @@ -326,22 +325,22 @@ def _pickle(p): class Scanner: def __init__(self, lexicon, flags=0): - from sre_constants import BRANCH, SUBPATTERN + from ._constants import BRANCH, SUBPATTERN if isinstance(flags, RegexFlag): flags = flags.value self.lexicon = lexicon # combine phrases into a compound pattern p = [] - s = sre_parse.State() + s = _parser.State() s.flags = flags for phrase, action in lexicon: gid = s.opengroup() - p.append(sre_parse.SubPattern(s, [ - (SUBPATTERN, (gid, 0, 0, sre_parse.parse(phrase, flags))), + p.append(_parser.SubPattern(s, [ + (SUBPATTERN, (gid, 0, 0, _parser.parse(phrase, flags))), ])) s.closegroup(gid, p[-1]) - p = sre_parse.SubPattern(s, [(BRANCH, (None, p))]) - self.scanner = sre_compile.compile(p) + p = _parser.SubPattern(s, [(BRANCH, (None, p))]) + self.scanner = _compiler.compile(p) def scan(self, string): result = [] append = result.append diff --git a/Lib/sre_compile.py b/Lib/re/_compiler.py similarity index 99% rename from Lib/sre_compile.py rename to Lib/re/_compiler.py index 0867200a59a230..8e84ec3cd8c8cc 100644 --- a/Lib/sre_compile.py +++ b/Lib/re/_compiler.py @@ -11,8 +11,8 @@ """Internal support module for sre""" import _sre -import sre_parse -from sre_constants import * +from . import _parser +from ._constants import * assert _sre.MAGIC == MAGIC, "SRE module mismatch" @@ -68,7 +68,7 @@ for t in _equivalences for i in t} def _combine_flags(flags, add_flags, del_flags, - TYPE_FLAGS=sre_parse.TYPE_FLAGS): + TYPE_FLAGS=_parser.TYPE_FLAGS): if add_flags & TYPE_FLAGS: flags &= ~TYPE_FLAGS return (flags | add_flags) & ~del_flags @@ -777,7 +777,7 @@ def compile(p, flags=0): if isstring(p): pattern = p - p = sre_parse.parse(p, flags) + p = _parser.parse(p, flags) else: pattern = None diff --git a/Lib/sre_constants.py b/Lib/re/_constants.py similarity index 98% rename from Lib/sre_constants.py rename to Lib/re/_constants.py index a00b0170607b59..2d10ba6dc3be44 100644 --- a/Lib/sre_constants.py +++ b/Lib/re/_constants.py @@ -229,8 +229,8 @@ def dump(f, d, prefix): * * regular expression matching engine * - * NOTE: This file is generated by sre_constants.py. If you need - * to change anything in here, edit sre_constants.py and run it. + * NOTE: This file is generated by Lib/re/_constants.py. If you need + * to change anything in here, edit Lib/re/_constants.py and run it. * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. * diff --git a/Lib/sre_parse.py b/Lib/re/_parser.py similarity index 99% rename from Lib/sre_parse.py rename to Lib/re/_parser.py index b91082e48fafe1..e088de6facddc6 100644 --- a/Lib/sre_parse.py +++ b/Lib/re/_parser.py @@ -12,7 +12,7 @@ # XXX: show string offset and offending character for all errors -from sre_constants import * +from ._constants import * SPECIAL_CHARS = ".\\[{()*+?^$|" REPEAT_CHARS = "*+?{" diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py index 4bb9cfcad9a76a..157c522b63bd0b 100644 --- a/Lib/test/test_pyclbr.py +++ b/Lib/test/test_pyclbr.py @@ -221,7 +221,7 @@ def test_others(self): cm('cgi', ignore=('log',)) # set with = in module cm('pickle', ignore=('partial', 'PickleBuffer')) cm('aifc', ignore=('_aifc_params',)) # set with = in module - cm('sre_parse', ignore=('dump', 'groups', 'pos')) # from sre_constants import *; property + cm('re._parser', ignore=('dump', 'groups', 'pos')) # from ._constants import *; property cm( 'pdb', # pyclbr does not handle elegantly `typing` or properties diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 85716fbe2a8e8d..2153f55d322bde 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -3,7 +3,6 @@ check_disallow_instantiation, is_emscripten) import locale import re -import sre_compile import string import time import unittest @@ -569,7 +568,7 @@ def test_re_groupref_exists(self): 'two branches', 10) def test_re_groupref_overflow(self): - from sre_constants import MAXGROUPS + from re._constants import MAXGROUPS self.checkTemplateError('()', r'\g<%s>' % MAXGROUPS, 'xx', 'invalid group reference %d' % MAXGROUPS, 3) self.checkPatternError(r'(?P)(?(%d))' % MAXGROUPS, @@ -2433,7 +2432,7 @@ def test_immutable(self): tp.foo = 1 def test_overlap_table(self): - f = sre_compile._generate_overlap_table + f = re._compiler._generate_overlap_table self.assertEqual(f(""), []) self.assertEqual(f("a"), [0]) self.assertEqual(f("abcd"), [0, 0, 0, 0]) @@ -2442,8 +2441,8 @@ def test_overlap_table(self): self.assertEqual(f("abcabdac"), [0, 0, 0, 1, 2, 0, 1, 0]) def test_signedness(self): - self.assertGreaterEqual(sre_compile.MAXREPEAT, 0) - self.assertGreaterEqual(sre_compile.MAXGROUPS, 0) + self.assertGreaterEqual(re._compiler.MAXREPEAT, 0) + self.assertGreaterEqual(re._compiler.MAXGROUPS, 0) @cpython_only def test_disallow_instantiation(self): diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index a67cfec72aee4d..dd018d6b38a864 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -523,7 +523,7 @@ def test_startup_imports(self): self.assertIn('site', modules) # http://bugs.python.org/issue19205 - re_mods = {'re', '_sre', 'sre_compile', 'sre_constants', 'sre_parse'} + re_mods = {'re', '_sre', 're._compiler', 're._constants', 're._parser'} self.assertFalse(modules.intersection(re_mods), stderr) # http://bugs.python.org/issue9548 diff --git a/Misc/NEWS.d/next/Library/2022-03-29-19-14-53.bpo-47152.5rl5ZK.rst b/Misc/NEWS.d/next/Library/2022-03-29-19-14-53.bpo-47152.5rl5ZK.rst new file mode 100644 index 00000000000000..173ab74a03d2bd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-29-19-14-53.bpo-47152.5rl5ZK.rst @@ -0,0 +1,3 @@ +Convert the :mod:`re` module into a package. Modules ``sre_compile``, +``sre_constants`` and ``sre_parse`` are now private submodules of the ``re`` +package. diff --git a/Modules/sre_constants.h b/Modules/sre_constants.h index 8b9125b75b4568..45395dcea807a3 100644 --- a/Modules/sre_constants.h +++ b/Modules/sre_constants.h @@ -3,8 +3,8 @@ * * regular expression matching engine * - * NOTE: This file is generated by sre_constants.py. If you need - * to change anything in here, edit sre_constants.py and run it. + * NOTE: This file is generated by Lib/re/_constants.py. If you need + * to change anything in here, edit Lib/re/_constants.py and run it. * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. * From a746a7df0933662492680245ba08aac66feb0288 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 29 Mar 2022 21:11:04 +0300 Subject: [PATCH 2/9] Keep old sre_* modules, but deprecate them. --- Doc/whatsnew/3.11.rst | 4 ++++ Lib/sre_compile.py | 6 ++++++ Lib/sre_constants.py | 6 ++++++ Lib/sre_parse.py | 6 ++++++ Lib/test/test_re.py | 12 ++++++++++++ .../Library/2022-03-29-19-14-53.bpo-47152.5rl5ZK.rst | 5 ++--- 6 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 Lib/sre_compile.py create mode 100644 Lib/sre_constants.py create mode 100644 Lib/sre_parse.py diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 837d8c8cbd016c..9b1f6698c49235 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -530,6 +530,10 @@ Deprecated be able to parse Python 3.10 or newer. See the :pep:`617` (New PEG parser for CPython). (Contributed by Victor Stinner in :issue:`40360`.) +* Undocumented modules ``sre_compile``, ``sre_constants`` and ``sre_parse`` + are now deprecated. + (Contributed by Serhiy Storchaka in :issue:`47152`.) + * :class:`webbrowser.MacOSX` is deprecated and will be removed in Python 3.13. It is untested and undocumented and also not used by webbrowser itself. (Contributed by Dong-hee Na in :issue:`42255`.) diff --git a/Lib/sre_compile.py b/Lib/sre_compile.py new file mode 100644 index 00000000000000..c43b39d326df7d --- /dev/null +++ b/Lib/sre_compile.py @@ -0,0 +1,6 @@ +import warnings +warnings.warn(f"module {__name__!r} is deprecated", + DeprecationWarning, + stacklevel=2) + +from re._compiler import * diff --git a/Lib/sre_constants.py b/Lib/sre_constants.py new file mode 100644 index 00000000000000..883e46760fb828 --- /dev/null +++ b/Lib/sre_constants.py @@ -0,0 +1,6 @@ +import warnings +warnings.warn(f"module {__name__!r} is deprecated", + DeprecationWarning, + stacklevel=2) + +from re._constants import * diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py new file mode 100644 index 00000000000000..c43b39d326df7d --- /dev/null +++ b/Lib/sre_parse.py @@ -0,0 +1,6 @@ +import warnings +warnings.warn(f"module {__name__!r} is deprecated", + DeprecationWarning, + stacklevel=2) + +from re._compiler import * diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 2153f55d322bde..7325a289605c30 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -4,6 +4,7 @@ import locale import re import string +import sys import time import unittest import warnings @@ -2452,6 +2453,17 @@ def test_disallow_instantiation(self): pat = re.compile("") check_disallow_instantiation(self, type(pat.scanner(""))) + def test_deprecated_modules(self): + for name in 'sre_compile', 'sre_constants', 'sre_parse': + with self.subTest(module=name): + sys.modules.pop(name, None) + with self.assertWarns(DeprecationWarning) as cm: + __import__(name) + self.assertEqual(str(cm.warnings[0].message), + f"module {name!r} is deprecated") + self.assertEqual(cm.warnings[0].filename, __file__) + self.assertIn(name, sys.modules) + del sys.modules[name] class ExternalTests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2022-03-29-19-14-53.bpo-47152.5rl5ZK.rst b/Misc/NEWS.d/next/Library/2022-03-29-19-14-53.bpo-47152.5rl5ZK.rst index 173ab74a03d2bd..1e1633daae5977 100644 --- a/Misc/NEWS.d/next/Library/2022-03-29-19-14-53.bpo-47152.5rl5ZK.rst +++ b/Misc/NEWS.d/next/Library/2022-03-29-19-14-53.bpo-47152.5rl5ZK.rst @@ -1,3 +1,2 @@ -Convert the :mod:`re` module into a package. Modules ``sre_compile``, -``sre_constants`` and ``sre_parse`` are now private submodules of the ``re`` -package. +Convert the :mod:`re` module into a package. Deprecate modules ``sre_compile``, +``sre_constants`` and ``sre_parse``. From b4ec957d846fbb03a50b362fa61168a61cba02de Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 29 Mar 2022 23:14:22 +0300 Subject: [PATCH 3/9] Fix sre_parse.py. --- Lib/sre_parse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py index c43b39d326df7d..d9de2ef15159de 100644 --- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -3,4 +3,4 @@ DeprecationWarning, stacklevel=2) -from re._compiler import * +from re._parser import * From cfc39b922342081df7466c9dfb1f3556e4058831 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 30 Mar 2022 00:07:55 +0300 Subject: [PATCH 4/9] Fix installation. --- Makefile.pre.in | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.pre.in b/Makefile.pre.in index e6c6a6ba53a6d4..0da1df6894ed6b 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1871,6 +1871,7 @@ LIBSUBDIRS= asyncio \ logging \ multiprocessing multiprocessing/dummy \ pydoc_data \ + re \ site-packages \ sqlite3 \ tkinter \ From 3da0b4c27e43d74b32ca9dfe31c0539170b07bd9 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 30 Mar 2022 10:00:52 +0300 Subject: [PATCH 5/9] Keep old names of sre_* modules after moving them. --- Doc/library/modulefinder.rst | 6 +-- Doc/library/profile.rst | 8 +-- Lib/re/__init__.py | 50 +++++++++---------- Lib/re/{_compiler.py => sre_compile.py} | 8 +-- Lib/re/{_constants.py => sre_constants.py} | 4 +- Lib/re/{_parser.py => sre_parse.py} | 2 +- Lib/sre_compile.py | 2 +- Lib/sre_constants.py | 2 +- Lib/sre_parse.py | 2 +- Lib/test/test_pyclbr.py | 2 +- Lib/test/test_re.py | 8 +-- Lib/test/test_site.py | 2 +- .../2022-03-29-19-14-53.bpo-47152.5rl5ZK.rst | 4 +- Modules/sre_constants.h | 4 +- 14 files changed, 52 insertions(+), 52 deletions(-) rename Lib/re/{_compiler.py => sre_compile.py} (99%) rename Lib/re/{_constants.py => sre_constants.py} (97%) rename Lib/re/{_parser.py => sre_parse.py} (99%) diff --git a/Doc/library/modulefinder.rst b/Doc/library/modulefinder.rst index 526f0ff868c2b7..fc016f6692b796 100644 --- a/Doc/library/modulefinder.rst +++ b/Doc/library/modulefinder.rst @@ -96,14 +96,14 @@ Sample output (may vary depending on the architecture):: Loaded modules: _types: copyreg: _inverted_registry,_slotnames,__all__ - re._compiler: isstring,_sre,_optimize_unicode + re.sre_compile: isstring,_sre,_optimize_unicode _sre: - re._constants: REPEAT_ONE,makedict,AT_END_LINE + re.sre_constants: REPEAT_ONE,makedict,AT_END_LINE sys: re: __module__,finditer,_expand itertools: __main__: re,itertools,baconhameggs - re._parser: _PATTERNENDERS,SRE_FLAG_UNICODE + re.sre_parse: _PATTERNENDERS,SRE_FLAG_UNICODE array: types: __module__,IntType,TypeType --------------------------------------------------- diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index 514c209b05a265..cf324a57e79fdf 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -74,10 +74,10 @@ the following:: 1 0.000 0.000 0.001 0.001 :1() 1 0.000 0.000 0.001 0.001 re.py:212(compile) 1 0.000 0.000 0.001 0.001 re.py:268(_compile) - 1 0.000 0.000 0.000 0.000 _compiler.py:172(_compile_charset) - 1 0.000 0.000 0.000 0.000 _compiler.py:201(_optimize_charset) - 4 0.000 0.000 0.000 0.000 _compiler.py:25(_identityfunction) - 3/1 0.000 0.000 0.000 0.000 _compiler.py:33(_compile) + 1 0.000 0.000 0.000 0.000 sre_compile.py:172(_compile_charset) + 1 0.000 0.000 0.000 0.000 sre_compile.py:201(_optimize_charset) + 4 0.000 0.000 0.000 0.000 sre_compile.py:25(_identityfunction) + 3/1 0.000 0.000 0.000 0.000 sre_compile.py:33(_compile) The first line indicates that 197 calls were monitored. Of those calls, 192 were :dfn:`primitive`, meaning that the call was not induced via recursion. The diff --git a/Lib/re/__init__.py b/Lib/re/__init__.py index c47a2650e32f5f..fdc2edff2ca664 100644 --- a/Lib/re/__init__.py +++ b/Lib/re/__init__.py @@ -122,7 +122,7 @@ """ import enum -from . import _compiler, _parser +from . import sre_compile, sre_parse import functools try: import _locale @@ -145,21 +145,21 @@ @enum._simple_enum(enum.IntFlag, boundary=enum.KEEP) class RegexFlag: NOFLAG = 0 - ASCII = A = _compiler.SRE_FLAG_ASCII # assume ascii "locale" - IGNORECASE = I = _compiler.SRE_FLAG_IGNORECASE # ignore case - LOCALE = L = _compiler.SRE_FLAG_LOCALE # assume current 8-bit locale - UNICODE = U = _compiler.SRE_FLAG_UNICODE # assume unicode "locale" - MULTILINE = M = _compiler.SRE_FLAG_MULTILINE # make anchors look for newline - DOTALL = S = _compiler.SRE_FLAG_DOTALL # make dot match newline - VERBOSE = X = _compiler.SRE_FLAG_VERBOSE # ignore whitespace and comments + ASCII = A = sre_compile.SRE_FLAG_ASCII # assume ascii "locale" + IGNORECASE = I = sre_compile.SRE_FLAG_IGNORECASE # ignore case + LOCALE = L = sre_compile.SRE_FLAG_LOCALE # assume current 8-bit locale + UNICODE = U = sre_compile.SRE_FLAG_UNICODE # assume unicode "locale" + MULTILINE = M = sre_compile.SRE_FLAG_MULTILINE # make anchors look for newline + DOTALL = S = sre_compile.SRE_FLAG_DOTALL # make dot match newline + VERBOSE = X = sre_compile.SRE_FLAG_VERBOSE # ignore whitespace and comments # sre extensions (experimental, don't rely on these) - TEMPLATE = T = _compiler.SRE_FLAG_TEMPLATE # disable backtracking - DEBUG = _compiler.SRE_FLAG_DEBUG # dump pattern after compilation + TEMPLATE = T = sre_compile.SRE_FLAG_TEMPLATE # disable backtracking + DEBUG = sre_compile.SRE_FLAG_DEBUG # dump pattern after compilation __str__ = object.__str__ _numeric_repr_ = hex # sre exception -error = _compiler.error +error = sre_compile.error # -------------------------------------------------------------------- # public interface @@ -256,8 +256,8 @@ def escape(pattern): pattern = str(pattern, 'latin1') return pattern.translate(_special_chars_map).encode('latin1') -Pattern = type(_compiler.compile('', 0)) -Match = type(_compiler.compile('', 0).match('')) +Pattern = type(sre_compile.compile('', 0)) +Match = type(sre_compile.compile('', 0).match('')) # -------------------------------------------------------------------- # internals @@ -278,9 +278,9 @@ def _compile(pattern, flags): raise ValueError( "cannot process flags argument with a compiled pattern") return pattern - if not _compiler.isstring(pattern): + if not sre_compile.isstring(pattern): raise TypeError("first argument must be string or compiled pattern") - p = _compiler.compile(pattern, flags) + p = sre_compile.compile(pattern, flags) if not (flags & DEBUG): if len(_cache) >= _MAXCACHE: # Drop the oldest item @@ -294,12 +294,12 @@ def _compile(pattern, flags): @functools.lru_cache(_MAXCACHE) def _compile_repl(repl, pattern): # internal: compile replacement pattern - return _parser.parse_template(repl, pattern) + return sre_parse.parse_template(repl, pattern) def _expand(pattern, match, template): # internal: Match.expand implementation hook - template = _parser.parse_template(template, pattern) - return _parser.expand_template(template, match) + template = sre_parse.parse_template(template, pattern) + return sre_parse.expand_template(template, match) def _subx(pattern, template): # internal: Pattern.sub/subn implementation helper @@ -308,7 +308,7 @@ def _subx(pattern, template): # literal replacement return template[1][0] def filter(match, template=template): - return _parser.expand_template(template, match) + return sre_parse.expand_template(template, match) return filter # register myself for pickling @@ -325,22 +325,22 @@ def _pickle(p): class Scanner: def __init__(self, lexicon, flags=0): - from ._constants import BRANCH, SUBPATTERN + from .sre_constants import BRANCH, SUBPATTERN if isinstance(flags, RegexFlag): flags = flags.value self.lexicon = lexicon # combine phrases into a compound pattern p = [] - s = _parser.State() + s = sre_parse.State() s.flags = flags for phrase, action in lexicon: gid = s.opengroup() - p.append(_parser.SubPattern(s, [ - (SUBPATTERN, (gid, 0, 0, _parser.parse(phrase, flags))), + p.append(sre_parse.SubPattern(s, [ + (SUBPATTERN, (gid, 0, 0, sre_parse.parse(phrase, flags))), ])) s.closegroup(gid, p[-1]) - p = _parser.SubPattern(s, [(BRANCH, (None, p))]) - self.scanner = _compiler.compile(p) + p = sre_parse.SubPattern(s, [(BRANCH, (None, p))]) + self.scanner = sre_compile.compile(p) def scan(self, string): result = [] append = result.append diff --git a/Lib/re/_compiler.py b/Lib/re/sre_compile.py similarity index 99% rename from Lib/re/_compiler.py rename to Lib/re/sre_compile.py index 8e84ec3cd8c8cc..b76ee7905fd374 100644 --- a/Lib/re/_compiler.py +++ b/Lib/re/sre_compile.py @@ -11,8 +11,8 @@ """Internal support module for sre""" import _sre -from . import _parser -from ._constants import * +from . import sre_parse +from .sre_constants import * assert _sre.MAGIC == MAGIC, "SRE module mismatch" @@ -68,7 +68,7 @@ for t in _equivalences for i in t} def _combine_flags(flags, add_flags, del_flags, - TYPE_FLAGS=_parser.TYPE_FLAGS): + TYPE_FLAGS=sre_parse.TYPE_FLAGS): if add_flags & TYPE_FLAGS: flags &= ~TYPE_FLAGS return (flags | add_flags) & ~del_flags @@ -777,7 +777,7 @@ def compile(p, flags=0): if isstring(p): pattern = p - p = _parser.parse(p, flags) + p = sre_parse.parse(p, flags) else: pattern = None diff --git a/Lib/re/_constants.py b/Lib/re/sre_constants.py similarity index 97% rename from Lib/re/_constants.py rename to Lib/re/sre_constants.py index 2d10ba6dc3be44..332a4afec2ff37 100644 --- a/Lib/re/_constants.py +++ b/Lib/re/sre_constants.py @@ -229,8 +229,8 @@ def dump(f, d, prefix): * * regular expression matching engine * - * NOTE: This file is generated by Lib/re/_constants.py. If you need - * to change anything in here, edit Lib/re/_constants.py and run it. + * NOTE: This file is generated by Lib/re/sre_constants.py. If you need + * to change anything in here, edit Lib/re/sre_constants.py and run it. * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. * diff --git a/Lib/re/_parser.py b/Lib/re/sre_parse.py similarity index 99% rename from Lib/re/_parser.py rename to Lib/re/sre_parse.py index e088de6facddc6..f24488d361a832 100644 --- a/Lib/re/_parser.py +++ b/Lib/re/sre_parse.py @@ -12,7 +12,7 @@ # XXX: show string offset and offending character for all errors -from ._constants import * +from .sre_constants import * SPECIAL_CHARS = ".\\[{()*+?^$|" REPEAT_CHARS = "*+?{" diff --git a/Lib/sre_compile.py b/Lib/sre_compile.py index c43b39d326df7d..3182797bb7e98e 100644 --- a/Lib/sre_compile.py +++ b/Lib/sre_compile.py @@ -3,4 +3,4 @@ DeprecationWarning, stacklevel=2) -from re._compiler import * +from re.sre_compile import * diff --git a/Lib/sre_constants.py b/Lib/sre_constants.py index 883e46760fb828..f9f182162a6d4e 100644 --- a/Lib/sre_constants.py +++ b/Lib/sre_constants.py @@ -3,4 +3,4 @@ DeprecationWarning, stacklevel=2) -from re._constants import * +from re.sre_constants import * diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py index d9de2ef15159de..8e24714264cf30 100644 --- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -3,4 +3,4 @@ DeprecationWarning, stacklevel=2) -from re._parser import * +from re.sre_parse import * diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py index 157c522b63bd0b..2afd23cd43665a 100644 --- a/Lib/test/test_pyclbr.py +++ b/Lib/test/test_pyclbr.py @@ -221,7 +221,7 @@ def test_others(self): cm('cgi', ignore=('log',)) # set with = in module cm('pickle', ignore=('partial', 'PickleBuffer')) cm('aifc', ignore=('_aifc_params',)) # set with = in module - cm('re._parser', ignore=('dump', 'groups', 'pos')) # from ._constants import *; property + cm('re.sre_parse', ignore=('dump', 'groups', 'pos')) # from .sre_constants import *; property cm( 'pdb', # pyclbr does not handle elegantly `typing` or properties diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 7325a289605c30..8b74cbb4e37778 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -569,7 +569,7 @@ def test_re_groupref_exists(self): 'two branches', 10) def test_re_groupref_overflow(self): - from re._constants import MAXGROUPS + from re.sre_constants import MAXGROUPS self.checkTemplateError('()', r'\g<%s>' % MAXGROUPS, 'xx', 'invalid group reference %d' % MAXGROUPS, 3) self.checkPatternError(r'(?P)(?(%d))' % MAXGROUPS, @@ -2433,7 +2433,7 @@ def test_immutable(self): tp.foo = 1 def test_overlap_table(self): - f = re._compiler._generate_overlap_table + f = re.sre_compile._generate_overlap_table self.assertEqual(f(""), []) self.assertEqual(f("a"), [0]) self.assertEqual(f("abcd"), [0, 0, 0, 0]) @@ -2442,8 +2442,8 @@ def test_overlap_table(self): self.assertEqual(f("abcabdac"), [0, 0, 0, 1, 2, 0, 1, 0]) def test_signedness(self): - self.assertGreaterEqual(re._compiler.MAXREPEAT, 0) - self.assertGreaterEqual(re._compiler.MAXGROUPS, 0) + self.assertGreaterEqual(re.sre_compile.MAXREPEAT, 0) + self.assertGreaterEqual(re.sre_compile.MAXGROUPS, 0) @cpython_only def test_disallow_instantiation(self): diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index dd018d6b38a864..7cbecbb943454f 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -523,7 +523,7 @@ def test_startup_imports(self): self.assertIn('site', modules) # http://bugs.python.org/issue19205 - re_mods = {'re', '_sre', 're._compiler', 're._constants', 're._parser'} + re_mods = {'re', '_sre', 're.sre_compile', 're.sre_constants', 're.sre_parse'} self.assertFalse(modules.intersection(re_mods), stderr) # http://bugs.python.org/issue9548 diff --git a/Misc/NEWS.d/next/Library/2022-03-29-19-14-53.bpo-47152.5rl5ZK.rst b/Misc/NEWS.d/next/Library/2022-03-29-19-14-53.bpo-47152.5rl5ZK.rst index 1e1633daae5977..44f40e2609a5bc 100644 --- a/Misc/NEWS.d/next/Library/2022-03-29-19-14-53.bpo-47152.5rl5ZK.rst +++ b/Misc/NEWS.d/next/Library/2022-03-29-19-14-53.bpo-47152.5rl5ZK.rst @@ -1,2 +1,2 @@ -Convert the :mod:`re` module into a package. Deprecate modules ``sre_compile``, -``sre_constants`` and ``sre_parse``. +Convert the :mod:`re` module into a package. Deprecate undocumented modules +``sre_compile``, ``sre_constants`` and ``sre_parse``. diff --git a/Modules/sre_constants.h b/Modules/sre_constants.h index 45395dcea807a3..20f1b76460c506 100644 --- a/Modules/sre_constants.h +++ b/Modules/sre_constants.h @@ -3,8 +3,8 @@ * * regular expression matching engine * - * NOTE: This file is generated by Lib/re/_constants.py. If you need - * to change anything in here, edit Lib/re/_constants.py and run it. + * NOTE: This file is generated by Lib/re/sre_constants.py. If you need + * to change anything in here, edit Lib/re/sre_constants.py and run it. * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. * From 9abbc7015ec9806843b8996c9eb08bd8c2abb037 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 30 Mar 2022 12:12:03 +0300 Subject: [PATCH 6/9] Update Lib/re/sre_compile.py Co-authored-by: Oleg Iarygin --- Lib/re/sre_compile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/re/sre_compile.py b/Lib/re/sre_compile.py index b76ee7905fd374..a8ace208888080 100644 --- a/Lib/re/sre_compile.py +++ b/Lib/re/sre_compile.py @@ -5,7 +5,7 @@ # # Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. # -# See the sre.py file for information on usage and redistribution. +# See the re.py file for information on usage and redistribution. # """Internal support module for sre""" From d1e520ac0a444afb3ccd04c8475d646aa1e399ed Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 2 Apr 2022 10:21:54 +0300 Subject: [PATCH 7/9] Revert "Keep old names of sre_* modules after moving them." This reverts commit 3da0b4c27e43d74b32ca9dfe31c0539170b07bd9. --- Doc/library/modulefinder.rst | 6 +-- Doc/library/profile.rst | 8 +-- Lib/re/__init__.py | 50 +++++++++---------- Lib/re/{sre_compile.py => _compiler.py} | 8 +-- Lib/re/{sre_constants.py => _constants.py} | 4 +- Lib/re/{sre_parse.py => _parser.py} | 2 +- Lib/sre_compile.py | 2 +- Lib/sre_constants.py | 2 +- Lib/sre_parse.py | 2 +- Lib/test/test_pyclbr.py | 2 +- Lib/test/test_re.py | 8 +-- Lib/test/test_site.py | 2 +- .../2022-03-29-19-14-53.bpo-47152.5rl5ZK.rst | 4 +- Modules/sre_constants.h | 4 +- 14 files changed, 52 insertions(+), 52 deletions(-) rename Lib/re/{sre_compile.py => _compiler.py} (99%) rename Lib/re/{sre_constants.py => _constants.py} (97%) rename Lib/re/{sre_parse.py => _parser.py} (99%) diff --git a/Doc/library/modulefinder.rst b/Doc/library/modulefinder.rst index fc016f6692b796..526f0ff868c2b7 100644 --- a/Doc/library/modulefinder.rst +++ b/Doc/library/modulefinder.rst @@ -96,14 +96,14 @@ Sample output (may vary depending on the architecture):: Loaded modules: _types: copyreg: _inverted_registry,_slotnames,__all__ - re.sre_compile: isstring,_sre,_optimize_unicode + re._compiler: isstring,_sre,_optimize_unicode _sre: - re.sre_constants: REPEAT_ONE,makedict,AT_END_LINE + re._constants: REPEAT_ONE,makedict,AT_END_LINE sys: re: __module__,finditer,_expand itertools: __main__: re,itertools,baconhameggs - re.sre_parse: _PATTERNENDERS,SRE_FLAG_UNICODE + re._parser: _PATTERNENDERS,SRE_FLAG_UNICODE array: types: __module__,IntType,TypeType --------------------------------------------------- diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index cf324a57e79fdf..514c209b05a265 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -74,10 +74,10 @@ the following:: 1 0.000 0.000 0.001 0.001 :1() 1 0.000 0.000 0.001 0.001 re.py:212(compile) 1 0.000 0.000 0.001 0.001 re.py:268(_compile) - 1 0.000 0.000 0.000 0.000 sre_compile.py:172(_compile_charset) - 1 0.000 0.000 0.000 0.000 sre_compile.py:201(_optimize_charset) - 4 0.000 0.000 0.000 0.000 sre_compile.py:25(_identityfunction) - 3/1 0.000 0.000 0.000 0.000 sre_compile.py:33(_compile) + 1 0.000 0.000 0.000 0.000 _compiler.py:172(_compile_charset) + 1 0.000 0.000 0.000 0.000 _compiler.py:201(_optimize_charset) + 4 0.000 0.000 0.000 0.000 _compiler.py:25(_identityfunction) + 3/1 0.000 0.000 0.000 0.000 _compiler.py:33(_compile) The first line indicates that 197 calls were monitored. Of those calls, 192 were :dfn:`primitive`, meaning that the call was not induced via recursion. The diff --git a/Lib/re/__init__.py b/Lib/re/__init__.py index fdc2edff2ca664..c47a2650e32f5f 100644 --- a/Lib/re/__init__.py +++ b/Lib/re/__init__.py @@ -122,7 +122,7 @@ """ import enum -from . import sre_compile, sre_parse +from . import _compiler, _parser import functools try: import _locale @@ -145,21 +145,21 @@ @enum._simple_enum(enum.IntFlag, boundary=enum.KEEP) class RegexFlag: NOFLAG = 0 - ASCII = A = sre_compile.SRE_FLAG_ASCII # assume ascii "locale" - IGNORECASE = I = sre_compile.SRE_FLAG_IGNORECASE # ignore case - LOCALE = L = sre_compile.SRE_FLAG_LOCALE # assume current 8-bit locale - UNICODE = U = sre_compile.SRE_FLAG_UNICODE # assume unicode "locale" - MULTILINE = M = sre_compile.SRE_FLAG_MULTILINE # make anchors look for newline - DOTALL = S = sre_compile.SRE_FLAG_DOTALL # make dot match newline - VERBOSE = X = sre_compile.SRE_FLAG_VERBOSE # ignore whitespace and comments + ASCII = A = _compiler.SRE_FLAG_ASCII # assume ascii "locale" + IGNORECASE = I = _compiler.SRE_FLAG_IGNORECASE # ignore case + LOCALE = L = _compiler.SRE_FLAG_LOCALE # assume current 8-bit locale + UNICODE = U = _compiler.SRE_FLAG_UNICODE # assume unicode "locale" + MULTILINE = M = _compiler.SRE_FLAG_MULTILINE # make anchors look for newline + DOTALL = S = _compiler.SRE_FLAG_DOTALL # make dot match newline + VERBOSE = X = _compiler.SRE_FLAG_VERBOSE # ignore whitespace and comments # sre extensions (experimental, don't rely on these) - TEMPLATE = T = sre_compile.SRE_FLAG_TEMPLATE # disable backtracking - DEBUG = sre_compile.SRE_FLAG_DEBUG # dump pattern after compilation + TEMPLATE = T = _compiler.SRE_FLAG_TEMPLATE # disable backtracking + DEBUG = _compiler.SRE_FLAG_DEBUG # dump pattern after compilation __str__ = object.__str__ _numeric_repr_ = hex # sre exception -error = sre_compile.error +error = _compiler.error # -------------------------------------------------------------------- # public interface @@ -256,8 +256,8 @@ def escape(pattern): pattern = str(pattern, 'latin1') return pattern.translate(_special_chars_map).encode('latin1') -Pattern = type(sre_compile.compile('', 0)) -Match = type(sre_compile.compile('', 0).match('')) +Pattern = type(_compiler.compile('', 0)) +Match = type(_compiler.compile('', 0).match('')) # -------------------------------------------------------------------- # internals @@ -278,9 +278,9 @@ def _compile(pattern, flags): raise ValueError( "cannot process flags argument with a compiled pattern") return pattern - if not sre_compile.isstring(pattern): + if not _compiler.isstring(pattern): raise TypeError("first argument must be string or compiled pattern") - p = sre_compile.compile(pattern, flags) + p = _compiler.compile(pattern, flags) if not (flags & DEBUG): if len(_cache) >= _MAXCACHE: # Drop the oldest item @@ -294,12 +294,12 @@ def _compile(pattern, flags): @functools.lru_cache(_MAXCACHE) def _compile_repl(repl, pattern): # internal: compile replacement pattern - return sre_parse.parse_template(repl, pattern) + return _parser.parse_template(repl, pattern) def _expand(pattern, match, template): # internal: Match.expand implementation hook - template = sre_parse.parse_template(template, pattern) - return sre_parse.expand_template(template, match) + template = _parser.parse_template(template, pattern) + return _parser.expand_template(template, match) def _subx(pattern, template): # internal: Pattern.sub/subn implementation helper @@ -308,7 +308,7 @@ def _subx(pattern, template): # literal replacement return template[1][0] def filter(match, template=template): - return sre_parse.expand_template(template, match) + return _parser.expand_template(template, match) return filter # register myself for pickling @@ -325,22 +325,22 @@ def _pickle(p): class Scanner: def __init__(self, lexicon, flags=0): - from .sre_constants import BRANCH, SUBPATTERN + from ._constants import BRANCH, SUBPATTERN if isinstance(flags, RegexFlag): flags = flags.value self.lexicon = lexicon # combine phrases into a compound pattern p = [] - s = sre_parse.State() + s = _parser.State() s.flags = flags for phrase, action in lexicon: gid = s.opengroup() - p.append(sre_parse.SubPattern(s, [ - (SUBPATTERN, (gid, 0, 0, sre_parse.parse(phrase, flags))), + p.append(_parser.SubPattern(s, [ + (SUBPATTERN, (gid, 0, 0, _parser.parse(phrase, flags))), ])) s.closegroup(gid, p[-1]) - p = sre_parse.SubPattern(s, [(BRANCH, (None, p))]) - self.scanner = sre_compile.compile(p) + p = _parser.SubPattern(s, [(BRANCH, (None, p))]) + self.scanner = _compiler.compile(p) def scan(self, string): result = [] append = result.append diff --git a/Lib/re/sre_compile.py b/Lib/re/_compiler.py similarity index 99% rename from Lib/re/sre_compile.py rename to Lib/re/_compiler.py index a8ace208888080..b570a60ab59772 100644 --- a/Lib/re/sre_compile.py +++ b/Lib/re/_compiler.py @@ -11,8 +11,8 @@ """Internal support module for sre""" import _sre -from . import sre_parse -from .sre_constants import * +from . import _parser +from ._constants import * assert _sre.MAGIC == MAGIC, "SRE module mismatch" @@ -68,7 +68,7 @@ for t in _equivalences for i in t} def _combine_flags(flags, add_flags, del_flags, - TYPE_FLAGS=sre_parse.TYPE_FLAGS): + TYPE_FLAGS=_parser.TYPE_FLAGS): if add_flags & TYPE_FLAGS: flags &= ~TYPE_FLAGS return (flags | add_flags) & ~del_flags @@ -777,7 +777,7 @@ def compile(p, flags=0): if isstring(p): pattern = p - p = sre_parse.parse(p, flags) + p = _parser.parse(p, flags) else: pattern = None diff --git a/Lib/re/sre_constants.py b/Lib/re/_constants.py similarity index 97% rename from Lib/re/sre_constants.py rename to Lib/re/_constants.py index 332a4afec2ff37..2d10ba6dc3be44 100644 --- a/Lib/re/sre_constants.py +++ b/Lib/re/_constants.py @@ -229,8 +229,8 @@ def dump(f, d, prefix): * * regular expression matching engine * - * NOTE: This file is generated by Lib/re/sre_constants.py. If you need - * to change anything in here, edit Lib/re/sre_constants.py and run it. + * NOTE: This file is generated by Lib/re/_constants.py. If you need + * to change anything in here, edit Lib/re/_constants.py and run it. * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. * diff --git a/Lib/re/sre_parse.py b/Lib/re/_parser.py similarity index 99% rename from Lib/re/sre_parse.py rename to Lib/re/_parser.py index f24488d361a832..e088de6facddc6 100644 --- a/Lib/re/sre_parse.py +++ b/Lib/re/_parser.py @@ -12,7 +12,7 @@ # XXX: show string offset and offending character for all errors -from .sre_constants import * +from ._constants import * SPECIAL_CHARS = ".\\[{()*+?^$|" REPEAT_CHARS = "*+?{" diff --git a/Lib/sre_compile.py b/Lib/sre_compile.py index 3182797bb7e98e..c43b39d326df7d 100644 --- a/Lib/sre_compile.py +++ b/Lib/sre_compile.py @@ -3,4 +3,4 @@ DeprecationWarning, stacklevel=2) -from re.sre_compile import * +from re._compiler import * diff --git a/Lib/sre_constants.py b/Lib/sre_constants.py index f9f182162a6d4e..883e46760fb828 100644 --- a/Lib/sre_constants.py +++ b/Lib/sre_constants.py @@ -3,4 +3,4 @@ DeprecationWarning, stacklevel=2) -from re.sre_constants import * +from re._constants import * diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py index 8e24714264cf30..d9de2ef15159de 100644 --- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -3,4 +3,4 @@ DeprecationWarning, stacklevel=2) -from re.sre_parse import * +from re._parser import * diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py index 2afd23cd43665a..157c522b63bd0b 100644 --- a/Lib/test/test_pyclbr.py +++ b/Lib/test/test_pyclbr.py @@ -221,7 +221,7 @@ def test_others(self): cm('cgi', ignore=('log',)) # set with = in module cm('pickle', ignore=('partial', 'PickleBuffer')) cm('aifc', ignore=('_aifc_params',)) # set with = in module - cm('re.sre_parse', ignore=('dump', 'groups', 'pos')) # from .sre_constants import *; property + cm('re._parser', ignore=('dump', 'groups', 'pos')) # from ._constants import *; property cm( 'pdb', # pyclbr does not handle elegantly `typing` or properties diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 8b74cbb4e37778..7325a289605c30 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -569,7 +569,7 @@ def test_re_groupref_exists(self): 'two branches', 10) def test_re_groupref_overflow(self): - from re.sre_constants import MAXGROUPS + from re._constants import MAXGROUPS self.checkTemplateError('()', r'\g<%s>' % MAXGROUPS, 'xx', 'invalid group reference %d' % MAXGROUPS, 3) self.checkPatternError(r'(?P)(?(%d))' % MAXGROUPS, @@ -2433,7 +2433,7 @@ def test_immutable(self): tp.foo = 1 def test_overlap_table(self): - f = re.sre_compile._generate_overlap_table + f = re._compiler._generate_overlap_table self.assertEqual(f(""), []) self.assertEqual(f("a"), [0]) self.assertEqual(f("abcd"), [0, 0, 0, 0]) @@ -2442,8 +2442,8 @@ def test_overlap_table(self): self.assertEqual(f("abcabdac"), [0, 0, 0, 1, 2, 0, 1, 0]) def test_signedness(self): - self.assertGreaterEqual(re.sre_compile.MAXREPEAT, 0) - self.assertGreaterEqual(re.sre_compile.MAXGROUPS, 0) + self.assertGreaterEqual(re._compiler.MAXREPEAT, 0) + self.assertGreaterEqual(re._compiler.MAXGROUPS, 0) @cpython_only def test_disallow_instantiation(self): diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index 7cbecbb943454f..dd018d6b38a864 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -523,7 +523,7 @@ def test_startup_imports(self): self.assertIn('site', modules) # http://bugs.python.org/issue19205 - re_mods = {'re', '_sre', 're.sre_compile', 're.sre_constants', 're.sre_parse'} + re_mods = {'re', '_sre', 're._compiler', 're._constants', 're._parser'} self.assertFalse(modules.intersection(re_mods), stderr) # http://bugs.python.org/issue9548 diff --git a/Misc/NEWS.d/next/Library/2022-03-29-19-14-53.bpo-47152.5rl5ZK.rst b/Misc/NEWS.d/next/Library/2022-03-29-19-14-53.bpo-47152.5rl5ZK.rst index 44f40e2609a5bc..1e1633daae5977 100644 --- a/Misc/NEWS.d/next/Library/2022-03-29-19-14-53.bpo-47152.5rl5ZK.rst +++ b/Misc/NEWS.d/next/Library/2022-03-29-19-14-53.bpo-47152.5rl5ZK.rst @@ -1,2 +1,2 @@ -Convert the :mod:`re` module into a package. Deprecate undocumented modules -``sre_compile``, ``sre_constants`` and ``sre_parse``. +Convert the :mod:`re` module into a package. Deprecate modules ``sre_compile``, +``sre_constants`` and ``sre_parse``. diff --git a/Modules/sre_constants.h b/Modules/sre_constants.h index 20f1b76460c506..45395dcea807a3 100644 --- a/Modules/sre_constants.h +++ b/Modules/sre_constants.h @@ -3,8 +3,8 @@ * * regular expression matching engine * - * NOTE: This file is generated by Lib/re/sre_constants.py. If you need - * to change anything in here, edit Lib/re/sre_constants.py and run it. + * NOTE: This file is generated by Lib/re/_constants.py. If you need + * to change anything in here, edit Lib/re/_constants.py and run it. * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. * From eedf86c38679f387af5fe588b941708804d2416d Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 2 Apr 2022 10:44:33 +0300 Subject: [PATCH 8/9] Keep undescored names in the deprecated modules. --- Lib/sre_compile.py | 3 ++- Lib/sre_constants.py | 3 ++- Lib/sre_parse.py | 3 ++- Lib/test/test_re.py | 17 ++++++++++++++++- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Lib/sre_compile.py b/Lib/sre_compile.py index c43b39d326df7d..f9da61e6487869 100644 --- a/Lib/sre_compile.py +++ b/Lib/sre_compile.py @@ -3,4 +3,5 @@ DeprecationWarning, stacklevel=2) -from re._compiler import * +from re import _compiler as _ +globals().update({k: v for k, v in vars(_).items() if k[:2] != '__'}) diff --git a/Lib/sre_constants.py b/Lib/sre_constants.py index 883e46760fb828..fa09d044292965 100644 --- a/Lib/sre_constants.py +++ b/Lib/sre_constants.py @@ -3,4 +3,5 @@ DeprecationWarning, stacklevel=2) -from re._constants import * +from re import _constants as _ +globals().update({k: v for k, v in vars(_).items() if k[:2] != '__'}) diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py index d9de2ef15159de..25a3f557d44c61 100644 --- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -3,4 +3,5 @@ DeprecationWarning, stacklevel=2) -from re._parser import * +from re import _parser as _ +globals().update({k: v for k, v in vars(_).items() if k[:2] != '__'}) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 7325a289605c30..f1e5af452d8e06 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -2454,7 +2454,17 @@ def test_disallow_instantiation(self): check_disallow_instantiation(self, type(pat.scanner(""))) def test_deprecated_modules(self): - for name in 'sre_compile', 'sre_constants', 'sre_parse': + deprecated = { + 'sre_compile': ['compile', 'error', + 'SRE_FLAG_IGNORECASE', 'SUBPATTERN', + '_compile_info'], + 'sre_constants': ['error', 'SRE_FLAG_IGNORECASE', 'SUBPATTERN', + '_NamedIntConstant'], + 'sre_parse': ['SubPattern', 'parse', + 'SRE_FLAG_IGNORECASE', 'SUBPATTERN', + '_parse_sub'], + } + for name in deprecated: with self.subTest(module=name): sys.modules.pop(name, None) with self.assertWarns(DeprecationWarning) as cm: @@ -2463,6 +2473,11 @@ def test_deprecated_modules(self): f"module {name!r} is deprecated") self.assertEqual(cm.warnings[0].filename, __file__) self.assertIn(name, sys.modules) + mod = sys.modules[name] + self.assertEqual(mod.__name__, name) + self.assertEqual(mod.__package__, '') + for attr in deprecated[name]: + self.assertTrue(hasattr(mod, attr)) del sys.modules[name] class ExternalTests(unittest.TestCase): From 9114da4a70d8533b839986127e2e79de49575b43 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 2 Apr 2022 10:48:00 +0300 Subject: [PATCH 9/9] Fix internal references. --- Lib/re/_compiler.py | 2 +- Lib/re/_constants.py | 2 +- Lib/re/_parser.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/re/_compiler.py b/Lib/re/_compiler.py index b570a60ab59772..62da8e55d72abd 100644 --- a/Lib/re/_compiler.py +++ b/Lib/re/_compiler.py @@ -5,7 +5,7 @@ # # Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. # -# See the re.py file for information on usage and redistribution. +# See the __init__.py file for information on usage and redistribution. # """Internal support module for sre""" diff --git a/Lib/re/_constants.py b/Lib/re/_constants.py index 2d10ba6dc3be44..c735edfea1f13d 100644 --- a/Lib/re/_constants.py +++ b/Lib/re/_constants.py @@ -6,7 +6,7 @@ # # Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. # -# See the sre.py file for information on usage and redistribution. +# See the __init__.py file for information on usage and redistribution. # """Internal support module for sre""" diff --git a/Lib/re/_parser.py b/Lib/re/_parser.py index e088de6facddc6..ae44118564eb7d 100644 --- a/Lib/re/_parser.py +++ b/Lib/re/_parser.py @@ -5,7 +5,7 @@ # # Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. # -# See the sre.py file for information on usage and redistribution. +# See the __init__.py file for information on usage and redistribution. # """Internal support module for sre"""