Skip to content

Commit

Permalink
pythongh-90763: Modernise xx template module initialisation
Browse files Browse the repository at this point in the history
Use C APIs such as PyModule_AddType instead of PyModule_AddObject.
Also remove incorrect module decrefs if module fails to initialise.
  • Loading branch information
erlend-aasland committed May 22, 2022
1 parent e5d8dbd commit 66c0613
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 53 deletions.
74 changes: 40 additions & 34 deletions Modules/xxlimited_35.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ static PyType_Slot Xxo_Type_slots[] = {
};

static PyType_Spec Xxo_Type_spec = {
"xxlimited.Xxo",
"xxlimited_35.Xxo",
sizeof(XxoObject),
0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
Expand Down Expand Up @@ -189,7 +189,7 @@ static PyType_Slot Str_Type_slots[] = {
};

static PyType_Spec Str_Type_spec = {
"xxlimited.Str",
"xxlimited_35.Str",
0,
0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
Expand All @@ -212,7 +212,7 @@ static PyType_Slot Null_Type_slots[] = {
};

static PyType_Spec Null_Type_spec = {
"xxlimited.Null",
"xxlimited_35.Null",
0, /* basicsize */
0, /* itemsize */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
Expand All @@ -236,52 +236,58 @@ static PyMethodDef xx_methods[] = {
PyDoc_STRVAR(module_doc,
"This is a module for testing limited API from Python 3.5.");

static PyObject *
create_and_add_type(PyObject *module, const char *name, PyType_Spec *spec)
{
PyObject *type = PyType_FromSpec(spec);
if (type == NULL) {
return NULL;
}
int rc = PyModule_AddObject(module, name, type);
if (rc < 0) {
Py_DECREF(type);
return NULL;
}
return type;
}

static int
xx_modexec(PyObject *m)
{
PyObject *o;

/* Due to cross platform compiler issues the slots must be filled
* here. It's required for portability to Windows without requiring
* C++. */
Null_Type_slots[0].pfunc = &PyBaseObject_Type;
Null_Type_slots[1].pfunc = PyType_GenericNew;
Str_Type_slots[0].pfunc = &PyUnicode_Type;

Xxo_Type = PyType_FromSpec(&Xxo_Type_spec);
if (Xxo_Type == NULL)
goto fail;

/* Add some symbolic constants to the module */
if (ErrorObject == NULL) {
ErrorObject = PyErr_NewException("xxlimited.error", NULL, NULL);
if (ErrorObject == NULL)
goto fail;
ErrorObject = PyErr_NewException("xxlimited_35.error", NULL, NULL);
if (ErrorObject == NULL) {
return -1;
}
}
Py_INCREF(ErrorObject);
PyModule_AddObject(m, "error", ErrorObject);

/* Add Xxo */
o = PyType_FromSpec(&Xxo_Type_spec);
if (o == NULL)
goto fail;
PyModule_AddObject(m, "Xxo", o);

/* Add Str */
o = PyType_FromSpec(&Str_Type_spec);
if (o == NULL)
goto fail;
PyModule_AddObject(m, "Str", o);

/* Add Null */
o = PyType_FromSpec(&Null_Type_spec);
if (o == NULL)
goto fail;
PyModule_AddObject(m, "Null", o);
int rc = PyModule_AddObject(m, "error", ErrorObject);
if (rc < 0) {
Py_DECREF(ErrorObject);
return -1;
}

/* Add Xxo, Str, and Null types */
Xxo_Type = create_and_add_type(m, "Xxo", &Xxo_Type_spec);
if (Xxo_Type == NULL) {
return -1;
}
if (create_and_add_type(m, "Str", &Str_Type_spec) == NULL) {
return -1;
}
if (create_and_add_type(m, "Null", &Null_Type_spec) == NULL) {
return -1;
}

return 0;
fail:
Py_XDECREF(m);
return -1;
}


Expand Down
39 changes: 20 additions & 19 deletions Modules/xxmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,31 +358,32 @@ xx_exec(PyObject *m)

/* Finalize the type object including setting type of the new type
* object; doing it here is required for portability, too. */
if (PyType_Ready(&Xxo_Type) < 0)
goto fail;
if (PyType_Ready(&Xxo_Type) < 0) {
return -1;
}

/* Add some symbolic constants to the module */
if (ErrorObject == NULL) {
ErrorObject = PyErr_NewException("xx.error", NULL, NULL);
if (ErrorObject == NULL)
goto fail;
if (ErrorObject == NULL) {
return -1;
}
}
int rc = PyModule_AddType(m, (PyTypeObject *)ErrorObject);
Py_DECREF(ErrorObject);
if (rc < 0) {
return -1;
}
Py_INCREF(ErrorObject);
PyModule_AddObject(m, "error", ErrorObject);

/* Add Str */
if (PyType_Ready(&Str_Type) < 0)
goto fail;
PyModule_AddObject(m, "Str", (PyObject *)&Str_Type);

/* Add Null */
if (PyType_Ready(&Null_Type) < 0)
goto fail;
PyModule_AddObject(m, "Null", (PyObject *)&Null_Type);

/* Add Str and Null types */
if (PyModule_AddType(m, &Str_Type) < 0) {
return -1;
}
if (PyModule_AddType(m, &Null_Type) < 0) {
return -1;
}

return 0;
fail:
Py_XDECREF(m);
return -1;
}

static struct PyModuleDef_Slot xx_slots[] = {
Expand Down

0 comments on commit 66c0613

Please sign in to comment.