summaryrefslogtreecommitdiffstats
path: root/Modules/_sre.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_sre.c')
-rw-r--r--Modules/_sre.c473
1 files changed, 275 insertions, 198 deletions
diff --git a/Modules/_sre.c b/Modules/_sre.c
index fbabeb7..0a5ca60 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 @@ error:
/*[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 @@ error:
}
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 @@ error:
/*[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