summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2015-03-30 01:01:48 +0300
committerSerhiy Storchaka <storchaka@gmail.com>2015-03-30 01:01:48 +0300
commit07360df481adeacfc2b7a1a7f89ae9a76e86b725 (patch)
tree1d111118cafc0117d3cd68fdfa7397e68dd25191
parent1813c1701f8e7e9287bccf66d1b4b8348c432168 (diff)
downloadcpython-git-07360df481adeacfc2b7a1a7f89ae9a76e86b725.tar.gz
Issue #14260: The groupindex attribute of regular expression pattern object
now is non-modifiable mapping.
-rw-r--r--Lib/csv.py7
-rw-r--r--Lib/sre_parse.py3
-rw-r--r--Lib/test/test_re.py8
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/_sre.c15
5 files changed, 31 insertions, 5 deletions
diff --git a/Lib/csv.py b/Lib/csv.py
index a56eed88c8..c3c31f01fd 100644
--- a/Lib/csv.py
+++ b/Lib/csv.py
@@ -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]:
diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py
index 0bce71e9c9..c0f539dd93 100644
--- a/Lib/sre_parse.py
+++ b/Lib/sre_parse.py
@@ -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:
diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py
index 020656a62a..5b716125f9 100644
--- a/Lib/test/test_re.py
+++ b/Lib/test/test_re.py
@@ -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")
diff --git a/Misc/NEWS b/Misc/NEWS
index 333f6457ee..351a07fb80 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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.
diff --git a/Modules/_sre.c b/Modules/_sre.c
index 83eb96376a..8cad1ac270 100644
--- a/Modules/_sre.c
+++ b/Modules/_sre.c
@@ -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 */