diff --git a/Lib/re/_parser.py b/Lib/re/_parser.py index aab9b59168015c..0751f941a7a3a6 100644 --- a/Lib/re/_parser.py +++ b/Lib/re/_parser.py @@ -606,7 +606,7 @@ def addmember(code): if allow_nested and sourcematch("["): # A nested set after an operator is the whole operand, used as-is (not # wrapped in a group); it cannot be combined with loose members. - compound = _parse_charset(source, state, nested + 1) + compound = _parse_charset(source, state, nested + 2) while True: this = sourceget() if this is None: diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index d086fd521e73b5..5b05f3aa604bac 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -1537,6 +1537,10 @@ def test_set_operations(self): with warnings.catch_warnings(): warnings.simplefilter('error', FutureWarning) re.compile(r'[a-z--[aeiou]]') + # A reserved construct inside a nested operand warns against the caller. + with self.assertWarnsRegex(FutureWarning, 'Possible nested set ') as w: + re.compile(r'[a--[[b]]]') + self.assertEqual(w.filename, __file__) # Set union A||B == A or B (an explicit form of [AB]); flat operands # merge into one charset, otherwise the operations are alternated. @@ -1557,6 +1561,10 @@ def test_set_operations(self): self.assertEqual(re.findall(r'[\d~~1]', s), list('0123456789~')) self.assertEqual(w.filename, __file__) self.assertEqual(re.findall(r'[~~1]', s), list('1~')) + with self.assertWarnsRegex(FutureWarning, + 'Possible set symmetric difference ') as w: + re.compile(r'[a||[c~~d]]') + self.assertEqual(w.filename, __file__) def test_search_coverage(self): self.assertEqual(re.search(r"\s(b)", " b").group(1), "b")