diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 1bfbcb853c4ed1..c1d02cfaf0dcb6 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -2197,6 +2197,10 @@ def test_overlap_table(self): self.assertEqual(f("ababba"), [0, 0, 1, 2, 0, 1]) self.assertEqual(f("abcabdac"), [0, 0, 0, 1, 2, 0, 1, 0]) + def test_signedness(self): + self.assertGreaterEqual(sre_compile.MAXREPEAT, 0) + self.assertGreaterEqual(sre_compile.MAXGROUPS, 0) + class ExternalTests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2020-11-19-09-59-07.bpo-1635741.7cMypH.rst b/Misc/NEWS.d/next/Library/2020-11-19-09-59-07.bpo-1635741.7cMypH.rst new file mode 100644 index 00000000000000..1e7d412680a1b2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-11-19-09-59-07.bpo-1635741.7cMypH.rst @@ -0,0 +1,2 @@ +Convert _sre module types to heap types (PEP 384). Patch by Erlend E. +Aasland. diff --git a/Modules/_sre.c b/Modules/_sre.c index fbabeb7c9f3054..0a5ca60097af36 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -248,22 +248,36 @@ data_stack_grow(SRE_STATE* state, Py_ssize_t size) /* -------------------------------------------------------------------- */ /* factories and destructors */ -/* see sre.h for object declarations */ -static PyObject*pattern_new_match(PatternObject*, SRE_STATE*, Py_ssize_t); -static PyObject *pattern_scanner(PatternObject *, PyObject *, Py_ssize_t, Py_ssize_t); +/* module state */ +typedef struct { + PyTypeObject *Pattern_Type; + PyTypeObject *Match_Type; + PyTypeObject *Scanner_Type; +} _sremodulestate; + +static _sremodulestate * +get_sre_module_state(PyObject *m) +{ + _sremodulestate *state = (_sremodulestate *)PyModule_GetState(m); + assert(state); + return state; +} +static struct PyModuleDef sremodule; +#define get_sre_module_state_by_class(cls) \ + (get_sre_module_state(PyType_GetModule(cls))) + +/* see sre.h for object declarations */ +static PyObject*pattern_new_match(_sremodulestate *, PatternObject*, SRE_STATE*, Py_ssize_t); +static PyObject *pattern_scanner(_sremodulestate *, PatternObject *, PyObject *, Py_ssize_t, Py_ssize_t); /*[clinic input] module _sre -class _sre.SRE_Pattern "PatternObject *" "&Pattern_Type" -class _sre.SRE_Match "MatchObject *" "&Match_Type" -class _sre.SRE_Scanner "ScannerObject *" "&Scanner_Type" +class _sre.SRE_Pattern "PatternObject *" "get_sre_module_state_by_class(tp)->Pattern_Type" +class _sre.SRE_Match "MatchObject *" "get_sre_module_state_by_class(tp)->Match_Type" +class _sre.SRE_Scanner "ScannerObject *" "get_sre_module_state_by_class(tp)->Scanner_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b0230ec19a0deac8]*/ - -static PyTypeObject Pattern_Type; -static PyTypeObject Match_Type; -static PyTypeObject Scanner_Type; +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=fe2966e32b66a231]*/ /*[clinic input] _sre.getcodesize -> int @@ -550,12 +564,15 @@ pattern_error(Py_ssize_t status) static void pattern_dealloc(PatternObject* self) { + PyTypeObject *tp = Py_TYPE(self); + if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) self); Py_XDECREF(self->pattern); Py_XDECREF(self->groupindex); Py_XDECREF(self->indexgroup); PyObject_DEL(self); + Py_DECREF(tp); } LOCAL(Py_ssize_t) @@ -583,6 +600,8 @@ sre_search(SRE_STATE* state, SRE_CODE* pattern) /*[clinic input] _sre.SRE_Pattern.match + cls: defining_class + / string: object pos: Py_ssize_t = 0 endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize @@ -591,10 +610,12 @@ Matches zero or more characters at the beginning of the string. [clinic start generated code]*/ static PyObject * -_sre_SRE_Pattern_match_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos) -/*[clinic end generated code: output=ea2d838888510661 input=a2ba191647abebe5]*/ +_sre_SRE_Pattern_match_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos) +/*[clinic end generated code: output=ec6208ea58a0cca0 input=4bdb9c3e564d13ac]*/ { + _sremodulestate *module_state = get_sre_module_state_by_class(cls); SRE_STATE state; Py_ssize_t status; PyObject *match; @@ -614,7 +635,7 @@ _sre_SRE_Pattern_match_impl(PatternObject *self, PyObject *string, return NULL; } - match = pattern_new_match(self, &state, status); + match = pattern_new_match(module_state, self, &state, status); state_fini(&state); return match; } @@ -622,6 +643,8 @@ _sre_SRE_Pattern_match_impl(PatternObject *self, PyObject *string, /*[clinic input] _sre.SRE_Pattern.fullmatch + cls: defining_class + / string: object pos: Py_ssize_t = 0 endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize @@ -630,10 +653,12 @@ Matches against all of the string. [clinic start generated code]*/ static PyObject * -_sre_SRE_Pattern_fullmatch_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos) -/*[clinic end generated code: output=5833c47782a35f4a input=d9fb03a7625b5828]*/ +_sre_SRE_Pattern_fullmatch_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos) +/*[clinic end generated code: output=625b75b027ef94da input=50981172ab0fcfdd]*/ { + _sremodulestate *module_state = get_sre_module_state_by_class(cls); SRE_STATE state; Py_ssize_t status; PyObject *match; @@ -654,7 +679,7 @@ _sre_SRE_Pattern_fullmatch_impl(PatternObject *self, PyObject *string, return NULL; } - match = pattern_new_match(self, &state, status); + match = pattern_new_match(module_state, self, &state, status); state_fini(&state); return match; } @@ -662,6 +687,8 @@ _sre_SRE_Pattern_fullmatch_impl(PatternObject *self, PyObject *string, /*[clinic input] _sre.SRE_Pattern.search + cls: defining_class + / string: object pos: Py_ssize_t = 0 endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize @@ -672,10 +699,12 @@ Return None if no position in the string matches. [clinic start generated code]*/ static PyObject * -_sre_SRE_Pattern_search_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos) -/*[clinic end generated code: output=25f302a644e951e8 input=4ae5cb7dc38fed1b]*/ +_sre_SRE_Pattern_search_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos) +/*[clinic end generated code: output=bd7f2d9d583e1463 input=afa9afb66a74a4b3]*/ { + _sremodulestate *module_state = get_sre_module_state_by_class(cls); SRE_STATE state; Py_ssize_t status; PyObject *match; @@ -694,7 +723,7 @@ _sre_SRE_Pattern_search_impl(PatternObject *self, PyObject *string, return NULL; } - match = pattern_new_match(self, &state, status); + match = pattern_new_match(module_state, self, &state, status); state_fini(&state); return match; } @@ -826,6 +855,8 @@ _sre_SRE_Pattern_findall_impl(PatternObject *self, PyObject *string, /*[clinic input] _sre.SRE_Pattern.finditer + cls: defining_class + / string: object pos: Py_ssize_t = 0 endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize @@ -836,15 +867,17 @@ For each match, the iterator returns a match object. [clinic start generated code]*/ static PyObject * -_sre_SRE_Pattern_finditer_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos) -/*[clinic end generated code: output=0bbb1a0aeb38bb14 input=612aab69e9fe08e4]*/ +_sre_SRE_Pattern_finditer_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos) +/*[clinic end generated code: output=1791dbf3618ade56 input=812e332a4848cbaf]*/ { + _sremodulestate *module_state = get_sre_module_state_by_class(cls); PyObject* scanner; PyObject* search; PyObject* iterator; - scanner = pattern_scanner(self, string, pos, endpos); + scanner = pattern_scanner(module_state, self, string, pos, endpos); if (!scanner) return NULL; @@ -862,6 +895,8 @@ _sre_SRE_Pattern_finditer_impl(PatternObject *self, PyObject *string, /*[clinic input] _sre.SRE_Pattern.scanner + cls: defining_class + / string: object pos: Py_ssize_t = 0 endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize @@ -869,11 +904,14 @@ _sre.SRE_Pattern.scanner [clinic start generated code]*/ static PyObject * -_sre_SRE_Pattern_scanner_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos) -/*[clinic end generated code: output=54ea548aed33890b input=3aacdbde77a3a637]*/ +_sre_SRE_Pattern_scanner_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos) +/*[clinic end generated code: output=f70cd506112f1bd9 input=2e487e5151bcee4c]*/ { - return pattern_scanner(self, string, pos, endpos); + _sremodulestate *module_state = get_sre_module_state_by_class(cls); + + return pattern_scanner(module_state, self, string, pos, endpos); } /*[clinic input] @@ -980,8 +1018,12 @@ _sre_SRE_Pattern_split_impl(PatternObject *self, PyObject *string, } static PyObject* -pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string, - Py_ssize_t count, Py_ssize_t subn) +pattern_subx(_sremodulestate* module_state, + PatternObject* self, + PyObject* ptemplate, + PyObject* string, + Py_ssize_t count, + Py_ssize_t subn) { SRE_STATE state; PyObject* list; @@ -1083,7 +1125,7 @@ pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string, if (filter_is_callable) { /* pass match object through filter */ - match = pattern_new_match(self, &state, 1); + match = pattern_new_match(module_state, self, &state, 1); if (!match) goto error; item = PyObject_CallOneArg(filter, match); @@ -1163,6 +1205,8 @@ pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string, /*[clinic input] _sre.SRE_Pattern.sub + cls: defining_class + / repl: object string: object count: Py_ssize_t = 0 @@ -1171,16 +1215,20 @@ Return the string obtained by replacing the leftmost non-overlapping occurrences [clinic start generated code]*/ static PyObject * -_sre_SRE_Pattern_sub_impl(PatternObject *self, PyObject *repl, - PyObject *string, Py_ssize_t count) -/*[clinic end generated code: output=1dbf2ec3479cba00 input=c53d70be0b3caf86]*/ +_sre_SRE_Pattern_sub_impl(PatternObject *self, PyTypeObject *cls, + PyObject *repl, PyObject *string, Py_ssize_t count) +/*[clinic end generated code: output=4be141ab04bca60d input=d8d1d4ac2311a07c]*/ { - return pattern_subx(self, repl, string, count, 0); + _sremodulestate *module_state = get_sre_module_state_by_class(cls); + + return pattern_subx(module_state, self, repl, string, count, 0); } /*[clinic input] _sre.SRE_Pattern.subn + cls: defining_class + / repl: object string: object count: Py_ssize_t = 0 @@ -1189,11 +1237,14 @@ Return the tuple (new_string, number_of_subs_made) found by replacing the leftmo [clinic start generated code]*/ static PyObject * -_sre_SRE_Pattern_subn_impl(PatternObject *self, PyObject *repl, - PyObject *string, Py_ssize_t count) -/*[clinic end generated code: output=0d9522cd529e9728 input=e7342d7ce6083577]*/ +_sre_SRE_Pattern_subn_impl(PatternObject *self, PyTypeObject *cls, + PyObject *repl, PyObject *string, + Py_ssize_t count) +/*[clinic end generated code: output=da02fd85258b1e1f input=8b78a65b8302e58d]*/ { - return pattern_subx(self, repl, string, count, 1); + _sremodulestate *module_state = get_sre_module_state_by_class(cls); + + return pattern_subx(module_state, self, repl, string, count, 1); } /*[clinic input] @@ -1338,12 +1389,13 @@ _sre_compile_impl(PyObject *module, PyObject *pattern, int flags, { /* "compile" pattern descriptor to pattern object */ + _sremodulestate *module_state = get_sre_module_state(module); PatternObject* self; Py_ssize_t i, n; n = PyList_GET_SIZE(code); /* coverity[ampersand_in_size] */ - self = PyObject_NewVar(PatternObject, &Pattern_Type, n); + self = PyObject_NewVar(PatternObject, module_state->Pattern_Type, n); if (!self) return NULL; self->weakreflist = NULL; @@ -1887,10 +1939,13 @@ _validate(PatternObject *self) static void match_dealloc(MatchObject* self) { + PyTypeObject *tp = Py_TYPE(self); + Py_XDECREF(self->regs); Py_XDECREF(self->string); Py_DECREF(self->pattern); PyObject_DEL(self); + Py_DECREF(tp); } static PyObject* @@ -2319,7 +2374,10 @@ match_repr(MatchObject *self) static PyObject* -pattern_new_match(PatternObject* pattern, SRE_STATE* state, Py_ssize_t status) +pattern_new_match(_sremodulestate* module_state, + PatternObject* pattern, + SRE_STATE* state, + Py_ssize_t status) { /* create match object (from state object) */ @@ -2332,7 +2390,8 @@ pattern_new_match(PatternObject* pattern, SRE_STATE* state, Py_ssize_t status) /* create match object (with room for extra group marks) */ /* coverity[ampersand_in_size] */ - match = PyObject_NewVar(MatchObject, &Match_Type, + match = PyObject_NewVar(MatchObject, + module_state->Match_Type, 2*(pattern->groups+1)); if (!match) return NULL; @@ -2387,20 +2446,27 @@ pattern_new_match(PatternObject* pattern, SRE_STATE* state, Py_ssize_t status) static void scanner_dealloc(ScannerObject* self) { + PyTypeObject *tp = Py_TYPE(self); + state_fini(&self->state); Py_XDECREF(self->pattern); PyObject_DEL(self); + Py_DECREF(tp); } /*[clinic input] _sre.SRE_Scanner.match + cls: defining_class + / + [clinic start generated code]*/ static PyObject * -_sre_SRE_Scanner_match_impl(ScannerObject *self) -/*[clinic end generated code: output=936b30c63d4b81eb input=881a0154f8c13d9a]*/ +_sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=6e22c149dc0f0325 input=b5146e1f30278cb7]*/ { + _sremodulestate *module_state = get_sre_module_state_by_class(cls); SRE_STATE* state = &self->state; PyObject* match; Py_ssize_t status; @@ -2416,8 +2482,8 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self) if (PyErr_Occurred()) return NULL; - match = pattern_new_match((PatternObject*) self->pattern, - state, status); + match = pattern_new_match(module_state, (PatternObject*) self->pattern, + state, status); if (status == 0) state->start = NULL; @@ -2433,12 +2499,16 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self) /*[clinic input] _sre.SRE_Scanner.search + cls: defining_class + / + [clinic start generated code]*/ static PyObject * -_sre_SRE_Scanner_search_impl(ScannerObject *self) -/*[clinic end generated code: output=7dc211986088f025 input=161223ee92ef9270]*/ +_sre_SRE_Scanner_search_impl(ScannerObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=23e8fc78013f9161 input=056c2d37171d0bf2]*/ { + _sremodulestate *module_state = get_sre_module_state_by_class(cls); SRE_STATE* state = &self->state; PyObject* match; Py_ssize_t status; @@ -2454,8 +2524,8 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self) if (PyErr_Occurred()) return NULL; - match = pattern_new_match((PatternObject*) self->pattern, - state, status); + match = pattern_new_match(module_state, (PatternObject*) self->pattern, + state, status); if (status == 0) state->start = NULL; @@ -2468,12 +2538,16 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self) } static PyObject * -pattern_scanner(PatternObject *self, PyObject *string, Py_ssize_t pos, Py_ssize_t endpos) +pattern_scanner(_sremodulestate *module_state, + PatternObject *self, + PyObject *string, + Py_ssize_t pos, + Py_ssize_t endpos) { ScannerObject* scanner; /* create scanner object */ - scanner = PyObject_New(ScannerObject, &Scanner_Type); + scanner = PyObject_New(ScannerObject, module_state->Scanner_Type); if (!scanner) return NULL; scanner->pattern = NULL; @@ -2516,6 +2590,8 @@ pattern_hash(PatternObject *self) static PyObject* pattern_richcompare(PyObject *lefto, PyObject *righto, int op) { + PyTypeObject *tp = Py_TYPE(lefto); + _sremodulestate *module_state = get_sre_module_state_by_class(tp); PatternObject *left, *right; int cmp; @@ -2523,7 +2599,8 @@ pattern_richcompare(PyObject *lefto, PyObject *righto, int op) Py_RETURN_NOTIMPLEMENTED; } - if (!Py_IS_TYPE(lefto, &Pattern_Type) || !Py_IS_TYPE(righto, &Pattern_Type)) { + if (!Py_IS_TYPE(righto, module_state->Pattern_Type)) + { Py_RETURN_NOTIMPLEMENTED; } @@ -2592,47 +2669,28 @@ static PyMemberDef pattern_members[] = { "The regex matching flags."}, {"groups", T_PYSSIZET, PAT_OFF(groups), READONLY, "The number of capturing groups in the pattern."}, + {"__weaklistoffset__", T_PYSSIZET, offsetof(PatternObject, weakreflist), READONLY}, {NULL} /* Sentinel */ }; -static PyTypeObject Pattern_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "re.Pattern", - sizeof(PatternObject), sizeof(SRE_CODE), - (destructor)pattern_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)pattern_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)pattern_hash, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - pattern_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - pattern_richcompare, /* tp_richcompare */ - offsetof(PatternObject, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - pattern_methods, /* tp_methods */ - pattern_members, /* tp_members */ - pattern_getset, /* tp_getset */ +static PyType_Slot pattern_slots[] = { + {Py_tp_dealloc, (destructor)pattern_dealloc}, + {Py_tp_repr, (reprfunc)pattern_repr}, + {Py_tp_hash, (hashfunc)pattern_hash}, + {Py_tp_doc, (void *)pattern_doc}, + {Py_tp_richcompare, pattern_richcompare}, + {Py_tp_methods, pattern_methods}, + {Py_tp_members, pattern_members}, + {Py_tp_getset, pattern_getset}, + {0, NULL}, }; -/* Match objects do not support length or assignment, but do support - __getitem__. */ -static PyMappingMethods match_as_mapping = { - NULL, - (binaryfunc)match_getitem, - NULL +static PyType_Spec pattern_spec = { + .name = "re.Pattern", + .basicsize = sizeof(PatternObject), + .itemsize = sizeof(SRE_CODE), + .flags = Py_TPFLAGS_DEFAULT, + .slots = pattern_slots, }; static PyMethodDef match_methods[] = { @@ -2674,37 +2732,30 @@ static PyMemberDef match_members[] = { /* FIXME: implement setattr("string", None) as a special case (to detach the associated string, if any */ +static PyType_Slot match_slots[] = { + {Py_tp_dealloc, match_dealloc}, + {Py_tp_repr, match_repr}, + {Py_tp_doc, (void *)match_doc}, + {Py_tp_methods, match_methods}, + {Py_tp_members, match_members}, + {Py_tp_getset, match_getset}, + + /* As mapping. + * + * Match objects do not support length or assignment, but do support + * __getitem__. + */ + {Py_mp_subscript, match_getitem}, + + {0, NULL}, +}; -static PyTypeObject Match_Type = { - PyVarObject_HEAD_INIT(NULL,0) - "re.Match", - sizeof(MatchObject), sizeof(Py_ssize_t), - (destructor)match_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)match_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - &match_as_mapping, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - match_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - match_methods, /* tp_methods */ - match_members, /* tp_members */ - match_getset, /* tp_getset */ +static PyType_Spec match_spec = { + .name = "re.Match", + .basicsize = sizeof(MatchObject), + .itemsize = sizeof(Py_ssize_t), + .flags = Py_TPFLAGS_DEFAULT, + .slots = match_slots, }; static PyMethodDef scanner_methods[] = { @@ -2719,36 +2770,18 @@ static PyMemberDef scanner_members[] = { {NULL} /* Sentinel */ }; -static PyTypeObject Scanner_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_" SRE_MODULE ".SRE_Scanner", - sizeof(ScannerObject), 0, - (destructor)scanner_dealloc,/* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - scanner_methods, /* tp_methods */ - scanner_members, /* tp_members */ - 0, /* tp_getset */ +static PyType_Slot scanner_slots[] = { + {Py_tp_dealloc, scanner_dealloc}, + {Py_tp_methods, scanner_methods}, + {Py_tp_members, scanner_members}, + {0, NULL}, +}; + +static PyType_Spec scanner_spec = { + .name = "_" SRE_MODULE ".SRE_Scanner", + .basicsize = sizeof(ScannerObject), + .flags = Py_TPFLAGS_DEFAULT, + .slots = scanner_slots, }; static PyMethodDef _functions[] = { @@ -2761,64 +2794,108 @@ static PyMethodDef _functions[] = { {NULL, NULL} }; -static struct PyModuleDef sremodule = { - PyModuleDef_HEAD_INIT, - "_" SRE_MODULE, - NULL, - -1, - _functions, - NULL, - NULL, - NULL, - NULL -}; +static int +sre_traverse(PyObject *module, visitproc visit, void *arg) +{ + _sremodulestate *state = get_sre_module_state(module); + + Py_VISIT(state->Pattern_Type); + Py_VISIT(state->Match_Type); + Py_VISIT(state->Scanner_Type); + + return 0; +} -PyMODINIT_FUNC PyInit__sre(void) +static int +sre_clear(PyObject *module) { - PyObject* m; - PyObject* d; - PyObject* x; + _sremodulestate *state = get_sre_module_state(module); - /* Patch object types */ - if (PyType_Ready(&Pattern_Type) || PyType_Ready(&Match_Type) || - PyType_Ready(&Scanner_Type)) - return NULL; + Py_CLEAR(state->Pattern_Type); + Py_CLEAR(state->Match_Type); + Py_CLEAR(state->Scanner_Type); - m = PyModule_Create(&sremodule); - if (m == NULL) - return NULL; - d = PyModule_GetDict(m); + return 0; +} - x = PyLong_FromLong(SRE_MAGIC); - if (x) { - PyDict_SetItemString(d, "MAGIC", x); - Py_DECREF(x); - } +static void +sre_free(void *module) +{ + sre_clear((PyObject *)module); +} + +#define CREATE_TYPE(m, type, spec) \ +do { \ + type = (PyTypeObject *)PyType_FromModuleAndSpec(m, spec, NULL); \ + if (type == NULL) { \ + goto error; \ + } \ +} while (0) + +#define ADD_ULONG_CONSTANT(module, name, value) \ + do { \ + PyObject *o = PyLong_FromUnsignedLong(value); \ + if (!o) \ + goto error; \ + int res = PyModule_AddObjectRef(module, name, o); \ + Py_DECREF(o); \ + if (res < 0) { \ + goto error; \ + } \ +} while (0) - x = PyLong_FromLong(sizeof(SRE_CODE)); - if (x) { - PyDict_SetItemString(d, "CODESIZE", x); - Py_DECREF(x); - } +static int +sre_exec(PyObject *m) +{ + _sremodulestate *state; + + /* Create heap types */ + state = get_sre_module_state(m); + CREATE_TYPE(m, state->Pattern_Type, &pattern_spec); + CREATE_TYPE(m, state->Match_Type, &match_spec); + CREATE_TYPE(m, state->Scanner_Type, &scanner_spec); - x = PyLong_FromUnsignedLong(SRE_MAXREPEAT); - if (x) { - PyDict_SetItemString(d, "MAXREPEAT", x); - Py_DECREF(x); + if (PyModule_AddIntConstant(m, "MAGIC", SRE_MAGIC) < 0) { + goto error; } - x = PyLong_FromUnsignedLong(SRE_MAXGROUPS); - if (x) { - PyDict_SetItemString(d, "MAXGROUPS", x); - Py_DECREF(x); + if (PyModule_AddIntConstant(m, "CODESIZE", sizeof(SRE_CODE)) < 0) { + goto error; } - x = PyUnicode_FromString(copyright); - if (x) { - PyDict_SetItemString(d, "copyright", x); - Py_DECREF(x); + ADD_ULONG_CONSTANT(m, "MAXREPEAT", SRE_MAXREPEAT); + ADD_ULONG_CONSTANT(m, "MAXGROUPS", SRE_MAXGROUPS); + + if (PyModule_AddStringConstant(m, "copyright", copyright) < 0) { + goto error; } - return m; + + return 0; + +error: + return -1; +} + +static PyModuleDef_Slot sre_slots[] = { + {Py_mod_exec, sre_exec}, + {0, NULL}, +}; + +static struct PyModuleDef sremodule = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "_" SRE_MODULE, + .m_size = sizeof(_sremodulestate), + .m_methods = _functions, + .m_slots = sre_slots, + .m_traverse = sre_traverse, + .m_free = sre_free, + .m_clear = sre_clear, +}; + +PyMODINIT_FUNC +PyInit__sre(void) +{ + return PyModuleDef_Init(&sremodule); } /* vim:ts=4:sw=4:et diff --git a/Modules/clinic/_sre.c.h b/Modules/clinic/_sre.c.h index 2314114a1bc805..72d772c289ae8b 100644 --- a/Modules/clinic/_sre.c.h +++ b/Modules/clinic/_sre.c.h @@ -164,63 +164,28 @@ PyDoc_STRVAR(_sre_SRE_Pattern_match__doc__, "Matches zero or more characters at the beginning of the string."); #define _SRE_SRE_PATTERN_MATCH_METHODDEF \ - {"match", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_match, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_match__doc__}, + {"match", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_match, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_match__doc__}, static PyObject * -_sre_SRE_Pattern_match_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos); +_sre_SRE_Pattern_match_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos); static PyObject * -_sre_SRE_Pattern_match(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_sre_SRE_Pattern_match(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "match", 0}; - PyObject *argsbuf[3]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + static _PyArg_Parser _parser = {"O|nn:match", _keywords, 0}; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); - if (!args) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &string, &pos, &endpos)) { goto exit; } - string = args[0]; - if (!noptargs) { - goto skip_optional_pos; - } - if (args[1]) { - { - Py_ssize_t ival = -1; - PyObject *iobj = _PyNumber_Index(args[1]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - pos = ival; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } - { - Py_ssize_t ival = -1; - PyObject *iobj = _PyNumber_Index(args[2]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - endpos = ival; - } -skip_optional_pos: - return_value = _sre_SRE_Pattern_match_impl(self, string, pos, endpos); + return_value = _sre_SRE_Pattern_match_impl(self, cls, string, pos, endpos); exit: return return_value; @@ -233,63 +198,28 @@ PyDoc_STRVAR(_sre_SRE_Pattern_fullmatch__doc__, "Matches against all of the string."); #define _SRE_SRE_PATTERN_FULLMATCH_METHODDEF \ - {"fullmatch", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_fullmatch, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_fullmatch__doc__}, + {"fullmatch", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_fullmatch, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_fullmatch__doc__}, static PyObject * -_sre_SRE_Pattern_fullmatch_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos); +_sre_SRE_Pattern_fullmatch_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos); static PyObject * -_sre_SRE_Pattern_fullmatch(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_sre_SRE_Pattern_fullmatch(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fullmatch", 0}; - PyObject *argsbuf[3]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + static _PyArg_Parser _parser = {"O|nn:fullmatch", _keywords, 0}; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); - if (!args) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &string, &pos, &endpos)) { goto exit; } - string = args[0]; - if (!noptargs) { - goto skip_optional_pos; - } - if (args[1]) { - { - Py_ssize_t ival = -1; - PyObject *iobj = _PyNumber_Index(args[1]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - pos = ival; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } - { - Py_ssize_t ival = -1; - PyObject *iobj = _PyNumber_Index(args[2]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - endpos = ival; - } -skip_optional_pos: - return_value = _sre_SRE_Pattern_fullmatch_impl(self, string, pos, endpos); + return_value = _sre_SRE_Pattern_fullmatch_impl(self, cls, string, pos, endpos); exit: return return_value; @@ -304,63 +234,28 @@ PyDoc_STRVAR(_sre_SRE_Pattern_search__doc__, "Return None if no position in the string matches."); #define _SRE_SRE_PATTERN_SEARCH_METHODDEF \ - {"search", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_search, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_search__doc__}, + {"search", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_search, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_search__doc__}, static PyObject * -_sre_SRE_Pattern_search_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos); +_sre_SRE_Pattern_search_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos); static PyObject * -_sre_SRE_Pattern_search(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_sre_SRE_Pattern_search(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "search", 0}; - PyObject *argsbuf[3]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + static _PyArg_Parser _parser = {"O|nn:search", _keywords, 0}; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); - if (!args) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &string, &pos, &endpos)) { goto exit; } - string = args[0]; - if (!noptargs) { - goto skip_optional_pos; - } - if (args[1]) { - { - Py_ssize_t ival = -1; - PyObject *iobj = _PyNumber_Index(args[1]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - pos = ival; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } - { - Py_ssize_t ival = -1; - PyObject *iobj = _PyNumber_Index(args[2]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - endpos = ival; - } -skip_optional_pos: - return_value = _sre_SRE_Pattern_search_impl(self, string, pos, endpos); + return_value = _sre_SRE_Pattern_search_impl(self, cls, string, pos, endpos); exit: return return_value; @@ -444,63 +339,28 @@ PyDoc_STRVAR(_sre_SRE_Pattern_finditer__doc__, "For each match, the iterator returns a match object."); #define _SRE_SRE_PATTERN_FINDITER_METHODDEF \ - {"finditer", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_finditer, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_finditer__doc__}, + {"finditer", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_finditer, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_finditer__doc__}, static PyObject * -_sre_SRE_Pattern_finditer_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos); +_sre_SRE_Pattern_finditer_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos); static PyObject * -_sre_SRE_Pattern_finditer(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_sre_SRE_Pattern_finditer(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "finditer", 0}; - PyObject *argsbuf[3]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + static _PyArg_Parser _parser = {"O|nn:finditer", _keywords, 0}; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); - if (!args) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &string, &pos, &endpos)) { goto exit; } - string = args[0]; - if (!noptargs) { - goto skip_optional_pos; - } - if (args[1]) { - { - Py_ssize_t ival = -1; - PyObject *iobj = _PyNumber_Index(args[1]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - pos = ival; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } - { - Py_ssize_t ival = -1; - PyObject *iobj = _PyNumber_Index(args[2]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - endpos = ival; - } -skip_optional_pos: - return_value = _sre_SRE_Pattern_finditer_impl(self, string, pos, endpos); + return_value = _sre_SRE_Pattern_finditer_impl(self, cls, string, pos, endpos); exit: return return_value; @@ -512,63 +372,28 @@ PyDoc_STRVAR(_sre_SRE_Pattern_scanner__doc__, "\n"); #define _SRE_SRE_PATTERN_SCANNER_METHODDEF \ - {"scanner", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_scanner, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_scanner__doc__}, + {"scanner", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_scanner, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_scanner__doc__}, static PyObject * -_sre_SRE_Pattern_scanner_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos); +_sre_SRE_Pattern_scanner_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos); static PyObject * -_sre_SRE_Pattern_scanner(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_sre_SRE_Pattern_scanner(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "scanner", 0}; - PyObject *argsbuf[3]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + static _PyArg_Parser _parser = {"O|nn:scanner", _keywords, 0}; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); - if (!args) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &string, &pos, &endpos)) { goto exit; } - string = args[0]; - if (!noptargs) { - goto skip_optional_pos; - } - if (args[1]) { - { - Py_ssize_t ival = -1; - PyObject *iobj = _PyNumber_Index(args[1]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - pos = ival; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } - { - Py_ssize_t ival = -1; - PyObject *iobj = _PyNumber_Index(args[2]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - endpos = ival; - } -skip_optional_pos: - return_value = _sre_SRE_Pattern_scanner_impl(self, string, pos, endpos); + return_value = _sre_SRE_Pattern_scanner_impl(self, cls, string, pos, endpos); exit: return return_value; @@ -632,47 +457,27 @@ PyDoc_STRVAR(_sre_SRE_Pattern_sub__doc__, "Return the string obtained by replacing the leftmost non-overlapping occurrences of pattern in string by the replacement repl."); #define _SRE_SRE_PATTERN_SUB_METHODDEF \ - {"sub", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_sub, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_sub__doc__}, + {"sub", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_sub, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_sub__doc__}, static PyObject * -_sre_SRE_Pattern_sub_impl(PatternObject *self, PyObject *repl, - PyObject *string, Py_ssize_t count); +_sre_SRE_Pattern_sub_impl(PatternObject *self, PyTypeObject *cls, + PyObject *repl, PyObject *string, Py_ssize_t count); static PyObject * -_sre_SRE_Pattern_sub(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_sre_SRE_Pattern_sub(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"repl", "string", "count", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sub", 0}; - PyObject *argsbuf[3]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + static _PyArg_Parser _parser = {"OO|n:sub", _keywords, 0}; PyObject *repl; PyObject *string; Py_ssize_t count = 0; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); - if (!args) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &repl, &string, &count)) { goto exit; } - repl = args[0]; - string = args[1]; - if (!noptargs) { - goto skip_optional_pos; - } - { - Py_ssize_t ival = -1; - PyObject *iobj = _PyNumber_Index(args[2]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - count = ival; - } -skip_optional_pos: - return_value = _sre_SRE_Pattern_sub_impl(self, repl, string, count); + return_value = _sre_SRE_Pattern_sub_impl(self, cls, repl, string, count); exit: return return_value; @@ -685,47 +490,28 @@ PyDoc_STRVAR(_sre_SRE_Pattern_subn__doc__, "Return the tuple (new_string, number_of_subs_made) found by replacing the leftmost non-overlapping occurrences of pattern with the replacement repl."); #define _SRE_SRE_PATTERN_SUBN_METHODDEF \ - {"subn", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_subn, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_subn__doc__}, + {"subn", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_subn, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_subn__doc__}, static PyObject * -_sre_SRE_Pattern_subn_impl(PatternObject *self, PyObject *repl, - PyObject *string, Py_ssize_t count); +_sre_SRE_Pattern_subn_impl(PatternObject *self, PyTypeObject *cls, + PyObject *repl, PyObject *string, + Py_ssize_t count); static PyObject * -_sre_SRE_Pattern_subn(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_sre_SRE_Pattern_subn(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"repl", "string", "count", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "subn", 0}; - PyObject *argsbuf[3]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + static _PyArg_Parser _parser = {"OO|n:subn", _keywords, 0}; PyObject *repl; PyObject *string; Py_ssize_t count = 0; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); - if (!args) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &repl, &string, &count)) { goto exit; } - repl = args[0]; - string = args[1]; - if (!noptargs) { - goto skip_optional_pos; - } - { - Py_ssize_t ival = -1; - PyObject *iobj = _PyNumber_Index(args[2]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - count = ival; - } -skip_optional_pos: - return_value = _sre_SRE_Pattern_subn_impl(self, repl, string, count); + return_value = _sre_SRE_Pattern_subn_impl(self, cls, repl, string, count); exit: return return_value; @@ -1075,15 +861,26 @@ PyDoc_STRVAR(_sre_SRE_Scanner_match__doc__, "\n"); #define _SRE_SRE_SCANNER_MATCH_METHODDEF \ - {"match", (PyCFunction)_sre_SRE_Scanner_match, METH_NOARGS, _sre_SRE_Scanner_match__doc__}, + {"match", (PyCFunction)(void(*)(void))_sre_SRE_Scanner_match, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Scanner_match__doc__}, static PyObject * -_sre_SRE_Scanner_match_impl(ScannerObject *self); +_sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls); static PyObject * -_sre_SRE_Scanner_match(ScannerObject *self, PyObject *Py_UNUSED(ignored)) +_sre_SRE_Scanner_match(ScannerObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _sre_SRE_Scanner_match_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":match", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _sre_SRE_Scanner_match_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(_sre_SRE_Scanner_search__doc__, @@ -1092,14 +889,25 @@ PyDoc_STRVAR(_sre_SRE_Scanner_search__doc__, "\n"); #define _SRE_SRE_SCANNER_SEARCH_METHODDEF \ - {"search", (PyCFunction)_sre_SRE_Scanner_search, METH_NOARGS, _sre_SRE_Scanner_search__doc__}, + {"search", (PyCFunction)(void(*)(void))_sre_SRE_Scanner_search, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Scanner_search__doc__}, static PyObject * -_sre_SRE_Scanner_search_impl(ScannerObject *self); +_sre_SRE_Scanner_search_impl(ScannerObject *self, PyTypeObject *cls); static PyObject * -_sre_SRE_Scanner_search(ScannerObject *self, PyObject *Py_UNUSED(ignored)) +_sre_SRE_Scanner_search(ScannerObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _sre_SRE_Scanner_search_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":search", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _sre_SRE_Scanner_search_impl(self, cls); + +exit: + return return_value; } -/*[clinic end generated code: output=0e27915b1eb7c0e4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=518f7bb775c1184f input=a9049054013a1b77]*/
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: