Skip to content

Commit 7cb581a

Browse files
committed
gh-156187: Fix the warning stacklevel inside a nested set operand
_parse_charset() derives the stacklevel of its FutureWarning from nested, and the nested-operand path inserts two frames, _parse_operand() and the inner _parse_charset(), while advancing nested by one. The warning was therefore reported against a frame inside the re package instead of the caller, and further off the deeper the nesting.
1 parent cdca502 commit 7cb581a

2 files changed

Lines changed: 9 additions & 1 deletion

File tree

Lib/re/_parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,7 @@ def addmember(code):
606606
if allow_nested and sourcematch("["):
607607
# A nested set after an operator is the whole operand, used as-is (not
608608
# wrapped in a group); it cannot be combined with loose members.
609-
compound = _parse_charset(source, state, nested + 1)
609+
compound = _parse_charset(source, state, nested + 2)
610610
while True:
611611
this = sourceget()
612612
if this is None:

Lib/test/test_re.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,6 +1537,10 @@ def test_set_operations(self):
15371537
with warnings.catch_warnings():
15381538
warnings.simplefilter('error', FutureWarning)
15391539
re.compile(r'[a-z--[aeiou]]')
1540+
# A reserved construct inside a nested operand warns against the caller.
1541+
with self.assertWarnsRegex(FutureWarning, 'Possible nested set ') as w:
1542+
re.compile(r'[a--[[b]]]')
1543+
self.assertEqual(w.filename, __file__)
15401544

15411545
# Set union A||B == A or B (an explicit form of [AB]); flat operands
15421546
# merge into one charset, otherwise the operations are alternated.
@@ -1557,6 +1561,10 @@ def test_set_operations(self):
15571561
self.assertEqual(re.findall(r'[\d~~1]', s), list('0123456789~'))
15581562
self.assertEqual(w.filename, __file__)
15591563
self.assertEqual(re.findall(r'[~~1]', s), list('1~'))
1564+
with self.assertWarnsRegex(FutureWarning,
1565+
'Possible set symmetric difference ') as w:
1566+
re.compile(r'[a||[c~~d]]')
1567+
self.assertEqual(w.filename, __file__)
15601568

15611569
def test_search_coverage(self):
15621570
self.assertEqual(re.search(r"\s(b)", " b").group(1), "b")

0 commit comments

Comments
 (0)