/* Example extension module for Python 3.0 Copyright (C) 2009 Arc Riley This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "Python.h" #include "structmember.h" static PyMethodDef example_Methods[] = { { NULL, NULL }, // sentinel }; static struct PyModuleDef example_Module = { PyModuleDef_HEAD_INIT, "example", // m_name "Example's PyDoc", // m_doc -1, // m_size example_Methods, // m_methods NULL, // m_reload NULL, // m_traverse NULL, // m_clear NULL // m_free }; static PyTypeObject Sample_Type; // see below typedef struct { PyObject_HEAD int value; } Sample_Object; /***************************************************************************\ every Python extension must have a function named PyInit_ | which is called on import and returns a new PyObject* for the module */ PyMODINIT_FUNC PyInit_example(void) { PyObject* module; // this "fills in" some of the empty fields of the new type // and otherwise prepares it for use. Checking this before // creating new module object for a clean exit if it fails. if (PyType_Ready(&Sample_Type) < 0) return NULL; // create new module object from PyModuleDef module = PyModule_Create(&example_Module); if (!module) return NULL; // incref Sample's type object and add it to the module Py_INCREF(&Sample_Type); PyModule_AddObject(module, "Sample", (PyObject*) &Sample_Type); return module; } /***************************************************************************\ every extension type needs a tp_new function which allocates and returns | new objects of that type. a pointer to this function is stored in the | PyTypeObject->tp_new field at the bottom of this file */ PyObject* Sample_New(PyTypeObject* type, PyObject* args, PyObject* kwds) { Sample_Object* self; static char* kwlist[] = {0}; self = (Sample_Object*) type->tp_alloc(type, 0); // this raises an error if any arguments or keywords are provided // see http://docs.python.org/3.0/c-api/arg.html if (!PyArg_ParseTupleAndKeywords(args, kwds, ":Sample", kwlist)) return NULL; return (PyObject*) self; } /***************************************************************************\ this is our only method, example.Sample.demo(). all it does is copies | the provided argument (which must be type 'int') to self->value | note that demo is added to the type object through Sample_Methods below */ static PyObject* demo(Sample_Object* self, PyObject* args) { // see http://docs.python.org/3.0/c-api/arg.html if (!PyArg_ParseTuple(args, "i:demo", &self->value)) return NULL; Py_RETURN_NONE; } static PyMethodDef Sample_Methods[] = { { "demo", // ml_name (PyCFunction) demo, // ml_meth METH_VARARGS, // ml_flags PyDoc_STR("demo() PyDoc string"), // ml_doc }, { NULL, NULL }, // sentinel }; static PyMemberDef Sample_Members[] = { { "value", // name T_INT, // type offsetof(Sample_Object, value), // offset READONLY, // flags PyDoc_STR("value PyDoc string"), // doc }, { NULL }, // sentinel }; static PyTypeObject Sample_Type = { PyVarObject_HEAD_INIT(NULL, 0) "example.Sample", // tp_name sizeof(Sample_Object), // tp_basicsize 0, // tp_itemsize 0, // tp_dealloc 0, // tp_print 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr 0, // tp_as_number 0, // tp_as_sequence 0, // tp_as_mapping 0, // tp_hash 0, // tp_call 0, // tp_str 0, // tp_getattro 0, // tp_setattro 0, // tp_as_buffer Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, // tp_flags PyDoc_STR("Sample PyDocs"), // tp_doc 0, // tp_traverse 0, // tp_clear 0, // tp_richcompare 0, // tp_weaklistoffset 0, // tp_iter 0, // tp_iternext Sample_Methods, // tp_methods Sample_Members, // tp_members 0, // tp_getset 0, // tp_base 0, // tp_dict 0, // tp_descr_get 0, // tp_descr_set 0, // tp_dictoffset 0, // tp_init 0, // tp_alloc Sample_New, // tp_new 0, // tp_free 0, // tp_is_gc };