summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2022-03-19 14:10:44 (GMT)
committerGitHub <noreply@github.com>2022-03-19 14:10:44 (GMT)
commit92a6abf72e7a8274f96edbb5297119d4ff055be7 (patch)
tree158af2148f4027e63d9b19cfaf968b6da7848c2e
parentcb7874f49d3d55df73a3c529773af14e2e344fb7 (diff)
downloadcpython-92a6abf72e7a8274f96edbb5297119d4ff055be7.zip
cpython-92a6abf72e7a8274f96edbb5297119d4ff055be7.tar.gz
cpython-92a6abf72e7a8274f96edbb5297119d4ff055be7.tar.bz2
bpo-47066: Convert a warning about flags not at the start of the regular expression into error (GH-31994)
-rw-r--r--Doc/library/re.rst3
-rw-r--r--Doc/whatsnew/3.11.rst5
-rw-r--r--Lib/sre_parse.py13
-rw-r--r--Lib/test/test_re.py68
-rw-r--r--Misc/NEWS.d/next/Library/2022-03-19-14-12-23.bpo-47066.we3YFx.rst3
5 files changed, 26 insertions, 66 deletions
diff --git a/Doc/library/re.rst b/Doc/library/re.rst
index 8d62e3b..950a5b1 100644
--- a/Doc/library/re.rst
+++ b/Doc/library/re.rst
@@ -299,6 +299,9 @@ The special characters are:
:func:`re.compile` function. Flags should be used first in the
expression string.
+ .. versionchanged:: 3.11
+ This construction can only be used at the start of the expression.
+
.. index:: single: (?:; in regular expressions
``(?:...)``
diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst
index 8b3450e..b7e9dc6 100644
--- a/Doc/whatsnew/3.11.rst
+++ b/Doc/whatsnew/3.11.rst
@@ -688,6 +688,11 @@ Changes in the Python API
if no locale is specified.
(Contributed by Victor Stinner in :issue:`46659`.)
+* Global inline flags (e.g. ``(?i)``) can now only be used at the start of
+ the regular expressions. Using them not at the start of expression was
+ deprecated since Python 3.6.
+ (Contributed by Serhiy Storchaka in :issue:`47066`.)
+
Build Changes
=============
diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py
index 5370667..bb95107 100644
--- a/Lib/sre_parse.py
+++ b/Lib/sre_parse.py
@@ -805,16 +805,9 @@ def _parse(source, state, verbose, nested, first=False):
flags = _parse_flags(source, state, char)
if flags is None: # global flags
if not first or subpattern:
- import warnings
- warnings.warn(
- 'Flags not at the start of the expression %r%s'
- ' but at position %d' % (
- source.string[:20], # truncate long regexes
- ' (truncated)' if len(source.string) > 20 else '',
- start,
- ),
- DeprecationWarning, stacklevel=nested + 6
- )
+ raise source.error('global flags not at the start '
+ 'of the expression',
+ source.tell() - start)
if (state.flags & SRE_FLAG_VERBOSE) and not verbose:
raise Verbose
continue
diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py
index 48dcb16..f8bbe51 100644
--- a/Lib/test/test_re.py
+++ b/Lib/test/test_re.py
@@ -1439,66 +1439,22 @@ class ReTests(unittest.TestCase):
self.assertTrue(re.match('(?x) (?i) ' + upper_char, lower_char))
self.assertTrue(re.match(' (?x) (?i) ' + upper_char, lower_char, re.X))
- p = upper_char + '(?i)'
- with self.assertWarns(DeprecationWarning) as warns:
- self.assertTrue(re.match(p, lower_char))
- self.assertEqual(
- str(warns.warnings[0].message),
- 'Flags not at the start of the expression %r'
- ' but at position 1' % p
- )
- self.assertEqual(warns.warnings[0].filename, __file__)
-
- p = upper_char + '(?i)%s' % ('.?' * 100)
- with self.assertWarns(DeprecationWarning) as warns:
- self.assertTrue(re.match(p, lower_char))
- self.assertEqual(
- str(warns.warnings[0].message),
- 'Flags not at the start of the expression %r (truncated)'
- ' but at position 1' % p[:20]
- )
- self.assertEqual(warns.warnings[0].filename, __file__)
+ msg = "global flags not at the start of the expression"
+ self.checkPatternError(upper_char + '(?i)', msg, 1)
# bpo-30605: Compiling a bytes instance regex was throwing a BytesWarning
with warnings.catch_warnings():
warnings.simplefilter('error', BytesWarning)
- p = b'A(?i)'
- with self.assertWarns(DeprecationWarning) as warns:
- self.assertTrue(re.match(p, b'a'))
- self.assertEqual(
- str(warns.warnings[0].message),
- 'Flags not at the start of the expression %r'
- ' but at position 1' % p
- )
- self.assertEqual(warns.warnings[0].filename, __file__)
-
- with self.assertWarns(DeprecationWarning):
- self.assertTrue(re.match('(?s).(?i)' + upper_char, '\n' + lower_char))
- with self.assertWarns(DeprecationWarning):
- self.assertTrue(re.match('(?i) ' + upper_char + ' (?x)', lower_char))
- with self.assertWarns(DeprecationWarning):
- self.assertTrue(re.match(' (?x) (?i) ' + upper_char, lower_char))
- with self.assertWarns(DeprecationWarning):
- self.assertTrue(re.match('^(?i)' + upper_char, lower_char))
- with self.assertWarns(DeprecationWarning):
- self.assertTrue(re.match('$|(?i)' + upper_char, lower_char))
- with self.assertWarns(DeprecationWarning) as warns:
- self.assertTrue(re.match('(?:(?i)' + upper_char + ')', lower_char))
- self.assertRegex(str(warns.warnings[0].message),
- 'Flags not at the start')
- self.assertEqual(warns.warnings[0].filename, __file__)
- with self.assertWarns(DeprecationWarning) as warns:
- self.assertTrue(re.fullmatch('(^)?(?(1)(?i)' + upper_char + ')',
- lower_char))
- self.assertRegex(str(warns.warnings[0].message),
- 'Flags not at the start')
- self.assertEqual(warns.warnings[0].filename, __file__)
- with self.assertWarns(DeprecationWarning) as warns:
- self.assertTrue(re.fullmatch('($)?(?(1)|(?i)' + upper_char + ')',
- lower_char))
- self.assertRegex(str(warns.warnings[0].message),
- 'Flags not at the start')
- self.assertEqual(warns.warnings[0].filename, __file__)
+ self.checkPatternError(b'A(?i)', msg, 1)
+
+ self.checkPatternError('(?s).(?i)' + upper_char, msg, 5)
+ self.checkPatternError('(?i) ' + upper_char + ' (?x)', msg, 7)
+ self.checkPatternError(' (?x) (?i) ' + upper_char, msg, 1)
+ self.checkPatternError('^(?i)' + upper_char, msg, 1)
+ self.checkPatternError('$|(?i)' + upper_char, msg, 2)
+ self.checkPatternError('(?:(?i)' + upper_char + ')', msg, 3)
+ self.checkPatternError('(^)?(?(1)(?i)' + upper_char + ')', msg, 9)
+ self.checkPatternError('($)?(?(1)|(?i)' + upper_char + ')', msg, 10)
def test_dollar_matches_twice(self):
diff --git a/Misc/NEWS.d/next/Library/2022-03-19-14-12-23.bpo-47066.we3YFx.rst b/Misc/NEWS.d/next/Library/2022-03-19-14-12-23.bpo-47066.we3YFx.rst
new file mode 100644
index 0000000..f28275b
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-03-19-14-12-23.bpo-47066.we3YFx.rst
@@ -0,0 +1,3 @@
+Global inline flags (e.g. ``(?i)``) can now only be used at the start of the
+regular expressions. Using them not at the start of expression was
+deprecated since Python 3.6.