Commit 913b2a38 authored by Georg Brandl's avatar Georg Brandl

#4504, #4505: Update noddy examples in "Extending & Embedding".

parent a872de55
......@@ -73,26 +73,25 @@ Moving on, we come to the crunch --- the type object. ::
static PyTypeObject noddy_NoddyType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"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_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, /*tp_flags*/
"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_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, /* tp_flags */
"Noddy objects", /* tp_doc */
};
......@@ -114,13 +113,6 @@ as the type of a type object is "type", but this isn't strictly conforming C and
some compilers complain. Fortunately, this member will be filled in for us by
:cfunc:`PyType_Ready`. ::
0, /* ob_size */
The :attr:`ob_size` field of the header is not used; its presence in the type
structure is a historical artifact that is maintained for binary compatibility
with extension modules compiled for older versions of Python. Always set this
field to zero. ::
"noddy.Noddy", /* tp_name */
The name of our type. This will appear in the default textual representation of
......@@ -162,7 +154,7 @@ for now.
Skipping a number of type methods that we don't provide, we set the class flags
to :const:`Py_TPFLAGS_DEFAULT`. ::
Py_TPFLAGS_DEFAULT, /*tp_flags*/
Py_TPFLAGS_DEFAULT, /* tp_flags */
All types should include this constant in their flags. It enables all of the
members defined by the current version of Python.
......@@ -193,7 +185,7 @@ All the other type methods are *NULL*, so we'll go over them later --- that's
for a later section!
Everything else in the file should be familiar, except for some code in
:cfunc:`initnoddy`::
:cfunc:`PyInit_noddy`::
if (PyType_Ready(&noddy_NoddyType) < 0)
return;
......@@ -523,8 +515,8 @@ object being created or used, so all we need to do is to add the
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
We rename :cfunc:`initnoddy` to :cfunc:`initnoddy2` and update the module name
passed to :cfunc:`Py_InitModule3`.
We rename :cfunc:`PyInit_noddy` to :cfunc:`PyInit_noddy2` and update the module
name in the :ctype:`PyModuleDef` struct.
Finally, we update our :file:`setup.py` file to build the new module::
......@@ -794,7 +786,7 @@ be simplified::
Finally, we add the :const:`Py_TPFLAGS_HAVE_GC` flag to the class flags::
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
That's pretty much it. If we had written custom :attr:`tp_alloc` or
:attr:`tp_free` slots, we'd need to modify them for cyclic-garbage collection.
......@@ -865,17 +857,17 @@ fill that field directly with the :cfunc:`PyList_Type`; it can be done later in
the module's :cfunc:`init` function. ::
PyMODINIT_FUNC
initshoddy(void)
PyInit_shoddy(void)
{
PyObject *m;
ShoddyType.tp_base = &PyList_Type;
if (PyType_Ready(&ShoddyType) < 0)
return;
return NULL;
m = Py_InitModule3("shoddy", NULL, "Shoddy module");
m = PyModule_Create(&shoddymodule);
if (m == NULL)
return;
return NULL;
Py_INCREF(&ShoddyType);
PyModule_AddObject(m, "Shoddy", (PyObject *) &ShoddyType);
......@@ -1241,30 +1233,31 @@ example that simply raises an exception; if this were really all you wanted, the
return -1;
}
.. XXX tp_compare is dead; need to rewrite for tp_richcompare!
Object Comparison
-----------------
Object Comparison
-----------------
::
::
cmpfunc tp_compare;
The :attr:`tp_compare` handler is called when comparisons are needed and the
object does not implement the specific rich comparison method which matches the
requested comparison. (It is always used if defined and the
:cfunc:`PyObject_Compare` or :cfunc:`PyObject_Cmp` functions are used, or if
:func:`cmp` is used from Python.) It is analogous to the :meth:`__cmp__` method.
This function should return ``-1`` if *obj1* is less than *obj2*, ``0`` if they
are equal, and ``1`` if *obj1* is greater than *obj2*. (It was previously
allowed to return arbitrary negative or positive integers for less than and
greater than, respectively; as of Python 2.2, this is no longer allowed. In the
future, other return values may be assigned a different meaning.)
A :attr:`tp_compare` handler may raise an exception. In this case it should
return a negative value. The caller has to test for the exception using
:cfunc:`PyErr_Occurred`.
Here is a sample implementation::
The :attr:`tp_compare` handler is called when comparisons are needed and the
object does not implement the specific rich comparison method which matches the
requested comparison. (It is always used if defined and the
:cfunc:`PyObject_Compare` or :cfunc:`PyObject_Cmp` functions are used, or if
:func:`cmp` is used from Python.) It is analogous to the :meth:`__cmp__` method.
This function should return ``-1`` if *obj1* is less than *obj2*, ``0`` if they
are equal, and ``1`` if *obj1* is greater than *obj2*. (It was previously
allowed to return arbitrary negative or positive integers for less than and
greater than, respectively; as of Python 2.2, this is no longer allowed. In the
future, other return values may be assigned a different meaning.)
A :attr:`tp_compare` handler may raise an exception. In this case it should
return a negative value. The caller has to test for the exception using
:cfunc:`PyErr_Occurred`.
Here is a sample implementation::
static int
newdatatype_compare(newdatatypeobject * obj1, newdatatypeobject * obj2)
......
......@@ -7,47 +7,48 @@ typedef struct {
static PyTypeObject noddy_NoddyType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"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_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, /*tp_flags*/
"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_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, /* tp_flags */
"Noddy objects", /* tp_doc */
};
static PyMethodDef noddy_methods[] = {
{NULL} /* Sentinel */
static PyModuleDef noddymodule = {
PyModuleDef_HEAD_INIT,
"noddy",
"Example module that creates an extension type.",
-1,
NULL, NULL, NULL, NULL, NULL
};
#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
initnoddy(void)
PyInit_noddy(void)
{
PyObject* m;
noddy_NoddyType.tp_new = PyType_GenericNew;
if (PyType_Ready(&noddy_NoddyType) < 0)
return;
return NULL;
m = Py_InitModule3("noddy", noddy_methods,
"Example module that creates an extension type.");
m = PyModule_Create(&noddymodule);
if (m == NULL)
return NULL;
Py_INCREF(&noddy_NoddyType);
PyModule_AddObject(m, "Noddy", (PyObject *)&noddy_NoddyType);
......
......@@ -13,7 +13,7 @@ Noddy_dealloc(Noddy* self)
{
Py_XDECREF(self->first);
Py_XDECREF(self->last);
self->ob_type->tp_free((PyObject*)self);
Py_TYPE(self)->tp_free((PyObject*)self);
}
static PyObject *
......@@ -124,26 +124,26 @@ static PyMethodDef Noddy_methods[] = {
static PyTypeObject NoddyType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"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_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*/
"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_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 */
"Noddy objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
......@@ -164,26 +164,25 @@ static PyTypeObject NoddyType = {
Noddy_new, /* tp_new */
};
static PyMethodDef module_methods[] = {
{NULL} /* Sentinel */
static PyModuleDef noddy2module = {
PyModuleDef_HEAD_INIT,
"noddy2",
"Example module that creates an extension type.",
-1,
NULL, NULL, NULL, NULL, NULL
};
#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
initnoddy2(void)
PyInit_noddy2(void)
{
PyObject* m;
if (PyType_Ready(&NoddyType) < 0)
return;
m = Py_InitModule3("noddy2", module_methods,
"Example module that creates an extension type.");
return NULL;
m = PyModule_Create(&noddy2module);
if (m == NULL)
return;
return NULL;
Py_INCREF(&NoddyType);
PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
......
......@@ -13,7 +13,7 @@ Noddy_dealloc(Noddy* self)
{
Py_XDECREF(self->first);
Py_XDECREF(self->last);
self->ob_type->tp_free((PyObject*)self);
Py_TYPE(self)->tp_free((PyObject*)self);
}
static PyObject *
......@@ -177,26 +177,26 @@ static PyMethodDef Noddy_methods[] = {
static PyTypeObject NoddyType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"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_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*/
"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_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 */
"Noddy objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
......@@ -217,26 +217,25 @@ static PyTypeObject NoddyType = {
Noddy_new, /* tp_new */
};
static PyMethodDef module_methods[] = {
{NULL} /* Sentinel */
static PyModuleDef noddy3module = {
PyModuleDef_HEAD_INIT,
"noddy3",
"Example module that creates an extension type.",
-1,
NULL, NULL, NULL, NULL, NULL
};
#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
initnoddy3(void)
PyInit_noddy3(void)
{
PyObject* m;
if (PyType_Ready(&NoddyType) < 0)
return;
m = Py_InitModule3("noddy3", module_methods,
"Example module that creates an extension type.");
return NULL;
m = PyModule_Create(&noddy3module);
if (m == NULL)
return;
return NULL;
Py_INCREF(&NoddyType);
PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
......
......@@ -47,7 +47,7 @@ static void
Noddy_dealloc(Noddy* self)
{
Noddy_clear(self);
self->ob_type->tp_free((PyObject*)self);
Py_TYPE(self)->tp_free((PyObject*)self);
}
static PyObject *
......@@ -158,26 +158,27 @@ static PyMethodDef Noddy_methods[] = {
static PyTypeObject NoddyType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"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_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 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
"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_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 |
Py_TPFLAGS_HAVE_GC, /* tp_flags */
"Noddy objects", /* tp_doc */
(traverseproc)Noddy_traverse, /* tp_traverse */
(inquiry)Noddy_clear, /* tp_clear */
......@@ -198,26 +199,25 @@ static PyTypeObject NoddyType = {
Noddy_new, /* tp_new */
};
static PyMethodDef module_methods[] = {
{NULL} /* Sentinel */
static PyModuleDef noddy4module = {
PyModuleDef_HEAD_INIT,
"noddy4",
"Example module that creates an extension type.",
-1,
NULL, NULL, NULL, NULL, NULL
};
#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
initnoddy4(void)
PyInit_noddy4(void)
{
PyObject* m;
if (PyType_Ready(&NoddyType) < 0)
return;
m = Py_InitModule3("noddy4", module_methods,
"Example module that creates an extension type.");
return NULL;
m = PyModule_Create(&noddy4module);
if (m == NULL)
return;
return NULL;
Py_INCREF(&NoddyType);
PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
......
......@@ -32,7 +32,6 @@ Shoddy_init(Shoddy *self, PyObject *args, PyObject *kwds)
static PyTypeObject ShoddyType = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
"shoddy.Shoddy", /* tp_name */
sizeof(Shoddy), /* tp_basicsize */
0, /* tp_itemsize */
......@@ -73,18 +72,26 @@ static PyTypeObject ShoddyType = {
0, /* tp_new */
};
static PyModuleDef shoddymodule = {
PyModuleDef_HEAD_INIT,
"shoddy",
"Shoddy module",
-1,
NULL, NULL, NULL, NULL, NULL
};
PyMODINIT_FUNC
initshoddy(void)
PyInit_shoddy(void)
{
PyObject *m;
ShoddyType.tp_base = &PyList_Type;
if (PyType_Ready(&ShoddyType) < 0)
return;
return NULL;
m = Py_InitModule3("shoddy", NULL, "Shoddy module");
m = PyModule_Create(&shoddymodule);
if (m == NULL)
return;
return NULL;
Py_INCREF(&ShoddyType);
PyModule_AddObject(m, "Shoddy", (PyObject *) &ShoddyType);
......
......@@ -34,21 +34,18 @@ typedef struct _typeobject {
char *tp_doc; /* Documentation string */
/* Assigned meaning in release 2.0 */
/* call function for all accessible objects */
traverseproc tp_traverse;
/* delete references to contained objects */
inquiry tp_clear;
/* Assigned meaning in release 2.1 */
/* rich comparisons */
richcmpfunc tp_richcompare;
/* weak reference enabler */
long tp_weaklistoffset;
/* Added in release 2.2 */
/* Iterators */
getiterfunc tp_iter;
iternextfunc tp_iternext;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment