diff options
author | Antoine Pitrou <pitrou@free.fr> | 2018-04-07 16:14:03 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-07 16:14:03 (GMT) |
commit | 1d80a561734b9932961c546b0897405a3bfbf3e6 (patch) | |
tree | 737793472ed6d3745d31fb56f2cb1f2b66429c69 /Doc/includes/custom3.c | |
parent | b405752dab95fa5dc65a19d94e798844d0378c61 (diff) | |
download | cpython-1d80a561734b9932961c546b0897405a3bfbf3e6.zip cpython-1d80a561734b9932961c546b0897405a3bfbf3e6.tar.gz cpython-1d80a561734b9932961c546b0897405a3bfbf3e6.tar.bz2 |
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
Diffstat (limited to 'Doc/includes/custom3.c')
-rw-r--r-- | Doc/includes/custom3.c | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/Doc/includes/custom3.c b/Doc/includes/custom3.c new file mode 100644 index 0000000..09e8735 --- /dev/null +++ b/Doc/includes/custom3.c @@ -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; +} |