diff -r 193ac288bc7f Lib/test/test_re.py --- a/Lib/test/test_re.py Sat Nov 01 11:05:36 2014 +0200 +++ b/Lib/test/test_re.py Sat Nov 01 16:48:22 2014 +0200 @@ -493,6 +493,13 @@ class ReTests(unittest.TestCase): self.assertEqual(re.match("(a)", "a").regs, ((0, 1), (0, 1))) self.assertTrue(re.match("(a)", "a").re) + # Issue 14260. + p = re.compile(r'abc(?Pdef)') + self.assertEqual(sorted(p.groupindex), ["n"]) + self.assertEqual(p.groupindex["n"], 1) + self.asserRaises(TypeError): + p.groupindex["n"] = 0 + def test_special_escapes(self): self.assertEqual(re.search(r"\b(b.)\b", "abcd abc bcd bx").group(1), "bx") diff -r 193ac288bc7f Modules/_sre.c --- a/Modules/_sre.c Sat Nov 01 11:05:36 2014 +0200 +++ b/Modules/_sre.c Sat Nov 01 16:48:22 2014 +0200 @@ -1371,12 +1371,24 @@ static PyMethodDef pattern_methods[] = { {NULL, NULL} }; +/* PatternObject's 'groupindex' method. */ +static PyObject * +pattern_groupindex(PatternObject *self) +{ + return PyDictProxy_New(self->groupindex); +} + +static PyGetSetDef pattern_getset[] = { + {"groupindex", (getter)pattern_groupindex, (setter)NULL, + "A dictionary mapping group names to group numbers."}, + {NULL} /* Sentinel */ +}; + #define PAT_OFF(x) offsetof(PatternObject, x) static PyMemberDef pattern_members[] = { {"pattern", T_OBJECT, PAT_OFF(pattern), READONLY}, {"flags", T_INT, PAT_OFF(flags), READONLY}, {"groups", T_PYSSIZET, PAT_OFF(groups), READONLY}, - {"groupindex", T_OBJECT, PAT_OFF(groupindex), READONLY}, {NULL} /* Sentinel */ }; @@ -1409,6 +1421,7 @@ static PyTypeObject Pattern_Type = { 0, /* tp_iternext */ pattern_methods, /* tp_methods */ pattern_members, /* tp_members */ + pattern_getset, /* tp_getset */ }; static int _validate(PatternObject *self); /* Forward */