Page 194
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <stddef.h>
#include "structmember.h"
typedef struct
{
PyObject_HEAD int myVal;
} MyObject;
static void Custom_dealloc(MyObject *self)
{
printf("destructor called\n");
Py_TYPE(self)->tp_free((PyObject *)self);
}
static PyObject *myFunc(MyObject *self, PyObject *args)
{
printf("%d\n", self->myVal);
printf("hello world\n");
Py_RETURN_NONE;
};
static PyMemberDef myMemberdef[] = {
{"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},
{NULL}};
static PyMethodDef myMethodDef[] = {
{"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},
{NULL}};
static PyTypeObject MyType1 = {
.ob_base = PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "example.myObject",
.tp_doc = PyDoc_STR("My Custom object"),
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_basicsize = sizeof(MyObject),
.tp_itemsize = 0,
.tp_new = PyType_GenericNew,
.tp_members = myMemberdef,
.tp_methods = myMethodDef,
.tp_dealloc = (destructor)Custom_dealloc,
};
static struct PyModuleDef myModule = {
PyModuleDef_HEAD_INIT,
"example",
"C library to test API",
-1,
NULL};
PyMODINIT_FUNC PyInit_example(void)
{
PyObject *m = PyModule_Create(&myModule);
if (m == NULL)
return NULL;
int res = PyType_Ready(&MyType1);
PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);
return m;
}
test.py
import example
myinst1=example.MyClass()
myinst1.MyVar=42
print(myinst1.MyVar)
myInst1=None
Page 196
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <stddef.h>
#include "structmember.h"
typedef struct
{
PyObject_HEAD
int myVal;
PyObject *myAttr;
} MyObject;
static void Custom_dealloc(MyObject *self)
{
printf("destructor called\n");
Py_TYPE(self)->tp_free((PyObject *)self);
}
static PyObject *myFunc(MyObject *self, PyObject *args)
{
printf("%d\n", self->myVal);
printf("hello world\n");
Py_RETURN_NONE;
};
static PyMemberDef myMemberdef[] = {
{"MyVar", T_INT, offsetof(MyObject, myVal), 0,"MyInstanceAttr"},
{"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0,"MyInstandeAttr"},
{NULL}};
static PyMethodDef myMethodDef[] = {
{"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},
{NULL}};
static PyTypeObject MyType1 = {
.ob_base = PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "example.myObject",
.tp_doc = PyDoc_STR("My Custom object"),
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_basicsize = sizeof(MyObject),
.tp_itemsize = 0,
.tp_new = PyType_GenericNew,
.tp_members = myMemberdef,
.tp_methods = myMethodDef,
.tp_dealloc = (destructor)Custom_dealloc,
};
static struct PyModuleDef myModule = {
PyModuleDef_HEAD_INIT,
"example",
"C library to test API",
-1,
NULL};
PyMODINIT_FUNC PyInit_example(void)
{
PyObject *m = PyModule_Create(&myModule);
if (m == NULL)
return NULL;
int res = PyType_Ready(&MyType1);
PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);
return m;
}
test.py
import example
myInst1=example.MyClass()
myInst1.MyAttr=myInst1
myInst1=None
print("end")
while True:
pass
Page 197
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <stddef.h>
#include "structmember.h"
typedef struct
{
PyObject_HEAD int myVal;
PyObject *myAttr;
PyObject *weaklist;
} MyObject;
static void Custom_dealloc(MyObject *self)
{
printf("destructor called\n");
Py_TYPE(self)->tp_free((PyObject *)self);
}
static PyObject *myFunc(MyObject *self, PyObject *args)
{
printf("%d\n", self->myVal);
printf("hello world\n");
Py_RETURN_NONE;
};
static PyMemberDef myMemberdef[] = {
{"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},
{"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},
{NULL}};
static PyMethodDef myMethodDef[] = {
{"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},
{NULL}};
static PyTypeObject MyType1 = {
.ob_base = PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "example.myObject",
.tp_doc = PyDoc_STR("My Custom object"),
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_basicsize = sizeof(MyObject),
.tp_itemsize = 0,
.tp_new = PyType_GenericNew,
.tp_members = myMemberdef,
.tp_methods = myMethodDef,
.tp_dealloc = (destructor)Custom_dealloc,
.tp_weaklistoffset = offsetof(MyObject, weaklist),
};
static struct PyModuleDef myModule = {
PyModuleDef_HEAD_INIT,
"example",
"C library to test API",
-1,
NULL};
PyMODINIT_FUNC PyInit_example(void)
{
PyObject *m = PyModule_Create(&myModule);
if (m == NULL)
return NULL;
int res = PyType_Ready(&MyType1);
PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);
return m;
}
test.py
import example
import weakref
myInst1=example.MyClass()
myInst1.MyAttr=weakref.ref(myInst1)
myInst1=None
print("end")
while True:
pass
Page 199
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <stddef.h>
#include "structmember.h"
typedef struct
{
PyObject_HEAD int myVal;
PyObject *myAttr;
} MyObject;
static void Custom_dealloc(MyObject *self)
{
printf("destructor called\n");
PyObject *error_type,*error_value, *error_traceback;
PyErr_Fetch(&error_type, &error_value, &error_traceback);
PyObject_GC_UnTrack(self);
Py_TYPE(self)->tp_clear((PyObject *)self);
PyObject_GC_Del(self);
PyErr_Restore(error_type, error_value, error_traceback);
}
static int Custom_clear(MyObject *self)
{
printf("clear called\n");
Py_CLEAR(self->myAttr);
return 0;
}
static int Custom_traverse(MyObject *self, visitproc visit, void *arg)
{
printf("traverse called\n");
Py_VISIT(self->myAttr);
return 0;
}
static int Custom_init(MyObject *self, PyObject *args, PyObject *kwds)
{
self->myVal = 0;
self->myAttr = Py_None;
Py_XINCREF(Py_None);
return 0;
}
static PyObject *myFunc(MyObject *self, PyObject *args)
{
printf("%d\n", self->myVal);
printf("hello world\n");
Py_RETURN_NONE;
};
static PyMemberDef myMemberdef[] = {
{"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},
{"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},
{NULL}};
static PyMethodDef myMethodDef[] = {
{"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},
{NULL}};
static PyTypeObject MyType1 = {
.ob_base = PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "example.myObject",
.tp_doc = PyDoc_STR("My Custom object"),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
.tp_basicsize = sizeof(MyObject),
.tp_itemsize = 0,
.tp_new = PyType_GenericNew,
.tp_init = (initproc)Custom_init,
.tp_members = myMemberdef,
.tp_methods = myMethodDef,
.tp_clear = (inquiry)Custom_clear,
.tp_traverse = (traverseproc)Custom_traverse,
.tp_dealloc = (destructor)Custom_dealloc,
};
static struct PyModuleDef myModule = {
PyModuleDef_HEAD_INIT,
"example",
"C library to test API",
-1,
NULL};
PyMODINIT_FUNC PyInit_example(void)
{
PyObject *m = PyModule_Create(&myModule);
if (m == NULL)
return NULL;
int res = PyType_Ready(&MyType1);
PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);
return m;
}
test.py
import example
import gcmyInst1=example.MyClass()
print(gc.is_tracked(myInst1))
myInst1.MyAttr=myInst1
myInst1=None
print(gc.get_count())
gc.collect()
print(gc.get_count())
Page 203
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <stddef.h>
#include "structmember.h"
static PyTypeObject MyType1;
typedef struct
{
PyObject_HEAD int myVal;
PyObject *myAttr;
} MyObject;
static void Custom_dealloc(MyObject *self)
{
printf("destructor called\n");
PyObject *error_type,
*error_value, *error_traceback;
PyErr_Fetch(&error_type, &error_value, &error_traceback);
PyObject_GC_UnTrack(self);
Py_TYPE(self)->tp_clear((PyObject *)self);
PyObject_GC_Del(self);
PyErr_Restore(error_type, error_value, error_traceback);
}
static void Custom_finalizer(MyObject *self)
{
printf("finalizer called\n");
if (PyObject_GC_IsFinalized((PyObject *)self))
return;
PyObject *error_type,
*error_value, *error_traceback;
PyErr_Fetch(&error_type, &error_value, &error_traceback);
PyObject_GC_UnTrack(self);
Py_TYPE(self)->tp_clear((PyObject *)self);
PyObject_GC_Del(self);
PyErr_Restore(error_type, error_value, error_traceback);
}
static int Custom_clear(MyObject *self)
{
printf("clear called\n");
Py_CLEAR(self->myAttr);
return 0;
}
static int Custom_traverse(MyObject *self, visitproc visit, void *arg)
{
printf("traverse called\n");
Py_VISIT(self->myAttr);
return 0;
}
static int Custom_init(MyObject *self, PyObject *args, PyObject *kwds)
{
self->myVal = 0;
self->myAttr = Py_None;
Py_XINCREF(Py_None);
return 0;
}
static PyObject *myFunc(MyObject *self, PyObject *args)
{
printf("%d\n", self->myVal);
printf("hello world\n");
Py_RETURN_NONE;
};
static PyMemberDef myMemberdef[] = {
{"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},
{"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},
{NULL}};
static PyMethodDef myMethodDef[] = {
{"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},
{NULL}};
static PyTypeObject MyType1 = {
.ob_base = PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "example.myObject",
.tp_doc = PyDoc_STR("My Custom object"),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
.tp_basicsize = sizeof(MyObject),
.tp_itemsize = 0,
.tp_new = PyType_GenericNew,
.tp_init = (initproc)Custom_init,
.tp_members = myMemberdef,
.tp_methods = myMethodDef,
.tp_clear = (inquiry)Custom_clear,
.tp_traverse = (traverseproc)Custom_traverse,
.tp_finalize = (destructor)Custom_finalizer,
.tp_dealloc = (destructor)Custom_dealloc,
};
static struct PyModuleDef myModule = {
PyModuleDef_HEAD_INIT,
"example",
"C library to test API",
-1,
NULL};
PyMODINIT_FUNC PyInit_example(void)
{
PyObject *m = PyModule_Create(&myModule);
if (m == NULL)
return NULL;
int res = PyType_Ready(&MyType1);
PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);
return m;
}
test.py
import example
import gcmyInst1=example.MyClass()
print(gc.is_tracked(myInst1))
myInst1.MyAttr=myInst1
myInst1=None
print(gc.get_count())
gc.collect()
print(gc.get_count())
Page 205
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <stddef.h>
#include "structmember.h"
typedef struct
{
PyObject_HEAD
int myVal;
} MyObject;
static PyObject *myFunc(MyObject *self, PyObject *args)
{
printf("%d\n", self->myVal);
printf("hello world\n");
Py_RETURN_NONE;
};
static PyMemberDef myMemberdef[] = {
{"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},
{NULL}};
static PyMethodDef myMethodDef[] = {
{"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},
{NULL}};
static struct PyModuleDef myModule = {PyModuleDef_HEAD_INIT, "example", "C library to test API", -1, NULL};
PyMODINIT_FUNC PyInit_example(void)
{
PyObject *m = PyModule_Create(&myModule);
if (m == NULL)
return NULL;
static PyType_Slot mySlots[] = {
{Py_tp_doc, "My Custom object"},
{Py_tp_members, myMemberdef},
{Py_tp_methods, myMethodDef},
{0, NULL}};
PyType_Spec mySpec = {
"example.myObject",
sizeof(MyObject),
0,
Py_TPFLAGS_DEFAULT,
mySlots};
PyTypeObject *MyType1 = (PyTypeObject *)PyType_FromSpec(&mySpec);
PyModule_AddObject(m, "MyClass", (PyObject *)MyType1);
return m;
}
test.py
import example
myInst1=example.MyClass()
myInst1.MyVar=42
print(myInst1.MyVar)
myInst1.MyMethod()
example.MyClass.myNewVar=43
print(example.MyClass.myNewVar)
Page 206
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <stddef.h>
#include "structmember.h"
typedef struct
{
PyObject_HEAD int myVal;
PyObject *myAttr;
} MyObject;
static void Custom_dealloc(MyObject *self)
{
printf("destructor called\n");
PyObject *error_type, *error_value, *error_traceback;
PyErr_Fetch(&error_type, &error_value, &error_traceback);
PyObject_GC_UnTrack(self);
Py_TYPE(self)->tp_clear((PyObject *)self);
PyObject_GC_Del(self);
PyErr_Restore(error_type, error_value, error_traceback);
}
static void Custom_finalizer(MyObject *self)
{
printf("finalizer called\n");
if (PyObject_GC_IsFinalized((PyObject *)self))
return;
PyObject *error_type,
*error_value, *error_traceback;
PyErr_Fetch(&error_type, &error_value, &error_traceback);
PyObject_GC_UnTrack(self);
Py_TYPE(self)->tp_clear((PyObject *)self);
PyObject_GC_Del(self);
PyErr_Restore(error_type, error_value, error_traceback);
}
static int Custom_clear(MyObject *self)
{
printf("clear called\n");
Py_CLEAR(self->myAttr);
return 0;
}
static int Custom_traverse(MyObject *self, visitproc visit, void *arg)
{
printf("traverse called\n");
Py_VISIT(self->myAttr);
return 0;
}
static int Custom_init(MyObject *self, PyObject *args, PyObject *kwds)
{
self->myVal = 0;
self->myAttr = Py_None;
Py_XINCREF(Py_None);
return 0;
}
static PyObject *myFunc(MyObject *self, PyObject *args)
{
printf("%d\n", self->myVal);
printf("hello world\n");
Py_RETURN_NONE;
};
static PyMemberDef myMemberdef[] = {
{"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},
{"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},
{NULL}};
static PyMethodDef myMethodDef[] = {
{"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},
{NULL}};
static PyType_Slot mySlots[] = {
{Py_tp_doc, "My Custom object"},
{Py_tp_members, myMemberdef},
{Py_tp_methods, myMethodDef},
{Py_tp_clear, (inquiry)Custom_clear},
{Py_tp_traverse, (traverseproc)Custom_traverse},
{Py_tp_dealloc, (destructor)Custom_dealloc},
{Py_tp_finalize,(destructor)Custom_finalizer},
{0, NULL}};
PyType_Spec mySpec = {
"example.myObject",
sizeof(MyObject),
0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
mySlots};
static struct PyModuleDef myModule = {
PyModuleDef_HEAD_INIT,
"example",
"C library to test API",
-1,
NULL};
PyMODINIT_FUNC PyInit_example(void)
{
PyObject *m = PyModule_Create(&myModule);
if (m == NULL)
return NULL;
PyTypeObject *MyType1 = (PyTypeObject *)PyType_FromSpec(&mySpec);
PyModule_AddObject(m, "MyClass", (PyObject *)MyType1);
return m;
}
test.py
import example
import gcmyInst1=example.MyClass()
print(gc.is_tracked(myInst1))
#myInst1.MyAttr=myInst1
myInst1=None
print(gc.get_count())
gc.collect()
print(gc.get_count())example.MyClass.myNewVar=43
print(example.MyClass.myNewVar)
Page 209
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <stddef.h>
#include "structmember.h"
typedef struct
{
PyUnicodeObject str;
int myVal;
PyObject *myAttr;
} MyObject;
static PyObject *myFunc(MyObject *self, PyObject *args)
{
printf("%d\n", self->myVal);
printf("hello world\n");
Py_RETURN_NONE;
};
static PyMemberDef myMemberdef[] = {
{"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},
{"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},
{NULL}};
static PyMethodDef myMethodDef[] = {
{"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},
{NULL}};
static PyTypeObject MyType1 = {
.ob_base = PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "example.myObject",
.tp_doc = PyDoc_STR("My Custom object"),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
.tp_basicsize = sizeof(MyObject),
.tp_itemsize = 0,
.tp_members = myMemberdef,
.tp_methods = myMethodDef,
};
static struct PyModuleDef myModule = {
PyModuleDef_HEAD_INIT,
"example",
"C library to test API",
-1,
NULL};
PyMODINIT_FUNC PyInit_example(void)
{
PyObject *m = PyModule_Create(&myModule);
if (m == NULL)
return NULL;
MyType1.tp_base = &PyUnicode_Type;
int res = PyType_Ready(&MyType1);
PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);
return m;
}
test.py
import example
myInst1=example.MyClass("Hello")
print(len(myInst1))
myInst1.MyVar=42
print(myInst1.MyVar)
myInst1.MyMethod()
print("myInst=",myInst1)
Page 211
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <stddef.h>
#include "structmember.h"
typedef struct
{
PyListObject list;
int myVal;
PyObject *myAttr;
} MyObject;
static PyObject *myFunc(MyObject *self, PyObject *args)
{
printf("%d\n", self->myVal);
printf("hello world\n");
Py_RETURN_NONE;
};
static PyMemberDef myMemberdef[] = {
{"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},
{"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},
{NULL}};
static PyMethodDef myMethodDef[] = {
{"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},
{NULL}};
static PyTypeObject MyType1 = {
.ob_base = PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "example.myObject",
.tp_doc = PyDoc_STR("My Custom object"),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
.tp_basicsize = sizeof(MyObject),
.tp_itemsize = 0,
.tp_members = myMemberdef,
.tp_methods = myMethodDef,
};
static struct PyModuleDef myModule = {
PyModuleDef_HEAD_INIT,
"example",
"C library to test API",
-1,
NULL};
PyMODINIT_FUNC PyInit_example(void)
{
PyObject *m = PyModule_Create(&myModule);
if (m == NULL)
return NULL;
MyType1.tp_base = &PyList_Type;
int res = PyType_Ready(&MyType1);
PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);
return m;
}
test.py
import example
myInst1=example.MyClass(["brian","spam",42])
print(myInst1)
print(len(myInst1))
Page 213
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <stddef.h>
#include "structmember.h"
typedef struct
{
PyListObject list;
int myVal;
PyObject *myAttr;
} MyObject;
static PyObject *myFunc(MyObject *self, PyObject *args)
{
printf("%d\n", self->myVal);
printf("hello world\n");
Py_RETURN_NONE;
};
static int Custom_init(MyObject *self, PyObject *args, PyObject *kwds)
{
int res = Py_TYPE(self)->tp_base->tp_init((PyObject *)self, args, kwds);
self->myVal = PyList_Size((PyObject *)self);
return 0;
}
static void Custom_dealloc(MyObject *self)
{
printf("destructor called\n");
PyObject *error_type, *error_value, *error_traceback;
PyErr_Fetch(&error_type, &error_value, &error_traceback);
Py_TYPE(self)->tp_clear((PyObject *)self);
Py_TYPE(self)->tp_base->tp_dealloc((PyObject *)self);
PyErr_Restore(error_type, error_value, error_traceback);
}
static int Custom_clear(MyObject *self)
{
printf("clear called\n");
Py_CLEAR(self->myAttr);
return 0;
}
static int Custom_traverse(MyObject *self, visitproc visit, void *arg)
{
printf("traverse called\n");
Py_VISIT(self->myAttr);
PyList_Type.tp_traverse((PyObject *)self, visit, arg);
return 0;
}
static PyMemberDef myMemberdef[] = {
{"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},
{"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},
{NULL}};
static PyMethodDef myMethodDef[] = {
{"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},
{NULL}};
static PyTypeObject MyType1 = {
.ob_base = PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "example.myObject",
.tp_doc = PyDoc_STR("My Custom object"),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
.tp_basicsize = sizeof(MyObject),
.tp_itemsize = 0,
.tp_members = myMemberdef,
.tp_methods = myMethodDef,
.tp_init = (initproc)Custom_init,
.tp_clear = (inquiry)Custom_clear,
.tp_traverse = (traverseproc)Custom_traverse,
.tp_dealloc = (destructor)Custom_dealloc,
};
static struct PyModuleDef myModule = {
PyModuleDef_HEAD_INIT,
"example",
"C library to test API",
-1,
NULL};
PyMODINIT_FUNC PyInit_example(void)
{
PyObject *m = PyModule_Create(&myModule);
if (m == NULL)
return NULL;
MyType1.tp_base = &PyList_Type;
int res = PyType_Ready(&MyType1);
PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);
return m;
}
test.py
import example
myInst1=example.MyClass(["brian","spam",42])
print(myInst1)
print(len(myInst1))
print(myInst1.MyVar)
Page 216
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <stddef.h>
#include "structmember.h"
static PyObject *myFactory(PyObject *self, PyObject *args)
{
args = Py_BuildValue("()");
PyObject *result = PyObject_Call((PyObject *)self, args, NULL);
return result;
}
static PyMethodDef myFactory_def = {
"myFactory",
(PyCFunction)myFactory,
METH_FASTCALL | METH_KEYWORDS,
"the doc string"};
typedef struct
{
PyObject_HEAD
int myVal;
} MyObject;
static int Custom_init(MyObject *self, PyObject *args, PyObject *kwds)
{
self->myVal = 0;
return 0;
};
static PyMemberDef myMemberdef[] = {
{"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},
{NULL}};
static PyTypeObject MyType1= {
.ob_base = PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "example.myObject",
.tp_doc = PyDoc_STR("My Custom object"),
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_basicsize = sizeof(MyObject),
.tp_itemsize = 0,
.tp_new = PyType_GenericNew,
.tp_init = (initproc)Custom_init,
.tp_members = myMemberdef,
};
static struct PyModuleDef myModule = {
PyModuleDef_HEAD_INIT,
"example",
"C library to test API",
-1,
NULL};
PyMODINIT_FUNC PyInit_example(void)
{
PyObject *m = PyModule_Create(&myModule);
if (m == NULL)
return NULL;
PyObject *myPyFactory = PyCFunction_New(&myFactory_def,(PyObject*) &MyType1);
PyModule_AddObject(m, "myFactory", myPyFactory);
int res = PyType_Ready(&MyType1);
PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);
return m;
}
test.py
import example
myInst=example.myFactory()
print(myInst)
print(myInst.MyVar)
myInst.MyVar=42
print(myInst.MyVar)
Page 217
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
static PyObject *call(PyObject *self, PyObject *args)
{
PyObject *math = PyImport_AddModule("math");
PyObject *mathdict = PyModule_GetDict(math);
PyObject *myFunction = PyDict_GetItemString(mathdict, "sqrt");
args = Py_BuildValue("(I)", 2);
PyObject *result = PyObject_Call(myFunction, args, NULL);
return result;
}
static PyObject *object1(PyObject *self, PyObject *args)
{
PyObject *main = PyImport_AddModule("__main__");
PyObject *maindict = PyModule_GetDict(main);
PyObject *myclass = PyDict_GetItemString(maindict, "myClass");
args = Py_BuildValue("()");
PyObject *result = PyObject_Call(myclass, args, NULL);
PyObject *newValue = PyLong_FromLong(43);
PyObject_SetAttrString(result, "myAttribute1", newValue);
return result;
}
static PyMethodDef AddMethods[] = {
{"call", call, METH_VARARGS, "an example"},
{"object1", object1, METH_VARARGS, "an example"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef myModule = {
PyModuleDef_HEAD_INIT,
"example",
"C library to test API",
-1,
AddMethods
};
PyMODINIT_FUNC PyInit_example(void)
{
PyObject *m = PyModule_Create(&myModule);
if (m == NULL)
return NULL;
return m;
}
test.py
import example
import math
class myClass:
myAttribute1=0
print(example.call())
inst=example.object1()
print(inst)
print(inst.myAttribute1)