Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions Lib/test/test_re.py
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,65 @@ def test_bug_117612(self):
self.assertEqual(re.findall(r"(a|(b))", "aba"),
[("a", ""),("b", "b"),("a", "")])

def test_bug_7940(self):
# Issue 7940: re.finditer and re.findall should support negative end positions
pat = re.compile(".")

with self.assertWarns(FutureWarning) as cm:
self.assertEqual(pat.findall("abcd", -1, 1), [])
self.assertEqual(str(cm.warning), "Negative start index will not "
"be truncated to zero in the future")

with self.assertWarns(FutureWarning) as cm:
self.assertEqual(pat.findall("abcd", 1, -1), ['b', 'c'])
self.assertEqual(str(cm.warning), "Negative end index will not "
"be truncated to zero in the future")

with self.assertWarns(FutureWarning) as cm:
self.assertEqual(pat.findall("abcd", 1, 3), ['b', 'c'])
self.assertEqual(pat.findall("abcd", 1, -1), ['b', 'c'])
self.assertEqual(pat.findall("abcd", -3, -1), ['b', 'c'])
self.assertEqual(pat.findall("abcd", -3, 3), ['b', 'c'])
self.assertEqual(pat.findall("abcd", -1, 1), [])
self.assertEqual(pat.findall("abcd", -1, -3), [])
self.assertEqual(pat.findall("abcd", -200, -1), ['a', 'b', 'c'])
self.assertEqual(pat.findall("abcd", -200, -100), [])
self.assertEqual(pat.findall("abcd", pos=1, endpos=-1), ['b', 'c'])
self.assertEqual(len(cm.warnings), 12)

with self.assertWarns(FutureWarning) as cm:
self.assertEqual([m[0] for m in pat.finditer("abcd", -1, 1)],
[])
self.assertEqual(str(cm.warning), "Negative start index will not "
"be truncated to zero in the future")

with self.assertWarns(FutureWarning) as cm:
self.assertEqual([m[0] for m in pat.finditer("abcd", 1, -1)],
['b', 'c'])
self.assertEqual(str(cm.warning), "Negative end index will not "
"be truncated to zero in the future")

with self.assertWarns(FutureWarning) as cm:
self.assertEqual([m[0] for m in pat.finditer("abcd", 1, 3)],
['b', 'c'])
self.assertEqual([m[0] for m in pat.finditer("abcd", 1, -1)],
['b', 'c'])
self.assertEqual([m[0] for m in pat.finditer("abcd", -3, -1)],
['b', 'c'])
self.assertEqual([m[0] for m in pat.finditer("abcd", -3, 3)],
['b', 'c'])
self.assertEqual([m[0] for m in pat.finditer("abcd", -1, 1)],
[])
self.assertEqual([m[0] for m in pat.finditer("abcd", -1, -3)],
[])
self.assertEqual([m[0] for m in pat.finditer("abcd", -200, -1)],
['a', 'b', 'c'])
self.assertEqual([m[0] for m in pat.finditer("abcd", -200, -100)],
[])
self.assertEqual([m[0] for m in pat.finditer("abcd", pos=1,
endpos=-1)], ['b', 'c'])
self.assertEqual(len(cm.warnings), 12)

def test_re_match(self):
for string in 'a', S('a'):
self.assertEqual(re.match('a', string).groups(), ())
Expand Down
1 change: 1 addition & 0 deletions Misc/ACKS
Original file line number Diff line number Diff line change
Expand Up @@ -1873,6 +1873,7 @@ Steven Troxler
Brent Tubbs
Anthony Tuininga
Erno Tukia
Anıl Tuncel
Adam Turner
David Turner
Stephen Turner
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Add support for negative end positions to re.finditer and re.findall
(original patch by Matthew Barnett, tests and PR by Mustafa Anıl Tuncel).
12 changes: 12 additions & 0 deletions Modules/_sre/sre.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,11 +482,23 @@ state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string,
}

/* adjust boundaries */
if (start < 0) {
PyErr_WarnEx(PyExc_FutureWarning,
"Negative start index will not be truncated to zero in the future",
1);
start += length;
}
if (start < 0)
start = 0;
else if (start > length)
start = length;

if (end < 0) {
PyErr_WarnEx(PyExc_FutureWarning,
"Negative end index will not be truncated to zero in the future",
1);
end += length;
}
if (end < 0)
end = 0;
else if (end > length)
Expand Down