mirror of
https://github.com/python/cpython.git
synced 2025-11-02 03:01:58 +00:00
bpo-33201: Modernize "Extension types" doc (GH-6337)
* bpo-33201: Modernize "Extension types" doc * Split tutorial and other topics * Some small fixes * Address some review comments * Rename noddy* to custom* and shoddy to sublist * Fix markup
This commit is contained in:
parent
b405752dab
commit
1d80a56173
15 changed files with 1730 additions and 1914 deletions
39
Doc/includes/custom.c
Normal file
39
Doc/includes/custom.c
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#include <Python.h>
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
/* Type-specific fields go here. */
|
||||
} CustomObject;
|
||||
|
||||
static PyTypeObject CustomType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
.tp_name = "custom.Custom",
|
||||
.tp_doc = "Custom objects",
|
||||
.tp_basicsize = sizeof(CustomObject),
|
||||
.tp_itemsize = 0,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
||||
.tp_new = PyType_GenericNew,
|
||||
};
|
||||
|
||||
static PyModuleDef custommodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
.m_name = "custom",
|
||||
.m_doc = "Example module that creates an extension type.",
|
||||
.m_size = -1,
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit_custom(void)
|
||||
{
|
||||
PyObject *m;
|
||||
if (PyType_Ready(&CustomType) < 0)
|
||||
return NULL;
|
||||
|
||||
m = PyModule_Create(&custommodule);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
|
||||
Py_INCREF(&CustomType);
|
||||
PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
|
||||
return m;
|
||||
}
|
||||
132
Doc/includes/custom2.c
Normal file
132
Doc/includes/custom2.c
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
#include <Python.h>
|
||||
#include "structmember.h"
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *first; /* first name */
|
||||
PyObject *last; /* last name */
|
||||
int number;
|
||||
} CustomObject;
|
||||
|
||||
static void
|
||||
Custom_dealloc(CustomObject *self)
|
||||
{
|
||||
Py_XDECREF(self->first);
|
||||
Py_XDECREF(self->last);
|
||||
Py_TYPE(self)->tp_free((PyObject *) self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Custom_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
CustomObject *self;
|
||||
self = (CustomObject *) type->tp_alloc(type, 0);
|
||||
if (self != NULL) {
|
||||
self->first = PyUnicode_FromString("");
|
||||
if (self->first == NULL) {
|
||||
Py_DECREF(self);
|
||||
return NULL;
|
||||
}
|
||||
self->last = PyUnicode_FromString("");
|
||||
if (self->last == NULL) {
|
||||
Py_DECREF(self);
|
||||
return NULL;
|
||||
}
|
||||
self->number = 0;
|
||||
}
|
||||
return (PyObject *) self;
|
||||
}
|
||||
|
||||
static int
|
||||
Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"first", "last", "number", NULL};
|
||||
PyObject *first = NULL, *last = NULL, *tmp;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
|
||||
&first, &last,
|
||||
&self->number))
|
||||
return -1;
|
||||
|
||||
if (first) {
|
||||
tmp = self->first;
|
||||
Py_INCREF(first);
|
||||
self->first = first;
|
||||
Py_XDECREF(tmp);
|
||||
}
|
||||
if (last) {
|
||||
tmp = self->last;
|
||||
Py_INCREF(last);
|
||||
self->last = last;
|
||||
Py_XDECREF(tmp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyMemberDef Custom_members[] = {
|
||||
{"first", T_OBJECT_EX, offsetof(CustomObject, first), 0,
|
||||
"first name"},
|
||||
{"last", T_OBJECT_EX, offsetof(CustomObject, last), 0,
|
||||
"last name"},
|
||||
{"number", T_INT, offsetof(CustomObject, number), 0,
|
||||
"custom number"},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
Custom_name(CustomObject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
if (self->first == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, "first");
|
||||
return NULL;
|
||||
}
|
||||
if (self->last == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, "last");
|
||||
return NULL;
|
||||
}
|
||||
return PyUnicode_FromFormat("%S %S", self->first, self->last);
|
||||
}
|
||||
|
||||
static PyMethodDef Custom_methods[] = {
|
||||
{"name", (PyCFunction) Custom_name, METH_NOARGS,
|
||||
"Return the name, combining the first and last name"
|
||||
},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyTypeObject CustomType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
.tp_name = "custom2.Custom",
|
||||
.tp_doc = "Custom objects",
|
||||
.tp_basicsize = sizeof(CustomObject),
|
||||
.tp_itemsize = 0,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
.tp_new = Custom_new,
|
||||
.tp_init = (initproc) Custom_init,
|
||||
.tp_dealloc = (destructor) Custom_dealloc,
|
||||
.tp_members = Custom_members,
|
||||
.tp_methods = Custom_methods,
|
||||
};
|
||||
|
||||
static PyModuleDef custommodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
.m_name = "custom2",
|
||||
.m_doc = "Example module that creates an extension type.",
|
||||
.m_size = -1,
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit_custom2(void)
|
||||
{
|
||||
PyObject *m;
|
||||
if (PyType_Ready(&CustomType) < 0)
|
||||
return NULL;
|
||||
|
||||
m = PyModule_Create(&custommodule);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
|
||||
Py_INCREF(&CustomType);
|
||||
PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
|
||||
return m;
|
||||
}
|
||||
183
Doc/includes/custom3.c
Normal file
183
Doc/includes/custom3.c
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
#include <Python.h>
|
||||
#include "structmember.h"
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *first; /* first name */
|
||||
PyObject *last; /* last name */
|
||||
int number;
|
||||
} CustomObject;
|
||||
|
||||
static void
|
||||
Custom_dealloc(CustomObject *self)
|
||||
{
|
||||
Py_XDECREF(self->first);
|
||||
Py_XDECREF(self->last);
|
||||
Py_TYPE(self)->tp_free((PyObject *) self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Custom_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
CustomObject *self;
|
||||
self = (CustomObject *) type->tp_alloc(type, 0);
|
||||
if (self != NULL) {
|
||||
self->first = PyUnicode_FromString("");
|
||||
if (self->first == NULL) {
|
||||
Py_DECREF(self);
|
||||
return NULL;
|
||||
}
|
||||
self->last = PyUnicode_FromString("");
|
||||
if (self->last == NULL) {
|
||||
Py_DECREF(self);
|
||||
return NULL;
|
||||
}
|
||||
self->number = 0;
|
||||
}
|
||||
return (PyObject *) self;
|
||||
}
|
||||
|
||||
static int
|
||||
Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"first", "last", "number", NULL};
|
||||
PyObject *first = NULL, *last = NULL, *tmp;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|UUi", kwlist,
|
||||
&first, &last,
|
||||
&self->number))
|
||||
return -1;
|
||||
|
||||
if (first) {
|
||||
tmp = self->first;
|
||||
Py_INCREF(first);
|
||||
self->first = first;
|
||||
Py_DECREF(tmp);
|
||||
}
|
||||
if (last) {
|
||||
tmp = self->last;
|
||||
Py_INCREF(last);
|
||||
self->last = last;
|
||||
Py_DECREF(tmp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyMemberDef Custom_members[] = {
|
||||
{"number", T_INT, offsetof(CustomObject, number), 0,
|
||||
"custom number"},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
Custom_getfirst(CustomObject *self, void *closure)
|
||||
{
|
||||
Py_INCREF(self->first);
|
||||
return self->first;
|
||||
}
|
||||
|
||||
static int
|
||||
Custom_setfirst(CustomObject *self, PyObject *value, void *closure)
|
||||
{
|
||||
PyObject *tmp;
|
||||
if (value == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
|
||||
return -1;
|
||||
}
|
||||
if (!PyUnicode_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"The first attribute value must be a string");
|
||||
return -1;
|
||||
}
|
||||
tmp = self->first;
|
||||
Py_INCREF(value);
|
||||
self->first = value;
|
||||
Py_DECREF(tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Custom_getlast(CustomObject *self, void *closure)
|
||||
{
|
||||
Py_INCREF(self->last);
|
||||
return self->last;
|
||||
}
|
||||
|
||||
static int
|
||||
Custom_setlast(CustomObject *self, PyObject *value, void *closure)
|
||||
{
|
||||
PyObject *tmp;
|
||||
if (value == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute");
|
||||
return -1;
|
||||
}
|
||||
if (!PyUnicode_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"The last attribute value must be a string");
|
||||
return -1;
|
||||
}
|
||||
tmp = self->last;
|
||||
Py_INCREF(value);
|
||||
self->last = value;
|
||||
Py_DECREF(tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyGetSetDef Custom_getsetters[] = {
|
||||
{"first", (getter) Custom_getfirst, (setter) Custom_setfirst,
|
||||
"first name", NULL},
|
||||
{"last", (getter) Custom_getlast, (setter) Custom_setlast,
|
||||
"last name", NULL},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
Custom_name(CustomObject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return PyUnicode_FromFormat("%S %S", self->first, self->last);
|
||||
}
|
||||
|
||||
static PyMethodDef Custom_methods[] = {
|
||||
{"name", (PyCFunction) Custom_name, METH_NOARGS,
|
||||
"Return the name, combining the first and last name"
|
||||
},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyTypeObject CustomType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
.tp_name = "custom3.Custom",
|
||||
.tp_doc = "Custom objects",
|
||||
.tp_basicsize = sizeof(CustomObject),
|
||||
.tp_itemsize = 0,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
.tp_new = Custom_new,
|
||||
.tp_init = (initproc) Custom_init,
|
||||
.tp_dealloc = (destructor) Custom_dealloc,
|
||||
.tp_members = Custom_members,
|
||||
.tp_methods = Custom_methods,
|
||||
.tp_getset = Custom_getsetters,
|
||||
};
|
||||
|
||||
static PyModuleDef custommodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
.m_name = "custom3",
|
||||
.m_doc = "Example module that creates an extension type.",
|
||||
.m_size = -1,
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit_custom3(void)
|
||||
{
|
||||
PyObject *m;
|
||||
if (PyType_Ready(&CustomType) < 0)
|
||||
return NULL;
|
||||
|
||||
m = PyModule_Create(&custommodule);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
|
||||
Py_INCREF(&CustomType);
|
||||
PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
|
||||
return m;
|
||||
}
|
||||
197
Doc/includes/custom4.c
Normal file
197
Doc/includes/custom4.c
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
#include <Python.h>
|
||||
#include "structmember.h"
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *first; /* first name */
|
||||
PyObject *last; /* last name */
|
||||
int number;
|
||||
} CustomObject;
|
||||
|
||||
static int
|
||||
Custom_traverse(CustomObject *self, visitproc visit, void *arg)
|
||||
{
|
||||
Py_VISIT(self->first);
|
||||
Py_VISIT(self->last);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
Custom_clear(CustomObject *self)
|
||||
{
|
||||
Py_CLEAR(self->first);
|
||||
Py_CLEAR(self->last);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
Custom_dealloc(CustomObject *self)
|
||||
{
|
||||
PyObject_GC_UnTrack(self);
|
||||
Custom_clear(self);
|
||||
Py_TYPE(self)->tp_free((PyObject *) self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Custom_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
CustomObject *self;
|
||||
self = (CustomObject *) type->tp_alloc(type, 0);
|
||||
if (self != NULL) {
|
||||
self->first = PyUnicode_FromString("");
|
||||
if (self->first == NULL) {
|
||||
Py_DECREF(self);
|
||||
return NULL;
|
||||
}
|
||||
self->last = PyUnicode_FromString("");
|
||||
if (self->last == NULL) {
|
||||
Py_DECREF(self);
|
||||
return NULL;
|
||||
}
|
||||
self->number = 0;
|
||||
}
|
||||
return (PyObject *) self;
|
||||
}
|
||||
|
||||
static int
|
||||
Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"first", "last", "number", NULL};
|
||||
PyObject *first = NULL, *last = NULL, *tmp;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|UUi", kwlist,
|
||||
&first, &last,
|
||||
&self->number))
|
||||
return -1;
|
||||
|
||||
if (first) {
|
||||
tmp = self->first;
|
||||
Py_INCREF(first);
|
||||
self->first = first;
|
||||
Py_DECREF(tmp);
|
||||
}
|
||||
if (last) {
|
||||
tmp = self->last;
|
||||
Py_INCREF(last);
|
||||
self->last = last;
|
||||
Py_DECREF(tmp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyMemberDef Custom_members[] = {
|
||||
{"number", T_INT, offsetof(CustomObject, number), 0,
|
||||
"custom number"},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
Custom_getfirst(CustomObject *self, void *closure)
|
||||
{
|
||||
Py_INCREF(self->first);
|
||||
return self->first;
|
||||
}
|
||||
|
||||
static int
|
||||
Custom_setfirst(CustomObject *self, PyObject *value, void *closure)
|
||||
{
|
||||
if (value == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
|
||||
return -1;
|
||||
}
|
||||
if (!PyUnicode_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"The first attribute value must be a string");
|
||||
return -1;
|
||||
}
|
||||
Py_INCREF(value);
|
||||
Py_CLEAR(self->first);
|
||||
self->first = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Custom_getlast(CustomObject *self, void *closure)
|
||||
{
|
||||
Py_INCREF(self->last);
|
||||
return self->last;
|
||||
}
|
||||
|
||||
static int
|
||||
Custom_setlast(CustomObject *self, PyObject *value, void *closure)
|
||||
{
|
||||
if (value == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute");
|
||||
return -1;
|
||||
}
|
||||
if (!PyUnicode_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"The last attribute value must be a string");
|
||||
return -1;
|
||||
}
|
||||
Py_INCREF(value);
|
||||
Py_CLEAR(self->last);
|
||||
self->last = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyGetSetDef Custom_getsetters[] = {
|
||||
{"first", (getter) Custom_getfirst, (setter) Custom_setfirst,
|
||||
"first name", NULL},
|
||||
{"last", (getter) Custom_getlast, (setter) Custom_setlast,
|
||||
"last name", NULL},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
Custom_name(CustomObject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return PyUnicode_FromFormat("%S %S", self->first, self->last);
|
||||
}
|
||||
|
||||
static PyMethodDef Custom_methods[] = {
|
||||
{"name", (PyCFunction) Custom_name, METH_NOARGS,
|
||||
"Return the name, combining the first and last name"
|
||||
},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyTypeObject CustomType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
.tp_name = "custom4.Custom",
|
||||
.tp_doc = "Custom objects",
|
||||
.tp_basicsize = sizeof(CustomObject),
|
||||
.tp_itemsize = 0,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
|
||||
.tp_new = Custom_new,
|
||||
.tp_init = (initproc) Custom_init,
|
||||
.tp_dealloc = (destructor) Custom_dealloc,
|
||||
.tp_traverse = (traverseproc) Custom_traverse,
|
||||
.tp_clear = (inquiry) Custom_clear,
|
||||
.tp_members = Custom_members,
|
||||
.tp_methods = Custom_methods,
|
||||
.tp_getset = Custom_getsetters,
|
||||
};
|
||||
|
||||
static PyModuleDef custommodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
.m_name = "custom4",
|
||||
.m_doc = "Example module that creates an extension type.",
|
||||
.m_size = -1,
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit_custom4(void)
|
||||
{
|
||||
PyObject *m;
|
||||
if (PyType_Ready(&CustomType) < 0)
|
||||
return NULL;
|
||||
|
||||
m = PyModule_Create(&custommodule);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
|
||||
Py_INCREF(&CustomType);
|
||||
PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
|
||||
return m;
|
||||
}
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
#include <Python.h>
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
/* Type-specific fields go here. */
|
||||
} noddy_NoddyObject;
|
||||
|
||||
static PyTypeObject noddy_NoddyType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"noddy.Noddy", /* tp_name */
|
||||
sizeof(noddy_NoddyObject), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
0, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_reserved */
|
||||
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, /* tp_flags */
|
||||
"Noddy objects", /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
0, /* tp_methods */
|
||||
0, /* 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 */
|
||||
PyType_GenericNew, /* tp_new */
|
||||
};
|
||||
|
||||
static PyModuleDef noddymodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"noddy",
|
||||
"Example module that creates an extension type.",
|
||||
-1,
|
||||
NULL, NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit_noddy(void)
|
||||
{
|
||||
PyObject* m;
|
||||
|
||||
if (PyType_Ready(&noddy_NoddyType) < 0)
|
||||
return NULL;
|
||||
|
||||
m = PyModule_Create(&noddymodule);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
|
||||
Py_INCREF(&noddy_NoddyType);
|
||||
PyModule_AddObject(m, "Noddy", (PyObject *)&noddy_NoddyType);
|
||||
return m;
|
||||
}
|
||||
|
|
@ -1,172 +0,0 @@
|
|||
#include <Python.h>
|
||||
#include "structmember.h"
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *first; /* first name */
|
||||
PyObject *last; /* last name */
|
||||
int number;
|
||||
} Noddy;
|
||||
|
||||
static void
|
||||
Noddy_dealloc(Noddy* self)
|
||||
{
|
||||
Py_XDECREF(self->first);
|
||||
Py_XDECREF(self->last);
|
||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
Noddy *self;
|
||||
|
||||
self = (Noddy *)type->tp_alloc(type, 0);
|
||||
if (self != NULL) {
|
||||
self->first = PyUnicode_FromString("");
|
||||
if (self->first == NULL) {
|
||||
Py_DECREF(self);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self->last = PyUnicode_FromString("");
|
||||
if (self->last == NULL) {
|
||||
Py_DECREF(self);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self->number = 0;
|
||||
}
|
||||
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
static int
|
||||
Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyObject *first=NULL, *last=NULL, *tmp;
|
||||
|
||||
static char *kwlist[] = {"first", "last", "number", NULL};
|
||||
|
||||
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
|
||||
&first, &last,
|
||||
&self->number))
|
||||
return -1;
|
||||
|
||||
if (first) {
|
||||
tmp = self->first;
|
||||
Py_INCREF(first);
|
||||
self->first = first;
|
||||
Py_XDECREF(tmp);
|
||||
}
|
||||
|
||||
if (last) {
|
||||
tmp = self->last;
|
||||
Py_INCREF(last);
|
||||
self->last = last;
|
||||
Py_XDECREF(tmp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static PyMemberDef Noddy_members[] = {
|
||||
{"first", T_OBJECT_EX, offsetof(Noddy, first), 0,
|
||||
"first name"},
|
||||
{"last", T_OBJECT_EX, offsetof(Noddy, last), 0,
|
||||
"last name"},
|
||||
{"number", T_INT, offsetof(Noddy, number), 0,
|
||||
"noddy number"},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
Noddy_name(Noddy* self)
|
||||
{
|
||||
if (self->first == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, "first");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (self->last == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, "last");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return PyUnicode_FromFormat("%S %S", self->first, self->last);
|
||||
}
|
||||
|
||||
static PyMethodDef Noddy_methods[] = {
|
||||
{"name", (PyCFunction)Noddy_name, METH_NOARGS,
|
||||
"Return the name, combining the first and last name"
|
||||
},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyTypeObject NoddyType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"noddy.Noddy", /* tp_name */
|
||||
sizeof(Noddy), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
(destructor)Noddy_dealloc, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_reserved */
|
||||
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 */
|
||||
"Noddy objects", /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
Noddy_methods, /* tp_methods */
|
||||
Noddy_members, /* tp_members */
|
||||
0, /* tp_getset */
|
||||
0, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
0, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
(initproc)Noddy_init, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
Noddy_new, /* tp_new */
|
||||
};
|
||||
|
||||
static PyModuleDef noddy2module = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"noddy2",
|
||||
"Example module that creates an extension type.",
|
||||
-1,
|
||||
NULL, NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit_noddy2(void)
|
||||
{
|
||||
PyObject* m;
|
||||
|
||||
if (PyType_Ready(&NoddyType) < 0)
|
||||
return NULL;
|
||||
|
||||
m = PyModule_Create(&noddy2module);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
|
||||
Py_INCREF(&NoddyType);
|
||||
PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
|
||||
return m;
|
||||
}
|
||||
|
|
@ -1,225 +0,0 @@
|
|||
#include <Python.h>
|
||||
#include "structmember.h"
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *first;
|
||||
PyObject *last;
|
||||
int number;
|
||||
} Noddy;
|
||||
|
||||
static void
|
||||
Noddy_dealloc(Noddy* self)
|
||||
{
|
||||
Py_XDECREF(self->first);
|
||||
Py_XDECREF(self->last);
|
||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
Noddy *self;
|
||||
|
||||
self = (Noddy *)type->tp_alloc(type, 0);
|
||||
if (self != NULL) {
|
||||
self->first = PyUnicode_FromString("");
|
||||
if (self->first == NULL) {
|
||||
Py_DECREF(self);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self->last = PyUnicode_FromString("");
|
||||
if (self->last == NULL) {
|
||||
Py_DECREF(self);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self->number = 0;
|
||||
}
|
||||
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
static int
|
||||
Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyObject *first=NULL, *last=NULL, *tmp;
|
||||
|
||||
static char *kwlist[] = {"first", "last", "number", NULL};
|
||||
|
||||
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|SSi", kwlist,
|
||||
&first, &last,
|
||||
&self->number))
|
||||
return -1;
|
||||
|
||||
if (first) {
|
||||
tmp = self->first;
|
||||
Py_INCREF(first);
|
||||
self->first = first;
|
||||
Py_DECREF(tmp);
|
||||
}
|
||||
|
||||
if (last) {
|
||||
tmp = self->last;
|
||||
Py_INCREF(last);
|
||||
self->last = last;
|
||||
Py_DECREF(tmp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyMemberDef Noddy_members[] = {
|
||||
{"number", T_INT, offsetof(Noddy, number), 0,
|
||||
"noddy number"},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
Noddy_getfirst(Noddy *self, void *closure)
|
||||
{
|
||||
Py_INCREF(self->first);
|
||||
return self->first;
|
||||
}
|
||||
|
||||
static int
|
||||
Noddy_setfirst(Noddy *self, PyObject *value, void *closure)
|
||||
{
|
||||
if (value == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (! PyUnicode_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"The first attribute value must be a string");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Py_DECREF(self->first);
|
||||
Py_INCREF(value);
|
||||
self->first = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Noddy_getlast(Noddy *self, void *closure)
|
||||
{
|
||||
Py_INCREF(self->last);
|
||||
return self->last;
|
||||
}
|
||||
|
||||
static int
|
||||
Noddy_setlast(Noddy *self, PyObject *value, void *closure)
|
||||
{
|
||||
if (value == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (! PyUnicode_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"The last attribute value must be a string");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Py_DECREF(self->last);
|
||||
Py_INCREF(value);
|
||||
self->last = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyGetSetDef Noddy_getseters[] = {
|
||||
{"first",
|
||||
(getter)Noddy_getfirst, (setter)Noddy_setfirst,
|
||||
"first name",
|
||||
NULL},
|
||||
{"last",
|
||||
(getter)Noddy_getlast, (setter)Noddy_setlast,
|
||||
"last name",
|
||||
NULL},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
Noddy_name(Noddy* self)
|
||||
{
|
||||
return PyUnicode_FromFormat("%S %S", self->first, self->last);
|
||||
}
|
||||
|
||||
static PyMethodDef Noddy_methods[] = {
|
||||
{"name", (PyCFunction)Noddy_name, METH_NOARGS,
|
||||
"Return the name, combining the first and last name"
|
||||
},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyTypeObject NoddyType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"noddy.Noddy", /* tp_name */
|
||||
sizeof(Noddy), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
(destructor)Noddy_dealloc, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_reserved */
|
||||
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 */
|
||||
"Noddy objects", /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
Noddy_methods, /* tp_methods */
|
||||
Noddy_members, /* tp_members */
|
||||
Noddy_getseters, /* tp_getset */
|
||||
0, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
0, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
(initproc)Noddy_init, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
Noddy_new, /* tp_new */
|
||||
};
|
||||
|
||||
static PyModuleDef noddy3module = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"noddy3",
|
||||
"Example module that creates an extension type.",
|
||||
-1,
|
||||
NULL, NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit_noddy3(void)
|
||||
{
|
||||
PyObject* m;
|
||||
|
||||
if (PyType_Ready(&NoddyType) < 0)
|
||||
return NULL;
|
||||
|
||||
m = PyModule_Create(&noddy3module);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
|
||||
Py_INCREF(&NoddyType);
|
||||
PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
|
||||
return m;
|
||||
}
|
||||
|
|
@ -1,208 +0,0 @@
|
|||
#include <Python.h>
|
||||
#include "structmember.h"
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *first;
|
||||
PyObject *last;
|
||||
int number;
|
||||
} Noddy;
|
||||
|
||||
static int
|
||||
Noddy_traverse(Noddy *self, visitproc visit, void *arg)
|
||||
{
|
||||
int vret;
|
||||
|
||||
if (self->first) {
|
||||
vret = visit(self->first, arg);
|
||||
if (vret != 0)
|
||||
return vret;
|
||||
}
|
||||
if (self->last) {
|
||||
vret = visit(self->last, arg);
|
||||
if (vret != 0)
|
||||
return vret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
Noddy_clear(Noddy *self)
|
||||
{
|
||||
PyObject *tmp;
|
||||
|
||||
tmp = self->first;
|
||||
self->first = NULL;
|
||||
Py_XDECREF(tmp);
|
||||
|
||||
tmp = self->last;
|
||||
self->last = NULL;
|
||||
Py_XDECREF(tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
Noddy_dealloc(Noddy* self)
|
||||
{
|
||||
PyObject_GC_UnTrack(self);
|
||||
Noddy_clear(self);
|
||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
Noddy *self;
|
||||
|
||||
self = (Noddy *)type->tp_alloc(type, 0);
|
||||
if (self != NULL) {
|
||||
self->first = PyUnicode_FromString("");
|
||||
if (self->first == NULL) {
|
||||
Py_DECREF(self);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self->last = PyUnicode_FromString("");
|
||||
if (self->last == NULL) {
|
||||
Py_DECREF(self);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self->number = 0;
|
||||
}
|
||||
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
static int
|
||||
Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyObject *first=NULL, *last=NULL, *tmp;
|
||||
|
||||
static char *kwlist[] = {"first", "last", "number", NULL};
|
||||
|
||||
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
|
||||
&first, &last,
|
||||
&self->number))
|
||||
return -1;
|
||||
|
||||
if (first) {
|
||||
tmp = self->first;
|
||||
Py_INCREF(first);
|
||||
self->first = first;
|
||||
Py_XDECREF(tmp);
|
||||
}
|
||||
|
||||
if (last) {
|
||||
tmp = self->last;
|
||||
Py_INCREF(last);
|
||||
self->last = last;
|
||||
Py_XDECREF(tmp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static PyMemberDef Noddy_members[] = {
|
||||
{"first", T_OBJECT_EX, offsetof(Noddy, first), 0,
|
||||
"first name"},
|
||||
{"last", T_OBJECT_EX, offsetof(Noddy, last), 0,
|
||||
"last name"},
|
||||
{"number", T_INT, offsetof(Noddy, number), 0,
|
||||
"noddy number"},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
Noddy_name(Noddy* self)
|
||||
{
|
||||
if (self->first == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, "first");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (self->last == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, "last");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return PyUnicode_FromFormat("%S %S", self->first, self->last);
|
||||
}
|
||||
|
||||
static PyMethodDef Noddy_methods[] = {
|
||||
{"name", (PyCFunction)Noddy_name, METH_NOARGS,
|
||||
"Return the name, combining the first and last name"
|
||||
},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyTypeObject NoddyType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"noddy.Noddy", /* tp_name */
|
||||
sizeof(Noddy), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
(destructor)Noddy_dealloc, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_reserved */
|
||||
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 |
|
||||
Py_TPFLAGS_HAVE_GC, /* tp_flags */
|
||||
"Noddy objects", /* tp_doc */
|
||||
(traverseproc)Noddy_traverse, /* tp_traverse */
|
||||
(inquiry)Noddy_clear, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
Noddy_methods, /* tp_methods */
|
||||
Noddy_members, /* tp_members */
|
||||
0, /* tp_getset */
|
||||
0, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
0, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
(initproc)Noddy_init, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
Noddy_new, /* tp_new */
|
||||
};
|
||||
|
||||
static PyModuleDef noddy4module = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"noddy4",
|
||||
"Example module that creates an extension type.",
|
||||
-1,
|
||||
NULL, NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit_noddy4(void)
|
||||
{
|
||||
PyObject* m;
|
||||
|
||||
if (PyType_Ready(&NoddyType) < 0)
|
||||
return NULL;
|
||||
|
||||
m = PyModule_Create(&noddy4module);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
|
||||
Py_INCREF(&NoddyType);
|
||||
PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
|
||||
return m;
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
#include <Python.h>
|
||||
|
||||
typedef struct {
|
||||
PyListObject list;
|
||||
int state;
|
||||
} Shoddy;
|
||||
|
||||
|
||||
static PyObject *
|
||||
Shoddy_increment(Shoddy *self, PyObject *unused)
|
||||
{
|
||||
self->state++;
|
||||
return PyLong_FromLong(self->state);
|
||||
}
|
||||
|
||||
|
||||
static PyMethodDef Shoddy_methods[] = {
|
||||
{"increment", (PyCFunction)Shoddy_increment, METH_NOARGS,
|
||||
PyDoc_STR("increment state counter")},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static int
|
||||
Shoddy_init(Shoddy *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0)
|
||||
return -1;
|
||||
self->state = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static PyTypeObject ShoddyType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"shoddy.Shoddy", /* tp_name */
|
||||
sizeof(Shoddy), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
0, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_reserved */
|
||||
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 */
|
||||
0, /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
Shoddy_methods, /* tp_methods */
|
||||
0, /* tp_members */
|
||||
0, /* tp_getset */
|
||||
0, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
0, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
(initproc)Shoddy_init, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
0, /* tp_new */
|
||||
};
|
||||
|
||||
static PyModuleDef shoddymodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"shoddy",
|
||||
"Shoddy module",
|
||||
-1,
|
||||
NULL, NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit_shoddy(void)
|
||||
{
|
||||
PyObject *m;
|
||||
|
||||
ShoddyType.tp_base = &PyList_Type;
|
||||
if (PyType_Ready(&ShoddyType) < 0)
|
||||
return NULL;
|
||||
|
||||
m = PyModule_Create(&shoddymodule);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
|
||||
Py_INCREF(&ShoddyType);
|
||||
PyModule_AddObject(m, "Shoddy", (PyObject *) &ShoddyType);
|
||||
return m;
|
||||
}
|
||||
63
Doc/includes/sublist.c
Normal file
63
Doc/includes/sublist.c
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#include <Python.h>
|
||||
|
||||
typedef struct {
|
||||
PyListObject list;
|
||||
int state;
|
||||
} SubListObject;
|
||||
|
||||
static PyObject *
|
||||
SubList_increment(SubListObject *self, PyObject *unused)
|
||||
{
|
||||
self->state++;
|
||||
return PyLong_FromLong(self->state);
|
||||
}
|
||||
|
||||
static PyMethodDef SubList_methods[] = {
|
||||
{"increment", (PyCFunction) SubList_increment, METH_NOARGS,
|
||||
PyDoc_STR("increment state counter")},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static int
|
||||
SubList_init(SubListObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
if (PyList_Type.tp_init((PyObject *) self, args, kwds) < 0)
|
||||
return -1;
|
||||
self->state = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyTypeObject SubListType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
.tp_name = "sublist.SubList",
|
||||
.tp_doc = "SubList objects",
|
||||
.tp_basicsize = sizeof(SubListObject),
|
||||
.tp_itemsize = 0,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
.tp_init = (initproc) SubList_init,
|
||||
.tp_methods = SubList_methods,
|
||||
};
|
||||
|
||||
static PyModuleDef sublistmodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
.m_name = "sublist",
|
||||
.m_doc = "Example module that creates an extension type.",
|
||||
.m_size = -1,
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit_sublist(void)
|
||||
{
|
||||
PyObject *m;
|
||||
SubListType.tp_base = &PyList_Type;
|
||||
if (PyType_Ready(&SubListType) < 0)
|
||||
return NULL;
|
||||
|
||||
m = PyModule_Create(&sublistmodule);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
|
||||
Py_INCREF(&SubListType);
|
||||
PyModule_AddObject(m, "SubList", (PyObject *) &SubListType);
|
||||
return m;
|
||||
}
|
||||
|
|
@ -1,181 +1,168 @@
|
|||
"""Test module for the noddy examples
|
||||
"""Test module for the custom examples
|
||||
|
||||
Noddy 1:
|
||||
Custom 1:
|
||||
|
||||
>>> import noddy
|
||||
>>> n1 = noddy.Noddy()
|
||||
>>> n2 = noddy.Noddy()
|
||||
>>> del n1
|
||||
>>> del n2
|
||||
>>> import custom
|
||||
>>> c1 = custom.Custom()
|
||||
>>> c2 = custom.Custom()
|
||||
>>> del c1
|
||||
>>> del c2
|
||||
|
||||
|
||||
Noddy 2
|
||||
Custom 2
|
||||
|
||||
>>> import noddy2
|
||||
>>> n1 = noddy2.Noddy('jim', 'fulton', 42)
|
||||
>>> n1.first
|
||||
>>> import custom2
|
||||
>>> c1 = custom2.Custom('jim', 'fulton', 42)
|
||||
>>> c1.first
|
||||
'jim'
|
||||
>>> n1.last
|
||||
>>> c1.last
|
||||
'fulton'
|
||||
>>> n1.number
|
||||
>>> c1.number
|
||||
42
|
||||
>>> n1.name()
|
||||
>>> c1.name()
|
||||
'jim fulton'
|
||||
>>> n1.first = 'will'
|
||||
>>> n1.name()
|
||||
>>> c1.first = 'will'
|
||||
>>> c1.name()
|
||||
'will fulton'
|
||||
>>> n1.last = 'tell'
|
||||
>>> n1.name()
|
||||
>>> c1.last = 'tell'
|
||||
>>> c1.name()
|
||||
'will tell'
|
||||
>>> del n1.first
|
||||
>>> n1.name()
|
||||
>>> del c1.first
|
||||
>>> c1.name()
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError: first
|
||||
>>> n1.first
|
||||
>>> c1.first
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError: first
|
||||
>>> n1.first = 'drew'
|
||||
>>> n1.first
|
||||
>>> c1.first = 'drew'
|
||||
>>> c1.first
|
||||
'drew'
|
||||
>>> del n1.number
|
||||
>>> del c1.number
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
TypeError: can't delete numeric/char attribute
|
||||
>>> n1.number=2
|
||||
>>> n1.number
|
||||
>>> c1.number=2
|
||||
>>> c1.number
|
||||
2
|
||||
>>> n1.first = 42
|
||||
>>> n1.name()
|
||||
>>> c1.first = 42
|
||||
>>> c1.name()
|
||||
'42 tell'
|
||||
>>> n2 = noddy2.Noddy()
|
||||
>>> n2.name()
|
||||
>>> c2 = custom2.Custom()
|
||||
>>> c2.name()
|
||||
' '
|
||||
>>> n2.first
|
||||
>>> c2.first
|
||||
''
|
||||
>>> n2.last
|
||||
>>> c2.last
|
||||
''
|
||||
>>> del n2.first
|
||||
>>> n2.first
|
||||
>>> del c2.first
|
||||
>>> c2.first
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError: first
|
||||
>>> n2.first
|
||||
>>> c2.first
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError: first
|
||||
>>> n2.name()
|
||||
>>> c2.name()
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
AttributeError: first
|
||||
>>> n2.number
|
||||
>>> c2.number
|
||||
0
|
||||
>>> n3 = noddy2.Noddy('jim', 'fulton', 'waaa')
|
||||
>>> n3 = custom2.Custom('jim', 'fulton', 'waaa')
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: an integer is required
|
||||
>>> del n1
|
||||
>>> del n2
|
||||
TypeError: an integer is required (got type str)
|
||||
>>> del c1
|
||||
>>> del c2
|
||||
|
||||
|
||||
Noddy 3
|
||||
Custom 3
|
||||
|
||||
>>> import noddy3
|
||||
>>> n1 = noddy3.Noddy('jim', 'fulton', 42)
|
||||
>>> n1 = noddy3.Noddy('jim', 'fulton', 42)
|
||||
>>> n1.name()
|
||||
>>> import custom3
|
||||
>>> c1 = custom3.Custom('jim', 'fulton', 42)
|
||||
>>> c1 = custom3.Custom('jim', 'fulton', 42)
|
||||
>>> c1.name()
|
||||
'jim fulton'
|
||||
>>> del n1.first
|
||||
>>> del c1.first
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: Cannot delete the first attribute
|
||||
>>> n1.first = 42
|
||||
>>> c1.first = 42
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: The first attribute value must be a string
|
||||
>>> n1.first = 'will'
|
||||
>>> n1.name()
|
||||
>>> c1.first = 'will'
|
||||
>>> c1.name()
|
||||
'will fulton'
|
||||
>>> n2 = noddy3.Noddy()
|
||||
>>> n2 = noddy3.Noddy()
|
||||
>>> n2 = noddy3.Noddy()
|
||||
>>> n3 = noddy3.Noddy('jim', 'fulton', 'waaa')
|
||||
>>> c2 = custom3.Custom()
|
||||
>>> c2 = custom3.Custom()
|
||||
>>> c2 = custom3.Custom()
|
||||
>>> n3 = custom3.Custom('jim', 'fulton', 'waaa')
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: an integer is required
|
||||
>>> del n1
|
||||
>>> del n2
|
||||
TypeError: an integer is required (got type str)
|
||||
>>> del c1
|
||||
>>> del c2
|
||||
|
||||
Noddy 4
|
||||
Custom 4
|
||||
|
||||
>>> import noddy4
|
||||
>>> n1 = noddy4.Noddy('jim', 'fulton', 42)
|
||||
>>> n1.first
|
||||
>>> import custom4
|
||||
>>> c1 = custom4.Custom('jim', 'fulton', 42)
|
||||
>>> c1.first
|
||||
'jim'
|
||||
>>> n1.last
|
||||
>>> c1.last
|
||||
'fulton'
|
||||
>>> n1.number
|
||||
>>> c1.number
|
||||
42
|
||||
>>> n1.name()
|
||||
>>> c1.name()
|
||||
'jim fulton'
|
||||
>>> n1.first = 'will'
|
||||
>>> n1.name()
|
||||
>>> c1.first = 'will'
|
||||
>>> c1.name()
|
||||
'will fulton'
|
||||
>>> n1.last = 'tell'
|
||||
>>> n1.name()
|
||||
>>> c1.last = 'tell'
|
||||
>>> c1.name()
|
||||
'will tell'
|
||||
>>> del n1.first
|
||||
>>> n1.name()
|
||||
>>> del c1.first
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError: first
|
||||
>>> n1.first
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError: first
|
||||
>>> n1.first = 'drew'
|
||||
>>> n1.first
|
||||
TypeError: Cannot delete the first attribute
|
||||
>>> c1.name()
|
||||
'will tell'
|
||||
>>> c1.first = 'drew'
|
||||
>>> c1.first
|
||||
'drew'
|
||||
>>> del n1.number
|
||||
>>> del c1.number
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
TypeError: can't delete numeric/char attribute
|
||||
>>> n1.number=2
|
||||
>>> n1.number
|
||||
>>> c1.number=2
|
||||
>>> c1.number
|
||||
2
|
||||
>>> n1.first = 42
|
||||
>>> n1.name()
|
||||
'42 tell'
|
||||
>>> n2 = noddy4.Noddy()
|
||||
>>> n2 = noddy4.Noddy()
|
||||
>>> n2 = noddy4.Noddy()
|
||||
>>> n2 = noddy4.Noddy()
|
||||
>>> n2.name()
|
||||
>>> c1.first = 42
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
TypeError: The first attribute value must be a string
|
||||
>>> c1.name()
|
||||
'drew tell'
|
||||
>>> c2 = custom4.Custom()
|
||||
>>> c2 = custom4.Custom()
|
||||
>>> c2 = custom4.Custom()
|
||||
>>> c2 = custom4.Custom()
|
||||
>>> c2.name()
|
||||
' '
|
||||
>>> n2.first
|
||||
>>> c2.first
|
||||
''
|
||||
>>> n2.last
|
||||
>>> c2.last
|
||||
''
|
||||
>>> del n2.first
|
||||
>>> n2.first
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError: first
|
||||
>>> n2.first
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError: first
|
||||
>>> n2.name()
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
AttributeError: first
|
||||
>>> n2.number
|
||||
>>> c2.number
|
||||
0
|
||||
>>> n3 = noddy4.Noddy('jim', 'fulton', 'waaa')
|
||||
>>> n3 = custom4.Custom('jim', 'fulton', 'waaa')
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: an integer is required
|
||||
...
|
||||
TypeError: an integer is required (got type str)
|
||||
|
||||
|
||||
Test cyclic gc(?)
|
||||
|
|
@ -183,15 +170,14 @@ Test cyclic gc(?)
|
|||
>>> import gc
|
||||
>>> gc.disable()
|
||||
|
||||
>>> x = []
|
||||
>>> l = [x]
|
||||
>>> n2.first = l
|
||||
>>> n2.first
|
||||
[[]]
|
||||
>>> l.append(n2)
|
||||
>>> del l
|
||||
>>> del n1
|
||||
>>> del n2
|
||||
>>> class Subclass(custom4.Custom): pass
|
||||
...
|
||||
>>> s = Subclass()
|
||||
>>> s.cycle = [s]
|
||||
>>> s.cycle.append(s.cycle)
|
||||
>>> x = object()
|
||||
>>> s.x = x
|
||||
>>> del s
|
||||
>>> sys.getrefcount(x)
|
||||
3
|
||||
>>> ignore = gc.collect()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue