]> granicus.if.org Git - python/commitdiff
Issue #14260: The groupindex attribute of regular expression pattern object
authorSerhiy Storchaka <storchaka@gmail.com>
Sun, 29 Mar 2015 22:01:48 +0000 (01:01 +0300)
committerSerhiy Storchaka <storchaka@gmail.com>
Sun, 29 Mar 2015 22:01:48 +0000 (01:01 +0300)
now is non-modifiable mapping.

Lib/csv.py
Lib/sre_parse.py
Lib/test/test_re.py
Misc/NEWS
Modules/_sre.c

index a56eed88c862d4a43cbbcf10b5603ffb327badcc..c3c31f01fd072f59fb729748cb1599f0d652e6f9 100644 (file)
@@ -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]:
index 0bce71e9c97ce7f0defe45dd2b679643413f83fe..c0f539dd931ad2e6c924926056f72673760b9524 100644 (file)
@@ -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:
index 020656a62a4a2273a9318449fce1aa340fff9078..5b716125f97400884386a2464c7fe044a1f06746 100644 (file)
@@ -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")
index 333f6457ee3f07652d6ed5346d07c673a6983910..351a07fb808428880f63472588b18a7a4710b510 100644 (file)
--- 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.
index 83eb96376a7ff4e56f9507fb124067671f1eaa14..8cad1ac270bc06c3b295ffa1829f3af78c4e72a5 100644 (file)
@@ -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 */