Skip to content

Instantly share code, notes, and snippets.

@steve-s
Created December 6, 2022 13:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save steve-s/9dd4d7e4810bf4cb61302f049d03ecf5 to your computer and use it in GitHub Desktop.
Save steve-s/9dd4d7e4810bf4cb61302f049d03ecf5 to your computer and use it in GitHub Desktop.
#include <Python.h>
static int spike_exec(PyObject *module);
static PyObject *nb_add(PyObject *self, PyObject *args);
typedef struct { int ID; } mod_state_t;
static PyModuleDef_Slot spike_slots[] = {
{Py_mod_exec, spike_exec},
{0, NULL}
};
static PyMethodDef Methods[] = { {NULL, NULL, 0, NULL} };
static struct PyModuleDef spike = {
PyModuleDef_HEAD_INIT,
NULL,
NULL,
sizeof(mod_state_t),
Methods,
spike_slots
};
static PyType_Slot slots1[] = {
{Py_nb_add, nb_add},
{0, 0},
};
static PyType_Spec Type1_spec = {
"MyType1", 0, 0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
slots1,
};
static PyType_Slot slots2[] = { {0, 0} };
static PyType_Spec Type2_spec = {
"MyType2", 0, 0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
slots2,
};
static PyObject *nb_add(PyObject *self, PyObject *args) {
PyObject *module = PyType_GetModuleByDef(Py_TYPE(self), &spike);
mod_state_t *state = (mod_state_t*) PyModule_GetState(module);
return PyLong_FromLong(state->ID);
}
static int spike_exec(PyObject *module) {
PyObject *py_name = PyObject_GetAttrString(module, "__name__");
const char *name_s = PyUnicode_AsUTF8AndSize(py_name, NULL);
mod_state_t *state = (mod_state_t*) PyModule_GetState(module);
PyObject *type;
if (strcmp(name_s, "spike") == 0) {
type = PyType_FromModuleAndSpec(module, &Type1_spec, NULL);
PyModule_AddObject(module, "MyType1", type);
state->ID = 1;
} else {
// imported as something else like: import subspike.spike
type = PyType_FromModuleAndSpec(module, &Type2_spec, NULL);
PyModule_AddObject(module, "MyType2", type);
state->ID = 2;
}
Py_DECREF(type);
return 0;
}
PyMODINIT_FUNC PyInit_spike(void) {
return PyModuleDef_Init(&spike);
}
/* Test:
import spike
import subspike.spike # simlink to spike.{tags}.so
class C(spike.MyType1):
pass
print("class C(spike.MyType1)")
print(f"{C() + C()=}")
class C(spike.MyType1, subspike.spike.MyType2):
pass
print("class C(spike.MyType1, subspike.spike.MyType2)")
print(f"{C() + C()=}")
class C(subspike.spike.MyType2, spike.MyType1):
pass
print("class C(subspike.spike.MyType2, spike.MyType1)")
print(f"{C() + C()=}")
# Output:
class C(spike.MyType1)
C() + C()=1
class C(spike.MyType1, subspike.spike.MyType2)
C() + C()=1
class C(subspike.spike.MyType2, spike.MyType1)
C() + C()=2
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment