[issue20283] Wrong keyword parameter name in regex pattern methods

Serhiy Storchaka report at bugs.python.org
Mon Mar 3 22:20:56 CET 2014


Serhiy Storchaka added the comment:

The disadvantage of sre_deprecate_pattern_keyword-3.4.patch is that it creates 
false signature for SRE_Pattern.match(). Default value of first argument is 
exposed as None, but actually this parameter is mandatory and None is not 
valid value for it. I afraid the only way to get rid of false signature (and 
keep backward compatibility) is to revert converting to Argument Clinic.  And 
here is a patch which do this.

----------
Added file: http://bugs.python.org/file34280/sre_deprecate_pattern_keyword-3.4_2.patch

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue20283>
_______________________________________
-------------- next part --------------
diff -r c47cc6351ce7 Modules/_sre.c
--- a/Modules/_sre.c	Mon Mar 03 21:19:19 2014 +0200
+++ b/Modules/_sre.c	Mon Mar 03 23:11:13 2014 +0200
@@ -526,59 +526,49 @@
     return sre_ucs4_search(state, pattern);
 }
 
-/*[clinic input]
-module _sre
-class _sre.SRE_Pattern "PatternObject *" "&Pattern_Type"
-
-_sre.SRE_Pattern.match as pattern_match
-
-    pattern: object
-    pos: Py_ssize_t = 0
-    endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize
-
-Matches zero or more characters at the beginning of the string.
-[clinic start generated code]*/
-
-PyDoc_STRVAR(pattern_match__doc__,
-"match($self, /, pattern, pos=0, endpos=sys.maxsize)\n"
-"--\n"
-"\n"
-"Matches zero or more characters at the beginning of the string.");
-
-#define PATTERN_MATCH_METHODDEF    \
-    {"match", (PyCFunction)pattern_match, METH_VARARGS|METH_KEYWORDS, pattern_match__doc__},
-
 static PyObject *
-pattern_match_impl(PatternObject *self, PyObject *pattern, Py_ssize_t pos, Py_ssize_t endpos);
+fix_string_param(PyObject *string, PyObject *string2, const char *oldname)
+{
+    if (string2 != NULL) {
+        if (string != NULL) {
+            PyErr_Format(PyExc_TypeError,
+                         "Argument given by name ('%s') and position (1)",
+                         oldname);
+            return NULL;
+        }
+        if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
+                             "The '%s' keyword parameter name is deprecated.  "
+                             "Use 'string' instead.", oldname) < 0)
+            return NULL;
+        return string2;
+    }
+    if (string == NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "Required argument 'string' (pos 1) not found");
+        return NULL;
+    }
+    return string;
+}
 
 static PyObject *
 pattern_match(PatternObject *self, PyObject *args, PyObject *kwargs)
 {
-    PyObject *return_value = NULL;
-    static char *_keywords[] = {"pattern", "pos", "endpos", NULL};
-    PyObject *pattern;
+    static char *_keywords[] = {"string", "pos", "endpos", "pattern", NULL};
+    PyObject *string = NULL;
     Py_ssize_t pos = 0;
     Py_ssize_t endpos = PY_SSIZE_T_MAX;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-        "O|nn:match", _keywords,
-        &pattern, &pos, &endpos))
-        goto exit;
-    return_value = pattern_match_impl(self, pattern, pos, endpos);
-
-exit:
-    return return_value;
-}
-
-static PyObject *
-pattern_match_impl(PatternObject *self, PyObject *pattern, Py_ssize_t pos, Py_ssize_t endpos)
-/*[clinic end generated code: output=1528eafdb8b025ad input=26f9fd31befe46b9]*/
-{
+    PyObject *pattern = NULL;
     SRE_STATE state;
     Py_ssize_t status;
-    PyObject *string;
-
-    string = state_init(&state, (PatternObject *)self, pattern, pos, endpos);
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+        "|Onn$O:match", _keywords,
+        &string, &pos, &endpos, &pattern))
+        return NULL;
+    string = fix_string_param(string, pattern, "pattern");
+    if (!string)
+        return NULL;
+    string = state_init(&state, (PatternObject *)self, string, pos, endpos);
     if (!string)
         return NULL;
 
@@ -603,12 +593,16 @@
     SRE_STATE state;
     Py_ssize_t status;
 
-    PyObject* string;
+    PyObject *string = NULL, *string2 = NULL;
     Py_ssize_t start = 0;
     Py_ssize_t end = PY_SSIZE_T_MAX;
