Article Index

 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 gc

myInst1=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 gc

myInst1=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 gc

myInst1=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)