Let's say I want to write a module called countries
that contains information about the countries of the world. I want to write it in C. It will expose a member called countries
which is a list of objects of type Country
. The Country
type has two members: name
and capital
, both strings. So we could do something like this:
>>> from countries import countries
>>> countries[0].name
Afghanistan
>>> countries[0].capital
Kabul
Following the various scraps of tutorials I was able to find online, I figured out how to create my custom Country
type in C. It looks basically like this:
typedef struct {
PyObject_HEAD
char *name;
char *capital;
} Country;
static struct PyMemberDef CountryMembers[] = {
{"name", T_OBJECT_EX, offsetof(Country, name), 0, "name"},
{"capital", T_OBJECT_EX, offsetof(Country, capital), 0, "capital"},
{NULL}
};
static PyTypeObject CountryType = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "countries.Country",
.tp_doc = "Country",
.tp_basicsize = sizeof(Country),
.tp_itemsize = 0,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_new = PyType_GenericNew,
.tp_members = CountryMembers
};
and then in the module init function, call Py_TypeReady
and add the type to the module. However, what I cannot figure out how to do is create a new instance of this type, in C, add it to the module, and populate its fields. The closest I can get is this, again in the module init function:
PyObject *afghanistan = PyObject_CallObject((PyObject*) &CountryType, NULL);
PyModule_AddObject(local_module, "afghanistan", (PyObject*) afghanistan);
But I don't know how to fill in the members.