diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 1eca22f45378df1..5b534c703a1f52e 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -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(), ()) diff --git a/Misc/ACKS b/Misc/ACKS index 94cb1965676f484..548b26f1786f26e 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1873,6 +1873,7 @@ Steven Troxler Brent Tubbs Anthony Tuininga Erno Tukia +Anıl Tuncel Adam Turner David Turner Stephen Turner diff --git a/Misc/NEWS.d/next/Library/2019-07-13-15-23-34.bpo-7940.NDghRj.rst b/Misc/NEWS.d/next/Library/2019-07-13-15-23-34.bpo-7940.NDghRj.rst new file mode 100644 index 000000000000000..bad823178b79bdf --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-07-13-15-23-34.bpo-7940.NDghRj.rst @@ -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). diff --git a/Modules/_sre/sre.c b/Modules/_sre/sre.c index 0f134b194de6f67..fc9143f62ae646a 100644 --- a/Modules/_sre/sre.c +++ b/Modules/_sre/sre.c @@ -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)