diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2022-03-19 14:10:44 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-19 14:10:44 (GMT) |
commit | 92a6abf72e7a8274f96edbb5297119d4ff055be7 (patch) | |
tree | 158af2148f4027e63d9b19cfaf968b6da7848c2e | |
parent | cb7874f49d3d55df73a3c529773af14e2e344fb7 (diff) | |
download | cpython-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.rst | 3 | ||||
-rw-r--r-- | Doc/whatsnew/3.11.rst | 5 | ||||
-rw-r--r-- | Lib/sre_parse.py | 13 | ||||
-rw-r--r-- | Lib/test/test_re.py | 68 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2022-03-19-14-12-23.bpo-47066.we3YFx.rst | 3 |
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. |