Issue #20283: RE pattern methods now accept the string keyword parameters

as documented.  The pattern and source keyword parameters are left as
deprecated aliases.
This commit is contained in:
Serhiy Storchaka 2014-03-06 11:36:15 +02:00
commit a537eb45fd
3 changed files with 101 additions and 64 deletions

View File

@ -1205,6 +1205,24 @@ class ReTests(unittest.TestCase):
self.assertEqual(out.getvalue().splitlines(), self.assertEqual(out.getvalue().splitlines(),
['literal 102 ', 'literal 111 ', 'literal 111 ']) ['literal 102 ', 'literal 111 ', 'literal 111 '])
def test_keyword_parameters(self):
# Issue #20283: Accepting the string keyword parameter.
pat = re.compile(r'(ab)')
self.assertEqual(
pat.match(string='abracadabra', pos=7, endpos=10).span(), (7, 9))
self.assertEqual(
pat.fullmatch(string='abracadabra', pos=7, endpos=9).span(), (7, 9))
self.assertEqual(
pat.search(string='abracadabra', pos=3, endpos=10).span(), (7, 9))
self.assertEqual(
pat.findall(string='abracadabra', pos=3, endpos=10), ['ab'])
self.assertEqual(
pat.split(string='abracadabra', maxsplit=1),
['', 'ab', 'racadabra'])
self.assertEqual(
pat.scanner(string='abracadabra', pos=3, endpos=10).search().span(),
(7, 9))
class PatternReprTests(unittest.TestCase): class PatternReprTests(unittest.TestCase):
def check(self, pattern, expected): def check(self, pattern, expected):

View File

@ -20,6 +20,10 @@ Core and Builtins
Library Library
------- -------
- Issue #20283: RE pattern methods now accept the string keyword parameters
as documented. The pattern and source keyword parameters are left as
deprecated aliases.
- Issue #20839: Don't trigger a DeprecationWarning in the still supported - Issue #20839: Don't trigger a DeprecationWarning in the still supported
pkgutil.get_loader() API when __loader__ isn't set on a module (nor pkgutil.get_loader() API when __loader__ isn't set on a module (nor
when pkgutil.find_loader() is called directly). when pkgutil.find_loader() is called directly).

View File

