Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ccdf352

Browse files
Issue #20283: RE pattern methods now accept the string keyword parameters
as documented. The pattern and source keyword parameters are left as deprecated aliases.
1 parent 25dded0 commit ccdf352

3 files changed

Lines changed: 84 additions & 20 deletions

File tree

Lib/test/test_re.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,22 @@ def test_debug_flag(self):
10761076
self.assertEqual(out.getvalue().splitlines(),
10771077
['literal 102 ', 'literal 111 ', 'literal 111 '])
10781078

1079+
def test_keyword_parameters(self):
1080+
# Issue #20283: Accepting the string keyword parameter.
1081+
pat = re.compile(r'(ab)')
1082+
self.assertEqual(
1083+
pat.match(string='abracadabra', pos=7, endpos=10).span(), (7, 9))
1084+
self.assertEqual(
1085+
pat.search(string='abracadabra', pos=3, endpos=10).span(), (7, 9))
1086+
self.assertEqual(
1087+
pat.findall(string='abracadabra', pos=3, endpos=10), ['ab'])
1088+
self.assertEqual(
1089+
pat.split(string='abracadabra', maxsplit=1),
1090+
['', 'ab', 'racadabra'])
1091+
self.assertEqual(
1092+
pat.scanner(string='abracadabra', pos=3, endpos=10).search().span(),
1093+
(7, 9))
1094+
10791095

10801096
def run_re_tests():
10811097
from test.re_tests import tests, SUCCEED, FAIL, SYNTAX_ERROR

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ Core and Builtins
2222
Library
2323
-------
2424

25+
- Issue #20283: RE pattern methods now accept the string keyword parameters
26+
as documented. The pattern and source keyword parameters are left as
27+
deprecated aliases.
28+
2529
- Issue #20778: Fix modulefinder to work with bytecode-only modules.
2630

2731
- Issue #20791: copy.copy() now doesn't make a copy when the input is

Modules/_sre.c

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1876,18 +1876,46 @@ pattern_dealloc(PatternObject* self)
18761876
PyObject_DEL(self);
18771877
}
18781878

1879+
static PyObject*
1880+
fix_string_param(PyObject *string, PyObject *string2, const char *oldname)
1881+
{
1882+
if (string2 != NULL) {
1883+
if (string != NULL) {
1884+
PyErr_Format(PyExc_TypeError,
1885+
"Argument given by name ('%s') and position (1)",
1886+
oldname);
1887+
return NULL;
1888+
}
1889+
if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1890+
"The '%s' keyword parameter name is deprecated. "
1891+
"Use 'string' instead.", oldname) < 0)
1892+
return NULL;
1893+
return string2;
1894+
}
1895+
if (string == NULL) {
1896+
PyErr_SetString(PyExc_TypeError,
1897+
"Required argument 'string' (pos 1) not found");
1898+
return NULL;
1899+
}
1900+
return string;
1901+
}
1902+
18791903
static PyObject*
18801904
pattern_match(PatternObject* self, PyObject* args, PyObject* kw)
18811905
{
18821906
SRE_STATE state;
18831907
int status;
18841908

1885-
PyObject* string;
1909+
PyObject *string = NULL, *string2 = NULL;
18861910
Py_ssize_t start = 0;
18871911
Py_ssize_t end = PY_SSIZE_T_MAX;
1888-
static char* kwlist[] = { "pattern", "pos", "endpos", NULL };
1889-
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:match", kwlist,
1890-
&string, &start, &end))
1912+
static char* kwlist[] = { "string", "pos", "endpos", "pattern", NULL };
1913+
if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:match", kwlist,
1914+
&string, &start, &end, &string2))
1915+
return NULL;
1916+
1917+
string = fix_string_param(string, string2, "pattern");
1918+
if (!string)
18911919
return NULL;
18921920

18931921
string = state_init(&state, self, string, start, end);
@@ -1919,12 +1947,16 @@ pattern_search(PatternObject* self, PyObject* args, PyObject* kw)
19191947
SRE_STATE state;
19201948
int status;
19211949

1922-
PyObject* string;
1950+
PyObject *string = NULL, *string2 = NULL;
19231951
Py_ssize_t start = 0;
19241952
Py_ssize_t end = PY_SSIZE_T_MAX;
1925-
static char* kwlist[] = { "pattern", "pos", "endpos", NULL };
1926-
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:search", kwlist,
1927-
&string, &start, &end))
1953+
static char* kwlist[] = { "string", "pos", "endpos", "pattern", NULL };
1954+
if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:search", kwlist,
1955+
&string, &start, &end, &string2))
1956+
return NULL;
1957+
1958+
string = fix_string_param(string, string2, "pattern");
1959+
if (!string)
19281960
return NULL;
19291961

19301962
string = state_init(&state, self, string, start, end);
@@ -2052,12 +2084,16 @@ pattern_findall(PatternObject* self, PyObject* args, PyObject* kw)
20522084
int status;
20532085
Py_ssize_t i, b, e;
20542086

2055-
PyObject* string;
2087+
PyObject *string = NULL, *string2 = NULL;
20562088
Py_ssize_t start = 0;
20572089
Py_ssize_t end = PY_SSIZE_T_MAX;
2058-
static char* kwlist[] = { "source", "pos", "endpos", NULL };
2059-
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:findall", kwlist,
2060-
&string, &start, &end))
2090+
static char* kwlist[] = { "string", "pos", "endpos", "source", NULL };
2091+
if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:findall", kwlist,
2092+
&string, &start, &end, &string2))
2093+
return NULL;
2094+
2095+
string = fix_string_param(string, string2, "source");
2096+
if (!string)
20612097
return NULL;
20622098

20632099
string = state_init(&state, self, string, start, end);
@@ -2180,11 +2216,15 @@ pattern_split(PatternObject* self, PyObject* args, PyObject* kw)
21802216
Py_ssize_t i;
21812217
void* last;
21822218

2183-
PyObject* string;
2219+
PyObject *string = NULL, *string2 = NULL;
21842220
Py_ssize_t maxsplit = 0;
2185-
static char* kwlist[] = { "source", "maxsplit", NULL };
2186-
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|n:split", kwlist,
2187-
&string, &maxsplit))
2221+
static char* kwlist[] = { "string", "maxsplit", "source", NULL };
2222+
if (!PyArg_ParseTupleAndKeywords(args, kw, "|On$O:split", kwlist,
2223+
&string, &maxsplit, &string2))
2224+
return NULL;
2225+
2226+
string = fix_string_param(string, string2, "source");
2227+
if (!string)
21882228
return NULL;
21892229

21902230
string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX);
@@ -3882,12 +3922,16 @@ pattern_scanner(PatternObject* pattern, PyObject* args, PyObject* kw)
38823922

38833923
ScannerObject* self;
38843924

3885-
PyObject* string;
3925+
PyObject *string = NULL, *string2 = NULL;
38863926
Py_ssize_t start = 0;
38873927
Py_ssize_t end = PY_SSIZE_T_MAX;
3888-
static char* kwlist[] = { "source", "pos", "endpos", NULL };
3889-
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:scanner", kwlist,
3890-
&string, &start, &end))
3928+
static char* kwlist[] = { "string", "pos", "endpos", "source", NULL };
3929+
if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:scanner", kwlist,
3930+
&string, &start, &end, &string2))
3931+
return NULL;
3932+
3933+
string = fix_string_param(string, string2, "source");
3934+
if (!string)
38913935
return NULL;
38923936

38933937
/* create scanner object */

0 commit comments

Comments
 (0)