Kaydet (Commit) 07360df4 authored tarafından Serhiy Storchaka's avatar Serhiy Storchaka

Issue #14260: The groupindex attribute of regular expression pattern object

now is non-modifiable mapping.
üst 1813c170
......@@ -231,20 +231,21 @@ class Sniffer:
quotes = {}
delims = {}
spaces = 0
groupindex = regexp.groupindex
for m in matches:
n = regexp.groupindex['quote'] - 1
n = groupindex['quote'] - 1
key = m[n]
if key:
quotes[key] = quotes.get(key, 0) + 1
try:
n = regexp.groupindex['delim'] - 1
n = groupindex['delim'] - 1
key = m[n]
except KeyError:
continue
if key and (delimiters is None or key in delimiters):
delims[key] = delims.get(key, 0) + 1
try:
n = regexp.groupindex['space'] - 1
n = groupindex['space'] - 1
except KeyError:
continue
if m[n]:
......
......@@ -855,6 +855,7 @@ def parse_template(source, pattern):
del literal[:]
groups.append((len(literals), index))
literals.append(None)
groupindex = pattern.groupindex
while True:
this = sget()
if this is None:
......@@ -869,7 +870,7 @@ def parse_template(source, pattern):
name = s.getuntil(">")
if name.isidentifier():
try:
index = pattern.groupindex[name]
index = groupindex[name]
except KeyError:
raise IndexError("unknown group name %r" % name)
else:
......
......@@ -577,6 +577,14 @@ class ReTests(unittest.TestCase):
self.assertEqual(re.match("(a)", "a").regs, ((0, 1), (0, 1)))
self.assertTrue(re.match("(a)", "a").re)
# Issue 14260. groupindex should be non-modifiable mapping.
p = re.compile(r'(?i)(?P<first>a)(?P<other>b)')
self.assertEqual(sorted(p.groupindex), ['first', 'other'])
self.assertEqual(p.groupindex['other'], 2)
with self.assertRaises(TypeError):
p.groupindex['other'] = 0
self.assertEqual(p.groupindex['other'], 2)
def test_special_escapes(self):
self.assertEqual(re.search(r"\b(b.)\b",
"abcd abc bcd bx").group(1), "bx")
......
......@@ -30,6 +30,9 @@ Core and Builtins
Library
-------
- Issue #14260: The groupindex attribute of regular expression pattern object
now is non-modifiable mapping.
- Issue #23792: Ignore KeyboardInterrupt when the pydoc pager is active.
This mimics the behavior of the standard unix pagers, and prevents
pipepager from shutting down while the pager itself is still running.
......
......@@ -1384,12 +1384,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 */
};
......@@ -1422,6 +1434,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 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment