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:
commit
a537eb45fd
|
@ -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):
|
||||||
|
|
|
@ -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).
|
||||||
|
|
143
Modules/_sre.c
143
Modules/_sre.c
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue