Extending & Embedding Python Using C
We have decided not to make the programs available as a download because this is not the point of the book - the programs are not finished production code but something you should type in and study.
The best solution is to provide the source code of the programs in a form that can be copied and pasted into an editor.
The only downside is that you have to create a project to paste the code into.
To do this follow the instructions in the book.
Notice that indents have been removed but you can put them back in by auto formatting the code after pasting.
All of the programs below were copy and pasted from working programs in the IDE. They have been formatted using the built in formatter and hence are not identical in layout to the programs in the book.
This is to make copy and pasting them easier. The programs in the book are formatted to be easy to read on the page.
If anything you consider important is missing or if you have any requests or comments contact:
This email address is being protected from spambots. You need JavaScript enabled to view it.
Page 23
Hello.c
#include
int main(int argc, char **argv)
{
printf("Hello C World\n");
return 0;
}
tasks.json
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc build active file",
"command": "/usr/bin/gcc",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
launch.json
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "enter program name, for example ${workspaceFolder}/a.out",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}
Page 24
arith.c
#define PY_SSIZE_T_CLEAN
#includestatic PyObject *add(PyObject *self, PyObject *args)
{
int x, y, sts;
if (!PyArg_ParseTuple(args, "ii", &x, &y))
return NULL;
sts = x + y;
return PyLong_FromLong(sts);
}static PyMethodDef AddMethods[] = {
{"add", add, METH_VARARGS, "add two numbers"},
{NULL, NULL, 0, NULL} // sentinel
};static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"arith",
"C library for sum",
-1,
AddMethods};PyMODINIT_FUNC PyInit_arith(void)
{
return PyModule_Create(&addmodule);
}
tasks.json
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc-10 build active file",
"command": "/usr/bin/gcc-10",
"args": [
"-fdiagnostics-color=always",
"-g",
"-shared",
"${file}",
"-o",
"arith.so",
"-I/usr/local/include/python3.11"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
c_cpp_properties.json
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/usr/local/include/**"
],"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c17",
"cppStandard": "gnu++14",
"intelliSenseMode": "linux-gcc-arm"
}
],
"version": 4
}
test.py
import arith
print(arith.add(1,2))
print(dir(arith))
Page 30
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
},
{
"name": "(gdb) Attach",
"type": "cppdbg",
"request": "attach",
"program": "/usr/local/bin/python3.11",
"processId": "${command:pickProcess}",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
Page 38
hello.c
#include <stdio.h>
int main(int argc, char **argv)
{
printf("Hello C World\n");
return 0;
}
tasks.json
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: cl.exe build active file",
"command": "cl.exe",
"args": [
"/Zi",
"/EHsc",
"/nologo",
"/Fe${fileDirname}\\${fileBasenameNoExtension}.exe",
"${file}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$msCompile"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
Page 30
Change mike.james in the quoted paths to your own user name
arith.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
static PyObject *add(PyObject *self, PyObject *args)
{
int x, y, sts;
if (!PyArg_ParseTuple(args, "ii", &x, &y))
return NULL;
sts = x + y;
return PyLong_FromLong(sts);
}
static PyMethodDef AddMethods[] = {
{"add", add, METH_VARARGS, "add two numbers"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"arith",
"C library for sum",
-1,
AddMethods};
PyMODINIT_FUNC PyInit_arith(void)
{
return PyModule_Create(&addmodule);
}
tasks.json
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: cl.exe build active file",
"command": "cl.exe",
"args": [
"/Zi",
"/EHsc",
"/nologo",
"/IC:/Users/mike.james/AppData/Local/Programs/Python/Python311/include",
"${file}",
"/link /dll /OUT:arith.pyd /LIBPATH:C:/Users/mike.james/AppData/Local/Programs/Python/Python311/libs"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$msCompile"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "(Windows) Attach",
"type": "cppvsdbg",
"request": "attach",
"processId": "${command:pickProcess}",
"symbolSearchPath": "C:/Users/mike.james/AppData/Local/Programs/Python/Python-3.11.4",
"sourceFileMap":{"D:/a/1/s/":"C:/Users/mike.james/AppData/Local/Programs/Python/Python311"},
},
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
}
]
}
c_cpp_properties.json
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/**",
"C:/Users/mike.james/AppData/Local/Programs/Python/Python311/include/"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"windowsSdkVersion": "10.0.22000.0",
"compilerPath": "cl.exe",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "windows-msvc-x64"
}
],
"version": 4
}
import arith
print(arith.add(1,2))
print(dir(arith))
Page 44
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "(Windows) Attach",
"type": "cppvsdbg",
"request": "attach",
"processId": "${command:pickProcess}",
},
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
}
]
}
Page 53
#define PY_SSIZE_T_CLEAN
#include <Python.h>
static PyObject * add(PyObject *self, PyObject *args)
{
int x, y, sts;
if (!PyArg_ParseTuple(args, "ii", &x, &y))
return NULL;
sts = x+y;
return PyLong_FromLong(sts);
}
static PyMethodDef AddMethods[] = {
{"add", add, METH_VARARGS, "add two numbers"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"arith",
"C library for sum",
-1,
AddMethods
};
PyMODINIT_FUNC PyInit_arith(void) {
return PyModule_Create(&addmodule);
}
Page 54 and on
Arith.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
static PyObject * Pi(PyObject *self, PyObject *args)
{
int m, n;
double pi,s;
if (!PyArg_ParseTuple(args, "ii", &m, &n))
return NULL;
pi=0;
for(int k=m;k<n;k++){
s=1;
if(k%2==0)s=-1;
pi=pi+s/(2*k-1);
}
return PyFloat_FromDouble(4*pi);
}
static PyMethodDef AddMethods[] = {
{"myPi", Pi, METH_VARARGS, "Compute Pi"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"Pi",
"C library to compute Pi",
-1,
AddMethods
};
PyMODINIT_FUNC PyInit_Pi(void) {
return PyModule_Create(&addmodule);
}
tasks.json LINUX
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc-10 build active file",
"command": "/usr/bin/gcc-10",
"args": [
"-fdiagnostics-color=always",
"-g",
"-shared",
"${file}",
"-o",
"Pi.so",
"-I/usr/local/include/python3.11"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
c_cpp_properties.json LINUX
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/usr/local/include/**"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c17",
"cppStandard": "gnu++14",
"intelliSenseMode": "linux-gcc-arm"
}
],
"version": 4
}
launch.json LINUX
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
},
{
"name": "(gdb) Attach",
"type": "cppdbg",
"request": "attach",
"program": "/usr/local/bin/python3.11",
"processId": "${command:pickProcess}",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
tasks.json WINDOWS - CHANGE USER IN PATH
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: cl.exe build active file",
"command": "cl.exe",
"args": [
"/Zi",
"/EHsc",
"/nologo",
"/IC:/Users/mike.james/AppData/Local/Programs/Python/Python311/include",
"${file}",
"/link /dll /OUT:arith.pyd /LIBPATH:C:/Users/mike.james/AppData/Local/Programs/Python/Python311/libs"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$msCompile"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
c_cpp_properties.json WINDOWS CHANGE USER IN PATH
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/**",
"C:/Users/mike.james/AppData/Local/Programs/Python/Python311/include/"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"windowsSdkVersion": "10.0.22000.0",
"compilerPath": "cl.exe",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "windows-msvc-x64"
}
],
"version": 4
}
launch.json WINDOWS CHANGE USER IN PATH
{
"version": "0.2.0",
"configurations": [
{
"name": "(Windows) Attach",
"type": "cppvsdbg",
"request": "attach",
"processId": "${command:pickProcess}",
"symbolSearchPath": "C:/Users/mike.james/AppData/Local/Programs/Python/Python-3.11.4",
"sourceFileMap":{"D:/a/1/s/":"C:/Users/mike.james/AppData/Local/Programs/Python/Python311"},
},
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
}
]
}
Py.py
import time
def myPi(m,n):
pi=0
for k in range(m,n+1):
s= 1 if k%2 else -1
pi += s / (2 * k - 1)
return 4*pi
if __name__ == '__main__':
N=10000000
t1=time.perf_counter()
pi=myPi(1,N)
t2=time.perf_counter()
print((t2-t1)*1000)
print(pi)
Py1.py
import Pi
import time
if __name__ == '__main__':
N=10000000
t1=time.perf_counter()
pi=Pi.myPi(1,N)
t2=time.perf_counter()
print((t2-t1)*1000)
print(pi)
Page 57
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
static PyObject* exampleFunction(PyObject *self, PyObject *args)
{
//example function code
}
static PyMethodDef AddMethods[] = {
{"exampleFunction", exampleFunction, METH_VARARGS, "an example"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"example",
"C library to test API",
-1,
AddMethods
};
PyMODINIT_FUNC PyInit_example(void) {
return PyModule_Create(&addmodule);
}
tasks.json LINUX
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc-10 build active file",
"command": "/usr/bin/gcc-10",
"args": [
"-fdiagnostics-color=always",
"-g",
"-shared",
"${file}",
"-o",
"example.so",
"-I/usr/local/include/python3.11"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
launch.json LINUX
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
},
{
"name": "(gdb) Attach",
"type": "cppdbg",
"request": "attach",
"program": "/usr/local/bin/python3.11",
"processId": "${command:pickProcess}",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
c_cpp_properties.json LINUX
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/usr/local/include/**"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c17",
"cppStandard": "gnu++14",
"intelliSenseMode": "linux-gcc-arm"
}
],
"version": 4
}
tasks.json WINDOWS - CHANGE USER IN PATH
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: cl.exe build active file",
"command": "cl.exe",
"args": [
"/Zi",
"/EHsc",
"/nologo",
"/IC:/Users/mike.james/AppData/Local/Programs/Python/Python311/include",
"${file}",
"/link /dll /OUT:example.pyd /LIBPATH:C:/Users/mike.james/AppData/Local/Programs/Python/Python311/libs"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$msCompile"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
c_cpp_properties.json WINDOWS CHANGE USER IN PATH
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/**",
"C:/Users/mike.james/AppData/Local/Programs/Python/Python311/include/"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"windowsSdkVersion": "10.0.22000.0",
"compilerPath": "cl.exe",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "windows-msvc-x64"
}
],
"version": 4
}
launch.json WINDOWS CHANGE USER IN PATH
{
"version": "0.2.0",
"configurations": [
{
"name": "(Windows) Attach",
"type": "cppvsdbg",
"request": "attach",
"processId": "${command:pickProcess}",
"symbolSearchPath": "C:/Users/mike.james/AppData/Local/Programs/Python/Python-3.11.4",
"sourceFileMap":{"D:/a/1/s/":"C:/Users/mike.james/AppData/Local/Programs/Python/Python311"},
},
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
}
]
}
Page 72
example.c
This is the combined code from the chapter - the json files are as for example given ealier
#define PY_SSIZE_T_CLEAN
#include <Python.h>
static PyObject *stringRaw(PyObject *self, PyObject *args)
{
char *name;
if (!PyArg_ParseTuple(args, "s", &name))
return NULL;
printf("%s\n", name);
for (int i = 0; name[i]; i++)
{
printf("%02X ", (unsigned char)name[i]);
}
printf("\n");
Py_RETURN_NONE;
}
static PyObject *stringRawLen(PyObject *self, PyObject *args)
{
char *name;
Py_ssize_t len;
if (!PyArg_ParseTuple(args, "s#", &name, &len))
return NULL;
printf("%s\n", name);
printf("%d\n", (int)len);
for (int i = 0; i < len; i++)
{
printf("%02X ", (unsigned char)name[i]);
}
printf("\n");
Py_RETURN_NONE;
}
static PyObject *stringPBuffer(PyObject *self, PyObject *args)
{
Py_buffer myBuf;
if (!PyArg_ParseTuple(args, "s*", &myBuf))
return NULL;
char *myString = (char *)myBuf.buf;
printf("%s\n", myString);
for (int i = 0; i < myBuf.len; i++)
{
printf("%02X ", (unsigned char)myString[i]);
}
printf("\n");
PyBuffer_Release(&myBuf);
Py_RETURN_NONE;
}
static PyObject *stringEncode(PyObject *self, PyObject *args)
{
char *name = NULL;
if (!PyArg_ParseTuple(args, "es", "cp1252", &name))
return NULL;
printf("%s \n", name);
for (int i = 0; name[i]; i++)
{
printf("%02X ", (unsigned char)name[i]);
}
printf("\n");
PyMem_Free(name);
Py_RETURN_NONE;
}
static PyObject *stringEncode2(PyObject *self, PyObject *args)
{
char *name = NULL;
Py_ssize_t len;
if (!PyArg_ParseTuple(args, "es#", "utf-16", &name, &len))
return NULL;
printf("%s \n", name);
for (int i = 0; i < len; i++)
{
printf("%02X ", (unsigned char)name[i]);
}
printf("\n");
PyMem_Free(name);
Py_RETURN_NONE;
}
static PyObject *stringEncodeAllocate(PyObject *self,
PyObject *args)
{
Py_ssize_t len = 25;
char *name = malloc(sizeof(char) * (len + 1));
if (!PyArg_ParseTuple(args, "es#", "cp1252", &name, &len))
return NULL;
printf("%d\n", (int)len);
printf("%s \n", name);
for (int i = 0; i < len; i++)
{
printf("%02X ", (unsigned char)name[i]);
}
printf("\n");
free(name);
Py_RETURN_NONE;
}
static PyObject *sequenceElements(PyObject *self, PyObject *args)
{
int number;
double x, y;
char *name = NULL;
if (!PyArg_ParseTuple(args, "(idds)", &number, &x, &y, &name))
return NULL;
printf("%d %f %f %s \n", number, x, y, name);
Py_RETURN_NONE;
}
static PyMethodDef AddMethods[] = {
{"stringRaw", stringRaw, METH_VARARGS, "an example"},
{"stringRawLen", stringRawLen, METH_VARARGS, "an example"},
{"stringPBuffer", stringPBuffer, METH_VARARGS, "an example"},
{"stringEncode", stringEncode, METH_VARARGS, "an example"},
{"stringEncode2", stringEncode2, METH_VARARGS, "an example"},
{"stringEncodeAllocate", stringEncodeAllocate, METH_VARARGS, "an example"},
{"sequenceElements", sequenceElements, METH_VARARGS, "an example"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"example",
"C library to test API",
-1,
AddMethods};
PyMODINIT_FUNC PyInit_example(void)
{
return PyModule_Create(&addmodule);
}
test.py
import example
example.stringRaw("Hello World")
example.stringRawLen("Hello \0 World")
example.stringPBuffer("Hello \0 World")
example.stringEncode("Hello World")
example.stringEncode("\u2020")
example.stringEncode2("Hello World")
example.stringEncodeAllocate("Hello World")
example.sequenceElements((2,1.2,1.3,"test"))
Page 81
example.c
This is the combined code from the chapter - the json files are as for example given ealier
#define PY_SSIZE_T_CLEAN
#include <Python.h>
static PyObject *retInt(PyObject *self, PyObject *args)
{
int value = -1;
return Py_BuildValue("I", value);
}
static PyObject *strTostr(PyObject *self, PyObject *args)
{
char *name = "Brian";
return Py_BuildValue("s", name);
}
static PyObject *strTostr2(PyObject *self, PyObject *args)
{
char name[] = " Brian";
name[0] = 0xCE;
name[1] = 0x94;
return Py_BuildValue("s", name);
}
static PyObject *strTostrLen(PyObject *self, PyObject *args)
{
char name[] = " Brian";
Py_ssize_t len = 5;
name[0] = 0xCE;
name[1] = 0x94;
return Py_BuildValue("s#", name, len);
}
static PyObject *strTobytesLen(PyObject *self, PyObject *args)
{
char name[] = " Brian";
Py_ssize_t len = 5;
name[0] = 0xCE;
name[1] = 0x94;
return Py_BuildValue("y#", name, len);
}
static PyObject *wcharTostrLen(PyObject *self, PyObject *args)
{
wchar_t name[] = L" Brian";
Py_ssize_t len = 5;
name[0] = 0x0394;
return Py_BuildValue("u#", name, len);
}
static PyObject *wcharTostrLen2(PyObject *self, PyObject *args)
{
wchar_t name[] = L" Brian";
Py_ssize_t len = 5;
name[0] = 0xD83E;
name[1] = 0xDD10;
return Py_BuildValue("u#", name, len);
}
static PyObject *retTuple(PyObject *self, PyObject *args)
{
int number = 42;
double x = 1.2, y = 1.1;
char *name = "brian";
return Py_BuildValue("(isdd)", number, name, x, y);
}
static PyObject *retList(PyObject *self, PyObject *args)
{
int number = 42;
double x = 1.2, y = 1.1;
char *name = "brian";
return Py_BuildValue("[isdd]", number, name, x, y);
}
static PyObject *retDict(PyObject *self, PyObject *args)
{
int number = 42;
double x = 1.2, y = 1.1;
char *name = "brian";
return Py_BuildValue("{sisssdsd}", "first", number,"second", name,"x", x,"y", y);
}
static PyMethodDef AddMethods[] = {
{"retInt", retInt, METH_VARARGS, "an example"},
{"strTostr", strTostr, METH_VARARGS, "an example"},
{"strTostr2", strTostr2, METH_VARARGS, "an example"},
{"strTostrLen", strTostrLen, METH_VARARGS, "an example"},
{"strTobytesLen", strTobytesLen, METH_VARARGS, "an example"},
{"wcharTostrLen", wcharTostrLen, METH_VARARGS, "an example"},
{"wcharTostrLen2", wcharTostrLen2, METH_VARARGS, "an example"},
{"retTuple", retTuple, METH_VARARGS, "an example"},
{"retList", retList, METH_VARARGS, "an example"},
{"retDict", retDict, METH_VARARGS, "an example"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"example",
"C library to test API",
-1,
AddMethods};
PyMODINIT_FUNC PyInit_example(void)
{
return PyModule_Create(&addmodule);
}
test.py
import example
print(example.retInt())
print(example.strTostr())
print(example.strTostr2())
print(example.strTostrLen())
print(example.strTobytesLen())
print(example.wcharTostrLen())
#print(example.wcharTostrLen2())
print(example.retTuple())
print(example.retList())
print(example.retDict())
print("end")
Page 96
example.c
This is the combined code from the chapter - the json files are as for example given ealier
#define PY_SSIZE_T_CLEAN
#include <Python.h>
static PyObject *Attributes1(PyObject *self, PyObject *args)
{
PyObject *myObject;
if (!PyArg_ParseTuple(args, "O", &myObject))
return NULL;
PyObject *attribName = Py_BuildValue("s", "myAttribute1");
PyObject *myAtt1 = PyObject_GetAttr(myObject, attribName);
Py_XDECREF(attribName);
return myAtt1;
}
static PyObject *displayAttributes(PyObject *self, PyObject *args)
{
PyObject *myObject;
PyObject *myString;
if (!PyArg_ParseTuple(args, "OO", &myObject, &myString))
return NULL;
PyObject *myAtt1 = PyObject_GetAttr(myObject, myString);
if (PyUnicode_Check(myAtt1))
{
const char *mytext = PyUnicode_AsUTF8(myAtt1);
printf("%s\n", mytext);
}
if (PyLong_Check(myAtt1))
{
int myValue = PyLong_AsLong(myAtt1);
printf("%d\n", myValue);
}
return myAtt1;
}
static PyObject *Attributes2(PyObject *self, PyObject *args)
{
PyObject *myObject;
if (!PyArg_ParseTuple(args, "O", &myObject))
return NULL;
PyObject *newValue = PyLong_FromLong(42);
if (PyObject_SetAttrString(myObject, "myAttribute1", newValue))
return NULL;
Py_RETURN_NONE;
}
static PyObject *Attributes3(PyObject *self, PyObject *args)
{
PyObject *myObject;
if (!PyArg_ParseTuple(args, "O", &myObject))
return NULL;
if (PyObject_HasAttrString(myObject, "myAttribute1"))
{
PyObject *myAtt1 = PyObject_GetAttrString(myObject, "myAttribute1");
if (PyLong_Check(myAtt1))
{
int myValue = PyLong_AsLong(myAtt1);
printf("%d\n", myValue);
}
}
Py_RETURN_NONE;
}
static PyObject *Attributes4(PyObject *self, PyObject *args)
{
PyObject *myObject;
if (!PyArg_ParseTuple(args, "O", &myObject))
return NULL;
PyObject *main = PyImport_AddModule("__main__");
PyObject *maindict = PyModule_GetDict(main);
PyObject *myclass = PyDict_GetItemString(maindict, "myClass");
if (PyObject_IsInstance(myObject, myclass))
{
PyObject *myAtt1 = PyObject_GetAttrString(myObject, "myAttribute1");
if (PyLong_Check(myAtt1))
{
int myValue = PyLong_AsLong(myAtt1);
printf("%d\n", myValue);
}
Py_XDECREF(myAtt1);
}
Py_RETURN_NONE;
}
static PyMethodDef AddMethods[] = {
{"Attributes1", Attributes1, METH_VARARGS, "an example"},
{"displayAttributes", displayAttributes, METH_VARARGS, "an example"},
{"Attributes2", Attributes2, METH_VARARGS, "an example"},
{"Attributes3", Attributes3, METH_VARARGS, "an example"},
{"Attributes4", Attributes4, METH_VARARGS, "an example"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"example",
"C library to test API",
-1,
AddMethods};
PyMODINIT_FUNC PyInit_example(void)
{
return PyModule_Create(&addmodule);
}
test.py
import example
class myClass:
myAttribute1=10
myAttribute2="Brian"
myInstance=myClass()
print(example.Attributes1(myInstance))
value=example.displayAttributes(myInstance,"myAttribute1")
print(value)
value=example.displayAttributes(myInstance,"myAttribute2")
print(value)
example.Attributes2(myInstance)
print(myInstance.myAttribute1)
example.Attributes3(myInstance)
example.Attributes4(myInstance)
Page 113
example.c
This is the combined code from the chapter - the json files are as for example given ealier
#define PY_SSIZE_T_CLEAN
#include <Python.h>
static PyObject *tuple1(PyObject *self, PyObject *args)
{
PyObject *myTuple = PyTuple_New(10);
for (int i = 0; i < 10; i++)
{
PyObject *item = PyLong_FromLong(i);
PyTuple_SET_ITEM(myTuple, i, item);
}
return myTuple;
}
static PyObject *list1(PyObject *self, PyObject *args)
{
PyObject *mylist = PyList_New(10);
for (int i = 0; i < 10; i++)
{
PyObject *item = PyLong_FromLong(i);
PyList_SetItem(mylist, i, item);
}
return mylist;
}
static PyObject *list2(PyObject *self, PyObject *args)
{
PyObject *itemlist = PyList_New(0);
for (int i = 0; i < 10; i++)
{
PyObject *item = PyLong_FromLong(i);
PyList_Append(itemlist, PyLong_FromLong(i));
Py_DECREF(PyList_GetItem(itemlist, i));
}
return itemlist;
}
static PyObject *dict1(PyObject *self, PyObject *args)
{
PyObject *mydict = PyDict_New();
PyObject *val = PyLong_FromLong(42333);
PyObject *key = PyUnicode_DecodeUTF8("Item0", 5, NULL);
PyDict_SetItem(mydict, key, val);
Py_DECREF(val);
Py_DECREF(key);
return mydict;
}
static PyObject *tuple2(PyObject *self, PyObject *args)
{
PyObject *myTuple;
if (!PyArg_ParseTuple(args, "O", &myTuple))
return NULL;
int myarray[10];
for (int i = 0; i < 10; i++)
{
PyObject *item = PyTuple_GetItem(myTuple, i);
myarray[i] = PyLong_AsLong(item);
printf("%d ", myarray[i]);
}
printf("\n");
Py_RETURN_NONE;
}
static PyObject *list3(PyObject *self, PyObject *args)
{
PyObject *mylist;
if (!PyArg_ParseTuple(args, "O", &mylist))
return NULL;
PyObject *itemlist = PyList_New(4);
PyList_SetItem(itemlist, 0, PyLong_FromLong(10));
PyList_SetItem(itemlist, 1, PyLong_FromLong(11));
PyList_SetItem(itemlist, 2, PyLong_FromLong(12));
PyList_SetItem(itemlist, 3, PyLong_FromLong(13));
PyList_SetSlice(mylist, 3, 5, itemlist);
Py_DECREF(itemlist);
Py_RETURN_NONE;
}
static PyObject *listIterator(PyObject *self, PyObject *args)
{
PyObject *mylist;
if (!PyArg_ParseTuple(args, "O", &mylist))
return NULL;
PyObject *myIter = PyObject_GetIter(mylist);
printf("%d ", PyLong_AsLong((PyIter_Next(myIter))));
printf("%d ", PyLong_AsLong((PyIter_Next(myIter))));
printf("%d ", PyLong_AsLong((PyIter_Next(myIter))));
printf("%d ", PyLong_AsLong((PyIter_Next(myIter))));
printf("\n");
Py_DECREF(myIter);
Py_RETURN_NONE;
}
static PyObject *listFor(PyObject *self, PyObject *args)
{
PyObject *myList;
if (!PyArg_ParseTuple(args, "O", &myList))
return NULL;
PyObject *myIter = PyObject_GetIter(myList);
for (PyObject *item = PyIter_Next(myIter); item != NULL; item = PyIter_Next(myIter))
{
printf("%d ", PyLong_AsLong(item));
Py_DECREF(item);
}
printf("\n");
Py_DECREF(myIter);
Py_RETURN_NONE;
}
static PyObject *listWhile(PyObject *self, PyObject *args)
{
PyObject *myList;
if (!PyArg_ParseTuple(args, "O", &myList))
return NULL;
PyObject *myIter = PyObject_GetIter(myList);
PyObject *item;
while (item = PyIter_Next(myIter))
{
printf("%d ", PyLong_AsLong(item));
Py_DECREF(item);
}
Py_DECREF(myIter);
printf("\n");
Py_DECREF(myIter);
Py_RETURN_NONE;
}
static PyMethodDef AddMethods[] = {
{"tuple1", tuple1, METH_VARARGS, "an example"},
{"list1", list1, METH_VARARGS, "an example"},
{"list2", list2, METH_VARARGS, "an example"},
{"dict1", dict1, METH_VARARGS, "an example"},
{"tuple2", tuple2, METH_VARARGS, "an example"},
{"list3", list3, METH_VARARGS, "an example"},
{"listIterator", listIterator, METH_VARARGS, "an example"},
{"listFor", listFor, METH_VARARGS, "an example"},
{"listWhile", listWhile, METH_VARARGS, "an example"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"example",
"C library to test API",
-1,
AddMethods};
PyMODINIT_FUNC PyInit_example(void)
{
return PyModule_Create(&addmodule);
}
test.py
import example
import sys
#print(example.tuple1())
print(example.list1())
myList=example.list2()
print(myList)
print("ref count=",sys.getrefcount(myList[0])-1)
myDict=example.dict1()
print(myDict)
print("ref count=",sys.getrefcount(myDict["Item0"])-1)
print("ref count=",sys.getrefcount(myDict)-1)
myTuple=example.tuple1()
print(myTuple)
example.tuple2(myTuple)
mylist=[0,1,2,3,4,5,6,7,8,9]
example.list3(mylist)
print(myList)
mylist=[0,1,2,3,4,5,6,7,8,9]
example.listIterator(mylist)
example.listFor(mylist)
example.listWhile(mylist)
Page 118
exception.py
total=0
class MyNumberError(ArithmeticError):
def __init__(self, message,):
super(MyNumberError, self).__init__(message)
def myFunc(x,y):
global total
total=total+1
print("in myFunc")
raise MyNumberError("Number not 42")
return 1
result=myFunc(1,1)
try:
result=myFunc(1,1)
except MyNumberError:
print("Can't divide by zero")
total=total-1
# result=myFunc(1,1)
#print(result)
print(total)
Page 123
example.c
This is the combined code from the chapter - the json files are as for example given ealier
#define PY_SSIZE_T_CLEAN
#include <Python.h>
static PyObject *exception1(PyObject *self, PyObject *args)
{
PyObject *x = PyLong_FromLong(1);
PyObject *y = PyLong_FromLong(0);
PyObject *ans = PyNumber_TrueDivide(x, y);
if (ans == NULL)
{
Py_DECREF(x);
Py_DECREF(y);
return NULL;
}
PyObject *z = PyLong_FromLong(1);
PyObject *ans2 = PyNumber_TrueDivide(x, z);
Py_DECREF(x);
Py_DECREF(y);
Py_DECREF(z);
return ans;
}
static PyObject *exception2(PyObject *self, PyObject *args)
{
PyErr_SetString(PyExc_ZeroDivisionError, "A Dummy divide error has occurred");
return NULL;
}
static PyObject *myCustomException;
static PyObject *exception3(PyObject *self, PyObject *args)
{
PyErr_SetString(myCustomException, "A Custom error has occurred");
return NULL;
}
static PyObject *exception4(PyObject *self, PyObject *args)
{
PyObject *x = PyLong_FromLong(1);
PyObject *y = PyLong_FromLong(0);
PyObject *ans = PyNumber_TrueDivide(x, y);
if (ans == NULL)
{
PyErr_Clear();
PyObject *z = PyLong_FromLong(1);
ans = PyNumber_TrueDivide(x, z);
Py_DECREF(z);
}
Py_DECREF(x);
Py_DECREF(y);
return ans;
}
static PyObject *exception5(PyObject *self, PyObject *args)
{
PyObject *x = PyLong_FromLong(1);
PyObject *y = PyLong_FromLong(0);
PyObject *ans = PyNumber_TrueDivide(x, y);
if (PyErr_Occurred() != NULL)
{
if(PyErr_ExceptionMatches(PyExc_ZeroDivisionError)){
PyErr_Clear();
PyObject *z = PyLong_FromLong(1);
ans = PyNumber_TrueDivide(x, z);
Py_DECREF(z);
}
}
Py_DECREF(x);
Py_DECREF(y);
return ans;
}
static PyObject *list1(PyObject *self, PyObject *args)
{
PyObject *myList;
if (!PyArg_ParseTuple(args, "O", &myList))
return NULL;
printf("myList %ld\n", Py_REFCNT(myList));
PyObject *temp = PyList_GetItem(myList, 0);
printf("item zero %ld\n", Py_REFCNT(temp));
PyObject *myList2 = PySequence_InPlaceConcat(myList, myList);
temp = PyList_GetItem(myList, 0);
temp = PyList_GetItem(myList, 0);
printf("myList %ld\n", Py_REFCNT(myList));
printf("item zero %ld\n", Py_REFCNT(temp));
Py_RETURN_NONE;
}
static PyMethodDef AddMethods[] = {
{"exception1", exception1, METH_VARARGS, "an example"},
{"exception2", exception2, METH_VARARGS, "an example"},
{"exception3", exception3, METH_VARARGS, "an example"},
{"exception4", exception4, METH_VARARGS, "an example"},
{"exception5", exception5, METH_VARARGS, "an example"},
{"list1", list1, METH_VARARGS, "an example"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"example",
"C library to test API",
-1,
AddMethods};
PyMODINIT_FUNC PyInit_example(void)
{
PyObject *m;
m = PyModule_Create(&addmodule);
if (m == NULL)
return NULL;
myCustomException = PyErr_NewException("example.myCustomException", NULL, NULL);
if (PyModule_AddObjectRef(m, "myCustomException", myCustomException) < 0)
{
Py_CLEAR(myCustomException);
Py_DECREF(m);
return NULL;
}
return m;
}
test.py
import example
import gc
#ans=example.exception1()
#print(ans)
#try:
# ans=example.exception2()
#except ZeroDivisionError as err:
# print(err)
try:
ans=example.exception3()
except example.myCustomException as err:
print(err)
try:
ans=example.exception4()
except ZeroDivisionError as err:
print(err)
print(ans)
try:
ans=example.exception5()
except ZeroDivisionError as err:
print(err)
print(ans)
print(gc.get_objects())
gc.collect()
myList=[257,1,2,3,4,5,6,7,8,9]
gc.collect()
example.list1(myList)
print(myList)
Page 148
example.c
This is the combined code from the chapter - the json files are as for example given ealier
#define PY_SSIZE_T_CLEAN
#include <Python.h>
static PyObject *bytes1(PyObject *self, PyObject *args)
{
char *myString = "Hello World";
PyObject *myBytes = PyBytes_FromString(myString);
return myBytes;
}
static PyObject *bytes2(PyObject *self, PyObject *args)
{
PyObject *myBytes;
if (!PyArg_ParseTuple(args, "O", &myBytes))
return NULL;
Py_ssize_t len = PyBytes_Size(myBytes);
for (int i = 1; i < len; i++)
{
PyObject *item = PySequence_GetItem(myBytes, i);
char c = (char)PyLong_AsLong(item);
printf("%X ", c);
}
printf("\n");
PyObject *myByteArray = PyByteArray_FromStringAndSize(PyBytes_AsString(myBytes), PyBytes_Size(myBytes));
char *HelloMessage = "Hello World";
PyObject *insert = PyByteArray_FromStringAndSize(HelloMessage, strlen(HelloMessage));
PySequence_SetSlice(myByteArray, 3, 7, insert);
return myByteArray;
}
static PyObject *string1(PyObject *self, PyObject *args)
{
PyObject *uni1 = PyUnicode_New(10, 255);
PyUnicode_Fill(uni1, 0, 10, 120);
PyUnicode_WriteChar(uni1, 0, 72);
return uni1;
}
static PyObject *string2(PyObject *self, PyObject *args)
{
PyObject *myString = PyUnicode_FromString("Spam, Spam, Spam, Spam… Lovely Spam! Wonderful Spam!");
int len = PyUnicode_GET_LENGTH(myString);
Py_UCS4 *buf = PyMem_Malloc(sizeof(Py_UCS4) * (len + 1));
PyUnicode_AsUCS4(myString, buf, 100, 1);
for (int i = 0; buf[i]; i++)
{
printf("%04X ", buf[i]);
}
PyMem_Free(buf);
printf("\n\n");
buf = PyUnicode_AsUCS4Copy(myString);
for (int i = 0; buf[i]; i++)
{
printf("%04X ", buf[i]);
}
printf("\n\n");
PyMem_Free(buf);
Py_DECREF(myString);
Py_RETURN_NONE;
}
static PyObject *string3(PyObject *self, PyObject *args)
{
PyObject *myString = PyUnicode_FromString("Spam, Spam, Spam, Spam… Lovely Spam! Wonderful Spam!");
int len = PyUnicode_GET_LENGTH(myString);
PyObject *substr = PyUnicode_FromString("Lovely");
Py_ssize_t pos = PyUnicode_Find(myString, substr, 0, len, 1);
printf("position of Lovely = %ld\n", pos);
pos = PyUnicode_FindChar(myString, 0x0000006D, 0, len, 1);
printf("position of first m %ld\n", pos);
substr = PyUnicode_FromString("Spam");
Py_ssize_t result = PyUnicode_Tailmatch(myString, substr, 0, len, -1);
printf("prefix match %ld\n", result);
substr = PyUnicode_FromString("Spam");
result = PyUnicode_Contains(myString, substr);
printf("Contains Spam %ld\n", result);
Py_ssize_t count = PyUnicode_Count(myString, substr, 0, len);
printf("Count of how many spam(s) %ld\n", count);
PyObject *test = PyUnicode_FromString("Spam");
result = PyUnicode_Compare(substr, test);
printf("compare to Spam %ld\n", result);
result = PyUnicode_CompareWithASCIIString(substr, "Spam");
printf("compare to Spam %ld\n", result);
PyObject *logic = PyUnicode_RichCompare(substr, test, Py_EQ);
if (Py_IsTrue(logic))
{
printf("Strings are equal\n");
}
else
{
printf("Strings are not equal\n");
}
Py_RETURN_NONE;
}
static PyObject *string4(PyObject *self, PyObject *args)
{
PyObject *myString = PyUnicode_FromString("Spam, Spam, Spam, Spam . . .Lovely Spam! Wonderful Spam!");
PyObject *bytesUTF8 = PyUnicode_AsUTF8String(myString);
PyObject *bytesUTF16 = PyUnicode_AsUTF16String(myString);
PyObject *bytesUTF32 = PyUnicode_AsUTF32String(myString);
Py_ssize_t len = PyBytes_Size(bytesUTF32);
for (int i = 0; i < len; i++)
{
PyObject *item = PySequence_GetItem(bytesUTF32, i);
int c = PyLong_AsLong(item);
printf("%02X ", c);
}
printf("\n");
char *buffer;
PyBytes_AsStringAndSize(bytesUTF32, &buffer, &len);
PyObject *decodeStr = PyUnicode_DecodeUTF32(buffer, len, NULL, NULL);
return decodeStr;
}
static PyObject *string5(PyObject *self, PyObject *args)
{
PyObject *myString = PyUnicode_New(1, 1114111);
PyUnicode_WriteChar(myString, 0, 0x2020);
PyObject *myBytes = PyUnicode_AsEncodedString(myString, "cp1252", NULL);
char *buffer;
Py_ssize_t len;
PyBytes_AsStringAndSize(myBytes, &buffer, &len);
printf("%X \n", buffer[0]);
printf("%s \n", buffer);
Py_DECREF(myBytes);
return myString;
}
static PyObject *string6(PyObject *self, PyObject *args)
{
PyObject *myString = PyUnicode_FromString("† Spam, Spam, Spam, Spam . . .Lovely Spam! Wonderful Spam!");
PyObject *myBytes = PyUnicode_AsEncodedString(myString, "raw_unicode_escape", NULL);
Py_DECREF(myString);
return myBytes;
}
static PyMethodDef AddMethods[] = {
{"bytes1", bytes1, METH_VARARGS, "an example"},
{"bytes2", bytes2, METH_VARARGS, "an example"},
{"string1", string1, METH_VARARGS, "an example"},
{"string2", string2, METH_VARARGS, "an example"},
{"string3", string3, METH_VARARGS, "an example"},
{"string4", string4, METH_VARARGS, "an example"},
{"string5", string5, METH_VARARGS, "an example"},
{"string6", string6, METH_VARARGS, "an example"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"example",
"C library to test API",
-1,
AddMethods};
PyMODINIT_FUNC PyInit_example(void)
{
return PyModule_Create(&addmodule);
}
test.py
import example
mybytes=example.bytes1()
print(mybytes)
print()mybytes=example.bytes2(b"My long message")
print(mybytes)print(example.string1())
print()
example.string2()
print()
example.string3()
print()
print(example.string4())print()
result=example.string5()
print(result)
print()
result=example.string6()
print(result)
Page 157
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
static PyObject *exampleFunction(PyObject *self, PyObject *args)
{
// example function code
}
static PyMethodDef AddMethods[] = {
{"exampleFunction", exampleFunction, METH_VARARGS, "an example"},
{NULL, NULL, 0, NULL} // sentinel
};
static PyObject *myFunc(PyObject *self, PyObject *args)
{
printf("hello world\n");
Py_RETURN_NONE;
}
static PyObject *myFunc2(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
for (int i = 0; i < nargs; i++)
{
const char *myString = PyUnicode_AsUTF8(args[i]);
printf("%s\n", myString);
}
Py_ssize_t nKwds = PyTuple_Size(kwnames);
for (int i = 0; i < nKwds; i++)
{
const char *myValue = PyUnicode_AsUTF8(args[i + nargs]);
const char *myKeyword = PyUnicode_AsUTF8(PyTuple_GetItem(kwnames, i));
printf("Keyword = %s, Value = %s \n", myKeyword, myValue);
}
Py_RETURN_NONE;
}
static PyMethodDef myFunc_def = {
"myFunc",
myFunc,
METH_VARARGS,
"the doc string"};
static PyMethodDef myFunc2_def = {
"myFunc2",
(PyCFunction)myFunc2,
METH_FASTCALL | METH_KEYWORDS,
"the doc string"};
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;
// Add a int
PyObject *myValue = PyLong_FromLong(42);
PyModule_AddObject(m, "myValue", myValue);
// Add a list
PyObject *myList = PyList_New(0);
PyModule_AddObject(m, "myList", myList);
// Add a function
PyObject *myPyFun = PyCFunction_New(&myFunc_def, m);
PyModule_AddObject(m, "myFunc1", myPyFun);
// Add a fastcall function
PyObject *myPyFun2 = PyCFunction_New(&myFunc2_def, m);
PyModule_AddObject(m, "myFunc2", myPyFun2);
//Add a function in another module
PyObject *math=PyImport_ImportModule("math");
PyObject *mathdict = PyModule_GetDict(math);
PyObject *myFunction = PyDict_GetItemString(mathdict, "sqrt");
PyModule_AddObject(m, "myFunc3", myFunction);
return m;
}
test.py
import example
print("module constant",example.myValue)
example.myValue=43
print("module constant",example.myValue)
print(example.myList)
example.myList.append("spam")
print(example.myList)
print(example.myFunc1())
example.myFunc2("Hello","World",MyKeyWord="myValue")
print(example.myFunc3(2))
print(example.myFunc3.__name__)
Page 160
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
int exec(PyObject *m)
{
PyObject *myValue = PyLong_FromLong(42);
PyModule_AddObject(m, "myValue", myValue);
return 0;
}
PyObject *create(PyObject *spec, PyModuleDef *def)
{
PyObject *res=PyObject_GetAttrString(spec,"origin");
printf("%s\n",PyUnicode_AsUTF8(res));
PyObject *m= PyModule_New("example");
return m;
}
PyModuleDef_Slot twoPhase[] = {
{Py_mod_create, create},
{Py_mod_exec, exec},
{0, 0}};
static struct PyModuleDef myModuledef = {
PyModuleDef_HEAD_INIT,
"example",
"C library to test API",
0,
NULL,
twoPhase};
PyMODINIT_FUNC PyInit_example(void)
{
return PyModuleDef_Init(&myModuledef);
}
test.py
import example
print(example.myValue)
Page 164
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
struct myData
{
int count;
char name[20];
};
static struct myData myModuleData = {42, "spam"};
static PyObject *myFunc(PyObject *self, PyObject *args)
{
printf("module data %d , %s\n", myModuleData.count, myModuleData.name);
myModuleData.count++;
struct myData *myModData = (struct myData *)PyModule_GetState(self);
printf("module data %d , %s\n", myModData->count, myModData->name);
myModData->count++;
Py_RETURN_NONE;
}
static PyMethodDef myFunc_def = {
"myFunc",
myFunc,
METH_VARARGS,
"the doc string"};
int exec(PyObject *m)
{
struct myData *myModData = (struct myData *)PyModule_GetState(m);
myModData->count = 42;
strcpy(myModData->name, "spam");
PyObject *myValue = PyLong_FromLong(42);
PyModule_AddObject(m, "myValue", myValue);
PyObject *myPyFun = PyCFunction_New(&myFunc_def, m);
PyModule_AddObject(m, "myFunc", myPyFun);
return 0;
}
PyObject *create(PyObject *spec, PyModuleDef *def)
{
PyObject *res = PyObject_GetAttrString(spec, "origin");
printf("%s\n", PyUnicode_AsUTF8(res));
PyObject *m = PyModule_New("example");
return m;
}
void freeModule(void *m){
struct myData *myModData = (struct myData *)PyModule_GetState(m);
PyMem_Free(myModData);
}
PyModuleDef_Slot twoPhase[] = {
{Py_mod_create, create},
{Py_mod_exec, exec},
{0, 0}};
static struct PyModuleDef myModuledef = {
PyModuleDef_HEAD_INIT,
"example",
"C library to test API",
sizeof(struct myData),
NULL,
twoPhase,
NULL,
NULL,
freeModule};
PyMODINIT_FUNC PyInit_example(void)
{
return PyModuleDef_Init(&myModuledef);
}
test.py
import example
example.myFunc()
example.myFunc()
Page 172
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
static PyTypeObject MyType1 = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "example.myObject",
.tp_doc = PyDoc_STR("My Custom object"),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION
};
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;
}
import example
myclass=example.MyClass
print(myclass)
print(myclass.__dict__)
Page 173
#define PY_SSIZE_T_CLEAN
#include <Python.h>
static PyTypeObject MyType1 = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "example.myObject",
.tp_doc = PyDoc_STR("My Custom object"),
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_basicsize = sizeof(PyObject),
.tp_itemsize = 0,
.tp_new = PyType_GenericNew,
};
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
myInst=example.MyClass()
print(myInst)
print(myInst.__dir__())
print(myInst.__sizeof__())
Page 176
exampe.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
static PyObject *myFunc(PyObject *self, PyObject *args)
{
printf("hello world\n");
Py_RETURN_NONE;
}
static PyMethodDef myFunc_def = {
"myFunc",
myFunc,
METH_VARARGS,
"the doc string"};
static PyTypeObject MyType1 = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "example.myObject",
.tp_doc = PyDoc_STR("My Custom object"),
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_basicsize = sizeof(PyObject),
.tp_itemsize = 0,
.tp_new = PyType_GenericNew,
};
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 *mydict = PyDict_New();
PyObject *val = PyLong_FromLong(42);
PyDict_SetItemString(mydict, "myValue", val);
Py_DECREF(val);
PyObject *myPyFun = PyCFunction_New(&myFunc_def, (PyObject *)&MyType1);
PyDict_SetItemString(mydict, "myFunc", myPyFun);
MyType1.tp_dict = mydict;
int res = PyType_Ready(&MyType1);
PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);
return m;
}
test.py
import example
example.MyClass.myFunc()
myInst=example.MyClass()
myInst.myFunc()
Page 177
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <stddef.h>
typedef struct
{
PyObject_HEAD
PyObject *dict;
} MyObject;
static PyObject *myFunc(PyObject *self, PyObject *args)
{
printf("hello world\n");
Py_RETURN_NONE;
}
static PyMethodDef myFunc_def = {
"myFunc",
myFunc,
METH_VARARGS,
"the doc string"};
static PyTypeObject MyType1 = {
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_dictoffset=offsetof(MyObject, dict),
.tp_new = PyType_GenericNew,
};
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 *mydict = PyDict_New();
PyObject *val = PyLong_FromLong(42);
PyDict_SetItemString(mydict, "myValue", val);
Py_DECREF(val);
PyObject *myPyFun = PyCFunction_New(&myFunc_def, (PyObject *)&MyType1);
PyDict_SetItemString(mydict, "myFunc", myPyFun);
MyType1.tp_dict = mydict;
int res = PyType_Ready(&MyType1);
PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);
return m;
}
test.py
import example
example.MyClass.myFunc()
myInst=example.MyClass()
myInst.myFunc()
myInst.myValue=43
print(myInst.myValue)
myInst.myVal1=42
print(myInst.myVal1)
Page 180
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <stddef.h>
typedef struct
{
PyObject_HEAD
PyObject *dict;
} MyObject;
static PyObject *myFunc(PyObject *self, PyObject *args)
{
printf("hello world\n");
Py_RETURN_NONE;
}
static PyMethodDef myFunc_def = {
"myFunc",
myFunc,
METH_VARARGS,
"the doc string"};
static PyObject *Custom_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
MyObject *self;
self = (MyObject *)type->tp_alloc(type, 0);
return (PyObject *)self;
}
static int Custom_init(MyObject *self, PyObject *args, PyObject *kwds)
{
PyObject *myPyFunc = PyCFunction_New(&myFunc_def, (PyObject *)self);
PyObject *myPyMethod = PyInstanceMethod_New(myPyFunc);
int res = PyObject_SetAttrString((PyObject *)self, "MyMethod", myPyMethod);
return 0;
}
static PyTypeObject MyType1 = {
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_dictoffset = offsetof(MyObject, dict),
.tp_new = Custom_new,
.tp_init = (initproc)Custom_init,
};
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 *mydict = PyDict_New();
PyObject *val = PyLong_FromLong(42);
PyDict_SetItemString(mydict, "myValue", val);
Py_DECREF(val);
PyObject *myPyFun = PyCFunction_New(&myFunc_def, (PyObject *)&MyType1);
PyDict_SetItemString(mydict, "myFunc", myPyFun);
MyType1.tp_dict = mydict;
int res = PyType_Ready(&MyType1);
PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);
return m;
}
test.py
import example
example.MyClass.myFunc()
myInst=example.MyClass()
myInst.myFunc()
myInst.myValue=43
print(myInst.myValue)
myInst.myVal1=42
print(myInst.myVal1)
myInst.MyMethod()
Page 185
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"};
static PyMethodDef myFunc_def = {
"myFunc",
(PyCFunction)myFunc,
METH_VARARGS,
"the doc string"};
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,
};
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 *mydict=PyDict_New();
PyObject *myMethodDesc = PyDescr_NewMethod(&MyType1, &myFunc_def);
int res = PyDict_SetItemString(mydict, "MyMethod", myMethodDesc);
PyObject *myMemberDesc = PyDescr_NewMember(&MyType1, &myMemberdef);
res = PyDict_SetItemString(mydict, "MyVar", myMemberDesc);
MyType1.tp_dict=mydict;
res = PyType_Ready(&MyType1);
PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);
return m;
}
test.py
import example
myInst=example.MyClass()
myInst.MyMethod()
myInst.MyVar=43
print(myInst.MyVar)
Page 187
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 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,
};
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
myInst=example.MyClass()
myInst.MyMethod()
myInst.MyVar=43
print(myInst.MyVar)
Page 190
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <stddef.h>
#include "structmember.h"
typedef struct
{
PyObject_HEAD
PyObject *myProp;
} MyObject;
static PyObject *getVal(MyObject *self, void *extra)
{
return Py_NewRef(self->myProp);
}
int setVal(MyObject *self, PyObject *val, void *extra)
{
Py_XSETREF(self->myProp, Py_XNewRef(val));
return 0;
}
static PyGetSetDef myGetSetDef[] = {
{"myProperty", (getter)getVal, (setter)setVal, "Example get set", NULL},
{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_getset = myGetSetDef,
};
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
myInst=example.MyClass()
myInst.myProperty=42
print(myInst.myProperty)
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)
Page 226
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#if defined(_WIN32) || defined(_WIN64)
#define SCALE 1000
#else
#define SCALE 1
#endif
static PyObject *Pi(PyObject *self, PyObject *args)
{
int m, n;
double pi, s;
if (!PyArg_ParseTuple(args, "ii", &m, &n))
return NULL;
Py_BEGIN_ALLOW_THREADS
pi = 0;
for (int k = m; k < n; k++)
{
s = 1;
if (k % 2 == 0)
s = -1;
pi = pi + s / (2 * k - 1);
}
sleep(5 * SCALE);
Py_END_ALLOW_THREADS
return PyFloat_FromDouble(4 * pi);
}
static PyMethodDef AddMethods[] = {
{"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"Pi",
"C library to compute Pi",
-1,
AddMethods};
PyMODINIT_FUNC PyInit_Pi(void)
{
return PyModule_Create(&addmodule);
}
test.py
import Pi
import time
import concurrent.futures
N=10000000
with concurrent.futures.ThreadPoolExecutor() as executor:
t1=time.perf_counter()
f1 = executor.submit(Pi.myPi,1,N)
t2=time.perf_counter()
print("do some additional work")
print("waiting for result")
print(f1.result())
print((t2-t1)*1000)
Page 227 LINUX VERSION
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
typedef struct
{
int m;
int n;
} range;
static pthread_mutex_t mutex;
static double PiShared = 0;
void *PartPi(void *args)
{
range *range1 = (range *)args;
double pi, s;
int m = range1->m;
int n = range1->n;
pi = 0;
for (int k = m; k < n; k++)
{
s = 1;
if (k % 2 == 0)
s = -1;
pi = pi + s / (2 * k - 1);
}
pthread_mutex_lock(&mutex);
PiShared += pi;
pthread_mutex_unlock(&mutex);
return NULL;
}
static PyObject *Pi(PyObject *self, PyObject *args)
{
int m, n;
if (!PyArg_ParseTuple(args, "ii", &m, &n))
return NULL;
Py_BEGIN_ALLOW_THREADS
range range1 = {m, n / 2};
range range2 = {n / 2 + 1, n};
int threadId;
pthread_mutex_init(&mutex, NULL);
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, PartPi, &range1);
pthread_create(&thread2, NULL, PartPi, &range2);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
Py_END_ALLOW_THREADS return PyFloat_FromDouble(4 * PiShared);
}
static PyMethodDef AddMethods[] = {
{"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"Pi",
"C library to compute Pi",
-1,
AddMethods};
PyMODINIT_FUNC PyInit_Pi(void)
{
return PyModule_Create(&addmodule);
}
Page 229 WINDOWS VERSION
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <Windows.h>
typedef struct
{
int m;
int n;
} range;
static int *Mutex;
static double PiShared = 0;
int PartPi(void *args)
{
range *range1 = (range *)args;
double pi, s;
int m = range1->m;
int n = range1->n;
pi = 0;
for (int k = m; k < n; k++)
{
s = 1;
if (k % 2 == 0)
s = -1;
pi = pi + s / (2 * k - 1);
}
WaitForSingleObject(Mutex, INFINITE);
PiShared += pi;
ReleaseMutex(Mutex);
return 0;
}
static PyObject *Pi(PyObject *self, PyObject *args)
{
int m, n;
int *handles[2];
if (!PyArg_ParseTuple(args, "ii", &m, &n))
return NULL;
Py_BEGIN_ALLOW_THREADS
range range1 = {m, n / 2};
range range2 = {n / 2 + 1, n};
int threadId;
Mutex = CreateMutex(NULL, FALSE, NULL);
handles[0] = CreateThread(NULL, 0, PartPi, (void *)&range1, 0, &threadId);
handles[1] = CreateThread(NULL, 0, PartPi, (void *)&range2, 0, &threadId);
WaitForMultipleObjects(2, handles, TRUE, INFINITE);
Py_END_ALLOW_THREADS return PyFloat_FromDouble(4 * PiShared);
}
static PyMethodDef AddMethods[] = {
{"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"Pi",
"C library to compute Pi",
-1,
AddMethods};
PyMODINIT_FUNC PyInit_Pi(void)
{
PyObject *m = PyModule_Create(&addmodule);
if (m == NULL)
return NULL;
return m;
}
test.py
import Pi
import time
import concurrent.futures
N=10000000
with concurrent.futures.ThreadPoolExecutor() as executor:
t1=time.perf_counter()
f1 = executor.submit(Pi.myPi,1,N)
t2=time.perf_counter()
print("do some additional work")
print("waiting for result")
print(f1.result())
print((t2-t1)*1000)
Page 231 LINUX VERSION
example.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
typedef struct
{
int m;
int n;
} range;
static pthread_mutex_t mutex;
static double PiShared = 0;
void *PartPi(void *args)
{
range *range1 = (range *)args;
double pi, s;
int m = range1->m;
int n = range1->n;
pi = 0;
for (int k = m; k < n; k++)
{
s = 1;
if (k % 2 == 0)
s = -1;
pi = pi + s / (2 * k - 1);
}
pthread_mutex_lock(&mutex);
PiShared += pi;
pthread_mutex_unlock(&mutex);
PyGILState_STATE gstate = PyGILState_Ensure();
PyObject *pimod = PyImport_AddModule("Pi");
PyObject *myVal = PyObject_GetAttrString(pimod, "myValue");
PyObject *myOne = PyLong_FromLong(1);
PyObject *myInc = PyNumber_Add(myVal, myOne);
int res = PyObject_SetAttrString((PyObject *)pimod, "myValue", myInc);
PyGILState_Release(gstate);
return NULL;
}
static PyObject *Pi(PyObject *self, PyObject *args)
{
int m, n;
if (!PyArg_ParseTuple(args, "ii", &m, &n))
return NULL;
Py_BEGIN_ALLOW_THREADS
range range1 = {m, n / 2};
range range2 = {n / 2 + 1, n};
pthread_mutex_init(&mutex, NULL);
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, PartPi, &range1);
pthread_create(&thread2, NULL, PartPi, &range2);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
Py_END_ALLOW_THREADS return PyFloat_FromDouble(4 * PiShared);
}
static PyMethodDef AddMethods[] = {
{"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"Pi",
"C library to compute Pi",
-1,
AddMethods};
PyMODINIT_FUNC PyInit_Pi(void)
{
PyObject *m = PyModule_Create(&addmodule);
if (m == NULL)
return NULL;
PyObject *myValue = PyLong_FromLong(42);
PyModule_AddObject(m, "myValue", myValue);
return m;
}
Page 233 WINDOWS VERSION
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <Windows.h>
typedef struct
{
int m;
int n;
} range;
static int *Mutex;
static double PiShared = 0;
int PartPi(void *args)
{
range *range1 = (range *)args;
double pi, s;
int m = range1->m;
int n = range1->n;
pi = 0;
for (int k = m; k < n; k++)
{
s = 1;
if (k % 2 == 0)
s = -1;
pi = pi + s / (2 * k - 1);
}
WaitForSingleObject(Mutex, INFINITE);
PiShared += pi;
ReleaseMutex(Mutex);
PyGILState_STATE gstate = PyGILState_Ensure();
PyObject *pimod = PyImport_AddModule("Pi");
PyObject *myVal = PyObject_GetAttrString(pimod, "myValue");
PyObject *myOne = PyLong_FromLong(1);
PyObject *myInc = PyNumber_Add(myVal, myOne);
int res = PyObject_SetAttrString((PyObject *)pimod, "myValue", myInc);
PyGILState_Release(gstate);
return 0;
}
static PyObject *Pi(PyObject *self, PyObject *args)
{
int m, n;
int *handles[2];
if (!PyArg_ParseTuple(args, "ii", &m, &n))
return NULL;
Py_BEGIN_ALLOW_THREADS
range range1 = {m, n / 2};
range range2 = {n / 2 + 1, n};
int threadId;
Mutex = CreateMutex(NULL, FALSE, NULL);
handles[0] = CreateThread(NULL, 0, PartPi, (void *)&range1, 0, &threadId);
handles[1] = CreateThread(NULL, 0, PartPi, (void *)&range2, 0, &threadId);
WaitForMultipleObjects(2, handles, TRUE, INFINITE);
Py_END_ALLOW_THREADS
return PyFloat_FromDouble(4 * PiShared);
}
static PyMethodDef AddMethods[] = {
{"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"Pi",
"C library to compute Pi",
-1,
AddMethods};
PyMODINIT_FUNC PyInit_Pi(void)
{
PyObject *m = PyModule_Create(&addmodule);
if (m == NULL)
return NULL;
PyObject *myValue = PyLong_FromLong(42);
PyModule_AddObject(m, "myValue", myValue);
return m;
}
test.py
import Pi
import time
import concurrent.futures
N=10000000
print("go")
with concurrent.futures.ThreadPoolExecutor() as executor:
t1=time.perf_counter()
f1 = executor.submit(Pi.myPi,1,N)
print("do some additional work")
print("waiting for result")
r=f1.result()
t2=time.perf_counter()
print((t2-t1)*1000)
print(r)
print(Pi.myValue)
Page 238 LINUX VERSION
#define PY_SSIZE_T_CLEAN
#include <Python.h>
typedef struct
{
int m;
int n;
double Pi;
PyObject *cb;
}State;
int Ccb(void *args)
{
State *state = (State *)args;
printf("C callback called \n");
PyObject *pi=Py_BuildValue("(f)",state->Pi);
PyObject_CallObject((PyObject *)(state->cb), pi);
free(state);
return 0;
}
static void *ComputePi(void *args)
{
State *state = (State *)args;
double pi, s;
pi = 0;
for (int k = state->m; k < state->n; k++)
{
s = 1;
if (k % 2 == 0)
s = -1;
pi = pi + s / (2 * k - 1);
}
state->Pi=4*pi;
int res = Py_AddPendingCall(Ccb, (void *)state);
return NULL;
}
static PyObject *Pi(PyObject *self, PyObject *args)
{
int m, n;
PyObject *cb;
if (!PyArg_ParseTuple(args, "iiO:myPi", &m, &n, &cb))
return NULL;
State *state=(State*)malloc(sizeof(State));
state->m = m;
state->n = n;
state->cb = cb;
state->Pi = 0;
pthread_t thread1;
pthread_create(&thread1, NULL, ComputePi, (void *)state);
return PyLong_FromLong(0);
}
static PyMethodDef AddMethods[] = {
{"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"Pi",
"C library to compute Pi",
-1,
AddMethods};
PyMODINIT_FUNC PyInit_Pi(void)
{
PyObject *m = PyModule_Create(&addmodule);
if (m == NULL)
return NULL;
return m;
}
Page 238 WINDOWS VERSION
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <Windows.h>
typedef struct
{
int m;
int n;
double Pi;
PyObject *cb;
}State;
int Ccb(void *args)
{
State *state = (State *)args;
printf("C callback called \n");
PyObject *pi=Py_BuildValue("(f)",state->Pi);
PyObject_CallObject((PyObject *)state->cb, pi);
free(state);
return 0;
}
static int ComputePi(void *args)
{
State *state = (State *)args;
double pi, s;
pi = 0;
for (int k = state->m; k < state->n; k++)
{
s = 1;
if (k % 2 == 0)
s = -1;
pi = pi + s / (2 * k - 1);
}
state->Pi=4*pi;
int res = Py_AddPendingCall(Ccb, (void *)state);
return 0;
}
static PyObject *Pi(PyObject *self, PyObject *args)
{
int m, n;
PyObject *cb;
if (!PyArg_ParseTuple(args, "iiO:myPi", &m, &n, &cb))
return NULL;
State *state=(State*)malloc(sizeof(State));
state->m = m;
state->n = n;
state->cb = cb;
state->Pi = 0;
int threadId;
int *handle = CreateThread(NULL, 0, ComputePi, (void *)state, 0, &threadId);
return PyLong_FromLong(0);
}
static PyMethodDef AddMethods[] = {
{"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"Pi",
"C library to compute Pi",
-1,
AddMethods};
PyMODINIT_FUNC PyInit_Pi(void)
{
PyObject *m = PyModule_Create(&addmodule);
if (m == NULL)
return NULL;
return m;
}
test.py
import Pi
import time
def myCallback(pi):
t2 = time.perf_counter()
print((t2-t1)*1000)
print("python callback")
print(pi)
N = 10000000
t1 = time.perf_counter()
Pi.myPi(1,N,myCallback)
print("do some additional work")
while True:
time.sleep(0.00001)
Page 244
main.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
int main(int argc, char *argv[])
{
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print('Today is', ctime(time()))\n");
Py_FinalizeEx();
return 0;
}
tasks.json WINDOWS
Change user name
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: cl.exe build active file",
"command": "cl.exe",
"args": [
"/Zi",
"/EHsc",
"/nologo",
"/IC:/Users/mike.james/AppData/Local/Programs/Python/Python311/include",
"/Fe${fileDirname}\\${fileBasenameNoExtension}.exe",
"${file}",
"/link /LIBPATH:C:/Users/mike.james/AppData/Local/Programs/Python/Python311/libs"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$msCompile"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
tasks.json LINUX
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc-10 build active file",
"command": "/usr/bin/gcc-10",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}",
"-I/usr/local/include/python3.11",
"-L/usr/local/lib/python3.11/config-3.11-arm-linux-gnueabihf",
"-L/usr/local/lib",
"-Xlinker",
"-export-dynamic",
"-lpython3.11",
"-lpthread",
"-ldl",
"-lutil",
"-lm",
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
Page 247
#define PY_SSIZE_T_CLEAN
#include <Python.h>
static PyObject *Pi(PyObject *self, PyObject *args)
{
int m, n;
double pi, s;
if (!PyArg_ParseTuple(args, "ii", &m, &n))
return NULL;
pi = 0;
for (int k = m; k < n; k++)
{
s = 1;
if (k % 2 == 0)
s = -1;
pi = pi + s / (2 * k - 1);
}
return PyFloat_FromDouble(4 * pi);
};
static PyMethodDef AddMethods[] = {
{"myPi", Pi, METH_VARARGS, "Compute Pi"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"Pi",
"C library to compute Pi",
-1,
AddMethods};
PyMODINIT_FUNC PyInit_Pi(void)
{
return PyModule_Create(&addmodule);
};
int main(int argc, char *argv[])
{
PyImport_AppendInittab("Pi", &PyInit_Pi);
Py_Initialize();
PyRun_SimpleString("import Pi\n"
"print(Pi.myPi(1,1000))\n");
Py_FinalizeEx();
return 0;
}
Page 248
#define PY_SSIZE_T_CLEAN
#include <Python.h>
int main(int argc, char *argv[])
{
Py_Initialize();
PyObject *math =PyImport_ImportModule("math");
PyObject *mathdict = PyModule_GetDict(math);
PyObject *myFunction = PyDict_GetItemString(mathdict, "sqrt");
PyObject *args = Py_BuildValue("(I)", 2);
PyObject *result = PyObject_Call(myFunction, args, NULL);
double res=PyFloat_AS_DOUBLE(result);
printf("%f\n",res);
PyRun_SimpleString(
"import math\n"
"print(math.sqrt(2))\n");
Py_FinalizeEx();
return 0;
}
Page 249
#define PY_SSIZE_T_CLEAN
#include <Python.h>
int main(int argc, char *argv[])
{
Py_Initialize();
{
PyObject *g = PyDict_New();
PyObject *l = PyDict_New();
PyDict_SetItemString(l, "X", PyLong_FromLong(2));
PyDict_SetItemString(l, "Y", PyLong_FromLong(2));
PyObject *pyResult = PyRun_String("X+Y", Py_eval_input, g, l);
int Cresult = PyLong_AS_LONG(pyResult);
printf("%d\n", Cresult);
}
{
PyObject *g = PyDict_New();
PyObject *l = PyDict_New();
PyObject *math = PyImport_ImportModule("math");
PyDict_SetItemString(g, "math", math);
PyObject *pyResult = PyRun_String("math.sqrt(2)", Py_eval_input, g, l);
double res2 = PyFloat_AS_DOUBLE(pyResult);
printf("%f\n", res2);
}
Py_FinalizeEx();
return 0;
}
Page 250
#define PY_SSIZE_T_CLEAN
#include <Python.h>
static PyObject *Pi(PyObject *self, PyObject *args)
{
int m, n;
double pi, s;
if (!PyArg_ParseTuple(args, "ii", &m, &n))
return NULL;
pi = 0;
for (int k = m; k < n; k++)
{
s = 1;
if (k % 2 == 0)
s = -1;
pi = pi + s / (2 * k - 1);
}
return PyFloat_FromDouble(4 * pi);
}
static PyMethodDef AddMethods[] = {
{"myPi", Pi, METH_VARARGS, "Compute Pi"},
{NULL, NULL, 0, NULL} // sentinel
};
static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"Pi",
"C library to compute Pi",
-1,
AddMethods};
PyMODINIT_FUNC PyInit_Pi(void)
{
return PyModule_Create(&addmodule);
}
int main(int argc, char *argv[])
{
PyImport_AppendInittab("Pi", &PyInit_Pi);
Py_Initialize();
PyObject *main = PyImport_AddModule("__main__");
PyObject *mainDict = PyModule_GetDict(main);
FILE *fp = fopen("Pi.py", "r");
PyObject *l = PyDict_New();
PyObject *result = PyRun_File(fp, "Pi.py", Py_file_input, mainDict, l);
Py_FinalizeEx();
return 0;
}
Pi,py
import Pi
import time
N=10000000
t1=time.perf_counter()
pi=Pi.myPi(1,N)
t2=time.perf_counter()
print((t2-t1)*1000)
print(pi)