-    static char* kwlist[] = { "pattern", "pos", "endpos", NULL };
-    if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:fullmatch", kwlist,
-                                     &string, &start, &end))
+    static char* kwlist[] = { "string", "pos", "endpos", "pattern", NULL };
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:fullmatch", kwlist,
+                                     &string, &start, &end, &string2))
+        return NULL;
+
+    string = fix_string_param(string, string2, "pattern");
+    if (!string)
         return NULL;
 
     string = state_init(&state, self, string, start, end);
@@ -637,12 +631,16 @@
     SRE_STATE state;
     Py_ssize_t status;
 
-    PyObject* string;
+    PyObject *string = NULL, *string2 = NULL;
     Py_ssize_t start = 0;
     Py_ssize_t end = PY_SSIZE_T_MAX;
-    static char* kwlist[] = { "pattern", "pos", "endpos", NULL };
-    if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:search", kwlist,
-                                     &string, &start, &end))
+    static char* kwlist[] = { "string", "pos", "endpos", "pattern", NULL };
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:search", kwlist,
+                                     &string, &start, &end, &string2))
+        return NULL;
+
+    string = fix_string_param(string, string2, "pattern");
+    if (!string)
         return NULL;
 
     string = state_init(&state, self, string, start, end);
@@ -718,12 +716,16 @@
     Py_ssize_t status;
     Py_ssize_t i, b, e;
 
-    PyObject* string;
+    PyObject *string = NULL, *string2 = NULL;
     Py_ssize_t start = 0;
     Py_ssize_t end = PY_SSIZE_T_MAX;
-    static char* kwlist[] = { "source", "pos", "endpos", NULL };
-    if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:findall", kwlist,
-                                     &string, &start, &end))
+    static char* kwlist[] = { "string", "pos", "endpos", "source", NULL };
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:findall", kwlist,
+                                     &string, &start, &end, &string2))
+        return NULL;
+
+    string = fix_string_param(string, string2, "source");
+    if (!string)
         return NULL;
 
     string = state_init(&state, self, string, start, end);
@@ -840,11 +842,15 @@
     Py_ssize_t i;
     void* last;
 
-    PyObject* string;
+    PyObject *string = NULL, *string2 = NULL;
     Py_ssize_t maxsplit = 0;
-    static char* kwlist[] = { "source", "maxsplit", NULL };
-    if (!PyArg_ParseTupleAndKeywords(args, kw, "O|n:split", kwlist,
-                                     &string, &maxsplit))
+    static char* kwlist[] = { "string", "maxsplit", "source", NULL };
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "|On$O:split", kwlist,
+                                     &string, &maxsplit, &string2))
+        return NULL;
+
+    string = fix_string_param(string, string2, "source");
+    if (!string)
         return NULL;
 
     string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX);
@@ -1292,6 +1298,10 @@
     return result;
 }
 
+PyDoc_STRVAR(pattern_match_doc,
+"match(string[, pos[, endpos]]) -> match object or None.\n\
+    Matches zero or more characters at the beginning of the string");
+
 PyDoc_STRVAR(pattern_fullmatch_doc,
 "fullmatch(string[, pos[, endpos]]) -> match object or None.\n\
     Matches against all of the string");
@@ -1329,7 +1339,8 @@
 PyDoc_STRVAR(pattern_doc, "Compiled regular expression objects");
 
 static PyMethodDef pattern_methods[] = {
-    PATTERN_MATCH_METHODDEF
+    {"match", (PyCFunction) pattern_match, METH_VARARGS|METH_KEYWORDS,
+        pattern_match_doc},
     {"fullmatch", (PyCFunction) pattern_fullmatch, METH_VARARGS|METH_KEYWORDS,
         pattern_fullmatch_doc},
     {"search", (PyCFunction) pattern_search, METH_VARARGS|METH_KEYWORDS,
@@ -2654,12 +2665,16 @@
 
     ScannerObject* self;
 
-    PyObject* string;
+    PyObject *string = NULL, *string2 = NULL;
     Py_ssize_t start = 0;
     Py_ssize_t end = PY_SSIZE_T_MAX;
-    static char* kwlist[] = { "source", "pos", "endpos", NULL };
-    if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:scanner", kwlist,
-                                     &string, &start, &end))
+    static char* kwlist[] = { "string", "pos", "endpos", "source", NULL };
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:scanner", kwlist,
+                                     &string, &start, &end, &string2))
+        return NULL;
+
+    string = fix_string_param(string, string2, "source");
+    if (!string)
         return NULL;
 
     /* create scanner object */


More information about the Python-bugs-list mailing list