@ -526,59 +526,49 @@ sre_search(SRE_STATE* state, SRE_CODE* pattern)
return sre_ucs4_search(state, pattern); 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 * 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 * static PyObject *
pattern_match(PatternObject *self, PyObject *args, PyObject *kwargs) pattern_match(PatternObject *self, PyObject *args, PyObject *kwargs)
{ {
PyObject *return_value = NULL; static char *_keywords[] = {"string", "pos", "endpos", "pattern", NULL};
static char *_keywords[] = {"pattern", "pos", "endpos", NULL}; PyObject *string = NULL;
PyObject *pattern;
Py_ssize_t pos = 0; Py_ssize_t pos = 0;
Py_ssize_t endpos = PY_SSIZE_T_MAX; Py_ssize_t endpos = PY_SSIZE_T_MAX;
PyObject *pattern = NULL;
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]*/
{
SRE_STATE state; SRE_STATE state;
Py_ssize_t status; 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) if (!string)
return NULL; return NULL;
@ -603,12 +593,16 @@ pattern_fullmatch(PatternObject* self, PyObject* args, PyObject* kw)
SRE_STATE state; SRE_STATE state;
Py_ssize_t status; Py_ssize_t status;
PyObject* string; PyObject *string = NULL, *string2 = NULL;
Py_ssize_t start = 0; Py_ssize_t start = 0;
Py_ssize_t end = PY_SSIZE_T_MAX; Py_ssize_t end = PY_SSIZE_T_MAX;
static char* kwlist[] = { "pattern", "pos", "endpos", NULL }; static char* kwlist[] = { "string", "pos", "endpos", "pattern", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:fullmatch", kwlist, if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:fullmatch", kwlist,
&string, &start, &end)) &string, &start, &end, &string2))
return NULL;
string = fix_string_param(string, string2, "pattern");
if (!string)
return NULL; return NULL;
string = state_init(&state, self, string, start, end); string = state_init(&state, self, string, start, end);
@ -637,12 +631,16 @@ pattern_search(PatternObject* self, PyObject* args, PyObject* kw)
SRE_STATE state; SRE_STATE state;
Py_ssize_t status; Py_ssize_t status;
PyObject* string; PyObject *string = NULL, *string2 = NULL;
Py_ssize_t start = 0; Py_ssize_t start = 0;
Py_ssize_t end = PY_SSIZE_T_MAX; Py_ssize_t end = PY_SSIZE_T_MAX;
static char* kwlist[] = { "pattern", "pos", "endpos", NULL }; static char* kwlist[] = { "string", "pos", "endpos", "pattern", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:search", kwlist, if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:search", kwlist,
&string, &start, &end)) &string, &start, &end, &string2))
return NULL;
string = fix_string_param(string, string2, "pattern");
if (!string)
return NULL; return NULL;
string = state_init(&state, self, string, start, end); string = state_init(&state, self, string, start, end);
@ -718,12 +716,16 @@ pattern_findall(PatternObject* self, PyObject* args, PyObject* kw)
Py_ssize_t status; Py_ssize_t status;
Py_ssize_t i, b, e; Py_ssize_t i, b, e;
PyObject* string; PyObject *string = NULL, *string2 = NULL;
Py_ssize_t start = 0; Py_ssize_t start = 0;
Py_ssize_t end = PY_SSIZE_T_MAX; Py_ssize_t end = PY_SSIZE_T_MAX;
static char* kwlist[] = { "source", "pos", "endpos", NULL }; static char* kwlist[] = { "string", "pos", "endpos", "source", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:findall", kwlist, if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:findall", kwlist,
&string, &start, &end)) &string, &start, &end, &string2))
return NULL;
string = fix_string_param(string, string2, "source");
if (!string)
return NULL; return NULL;
string = state_init(&state, self, string, start, end); string = state_init(&state, self, string, start, end);
@ -840,11 +842,15 @@ pattern_split(PatternObject* self, PyObject* args, PyObject* kw)
Py_ssize_t i; Py_ssize_t i;
void* last; void* last;
PyObject* string; PyObject *string = NULL, *string2 = NULL;
Py_ssize_t maxsplit = 0; Py_ssize_t maxsplit = 0;
static char* kwlist[] = { "source", "maxsplit", NULL }; static char* kwlist[] = { "string", "maxsplit", "source", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|n:split", kwlist, if (!PyArg_ParseTupleAndKeywords(args, kw, "|On$O:split", kwlist,
&string, &maxsplit)) &string, &maxsplit, &string2))
return NULL;
string = fix_string_param(string, string2, "source");
if (!string)
return NULL; return NULL;
string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX); string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX);
@ -1292,6 +1298,10 @@ done:
return result; 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, PyDoc_STRVAR(pattern_fullmatch_doc,
"fullmatch(string[, pos[, endpos]]) -> match object or None.\n\ "fullmatch(string[, pos[, endpos]]) -> match object or None.\n\
Matches against all of the string"); Matches against all of the string");
@ -1329,7 +1339,8 @@ PyDoc_STRVAR(pattern_subn_doc,
PyDoc_STRVAR(pattern_doc, "Compiled regular expression objects"); PyDoc_STRVAR(pattern_doc, "Compiled regular expression objects");
static PyMethodDef pattern_methods[] = { 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, {"fullmatch", (PyCFunction) pattern_fullmatch, METH_VARARGS|METH_KEYWORDS,
pattern_fullmatch_doc}, pattern_fullmatch_doc},
{"search", (PyCFunction) pattern_search, METH_VARARGS|METH_KEYWORDS, {"search", (PyCFunction) pattern_search, METH_VARARGS|METH_KEYWORDS,
@ -2654,12 +2665,16 @@ pattern_scanner(PatternObject* pattern, PyObject* args, PyObject* kw)
ScannerObject* self; ScannerObject* self;
PyObject* string; PyObject *string = NULL, *string2 = NULL;
Py_ssize_t start = 0; Py_ssize_t start = 0;
Py_ssize_t end = PY_SSIZE_T_MAX; Py_ssize_t end = PY_SSIZE_T_MAX;
static char* kwlist[] = { "source", "pos", "endpos", NULL }; static char* kwlist[] = { "string", "pos", "endpos", "source", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:scanner", kwlist, if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:scanner", kwlist,
&string, &start, &end)) &string, &start, &end, &string2))
return NULL;
string = fix_string_param(string, string2, "source");
if (!string)
return NULL; return NULL;
/* create scanner object */ /* create scanner object */