From 913b2a382f237c89a43198001398c61b3196b0be Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Fri, 5 Dec 2008 15:12:15 +0000 Subject: #4504, #4505: Update noddy examples in "Extending & Embedding". --- Doc/extending/newtypes.rst | 163 ++++++++++++++++++++++----------------------- Doc/includes/noddy.c | 59 ++++++++-------- Doc/includes/noddy2.c | 63 +++++++++--------- Doc/includes/noddy3.c | 63 +++++++++--------- Doc/includes/noddy4.c | 64 +++++++++--------- Doc/includes/shoddy.c | 19 ++++-- Doc/includes/typestruct.h | 3 - 7 files changed, 215 insertions(+), 219 deletions(-) diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst index 931c2b5..b0211b1 100644 --- a/Doc/extending/newtypes.rst +++ b/Doc/extending/newtypes.rst @@ -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,20 +857,20 @@ 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; + PyObject *m; - ShoddyType.tp_base = &PyList_Type; - if (PyType_Ready(&ShoddyType) < 0) - return; + ShoddyType.tp_base = &PyList_Type; + if (PyType_Ready(&ShoddyType) < 0) + return NULL; - m = Py_InitModule3("shoddy", NULL, "Shoddy module"); - if (m == NULL) - return; + m = PyModule_Create(&shoddymodule); + if (m == NULL) + return NULL; - Py_INCREF(&ShoddyType); - PyModule_AddObject(m, "Shoddy", (PyObject *) &ShoddyType); + Py_INCREF(&ShoddyType); + PyModule_AddObject(m, "Shoddy", (PyObject *) &ShoddyType); } Before calling :cfunc:`PyType_Ready`, the type structure must have the @@ -1241,49 +1233,50 @@ example that simply raises an exception; if this were really all you wanted, the return -1; } - -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:: - - static int - newdatatype_compare(newdatatypeobject * obj1, newdatatypeobject * obj2) - { - long result; - - if (obj1->obj_UnderlyingDatatypePtr->size < - obj2->obj_UnderlyingDatatypePtr->size) { - result = -1; - } - else if (obj1->obj_UnderlyingDatatypePtr->size > - obj2->obj_UnderlyingDatatypePtr->size) { - result = 1; - } - else { - result = 0; - } - return result; - } +.. XXX tp_compare is dead; need to rewrite for tp_richcompare! + + 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:: + + static int + newdatatype_compare(newdatatypeobject * obj1, newdatatypeobject * obj2) + { + long result; + + if (obj1->obj_UnderlyingDatatypePtr->size < + obj2->obj_UnderlyingDatatypePtr->size) { + result = -1; + } + else if (obj1->obj_UnderlyingDatatypePtr->size > + obj2->obj_UnderlyingDatatypePtr->size) { + result = 1; + } + else { + result = 0; + } + return result; + } Abstract Protocol Support diff --git a/Doc/includes/noddy.c b/Doc/includes/noddy.c index ec2d669..26a49a9 100644 --- a/Doc/includes/noddy.c +++ b/Doc/includes/noddy.c @@ -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); diff --git a/Doc/includes/noddy2.c b/Doc/includes/noddy2.c index eaa355f..5daecf9 100644 --- a/Doc/includes/noddy2.c +++ b/Doc/includes/noddy2.c @@ -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); diff --git a/Doc/includes/noddy3.c b/Doc/includes/noddy3.c index 3a1c0c2..39cdfdb 100644 --- a/Doc/includes/noddy3.c +++ b/Doc/includes/noddy3.c @@ -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); diff --git a/Doc/includes/noddy4.c b/Doc/includes/noddy4.c index ac0b1f4..94507ec 100644 --- a/Doc/includes/noddy4.c +++ b/Doc/includes/noddy4.c @@ -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); diff --git a/Doc/includes/shoddy.c b/Doc/includes/shoddy.c index 4c46bea..3757bca 100644 --- a/Doc/includes/shoddy.c +++ b/Doc/includes/shoddy.c @@ -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 */ @@ -52,7 +51,7 @@ static PyTypeObject ShoddyType = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_BASETYPE, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -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); diff --git a/Doc/includes/typestruct.h b/Doc/includes/typestruct.h index 0afe375..f6451b9 100644 --- a/Doc/includes/typestruct.h +++ b/Doc/includes/typestruct.h @@ -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; -- cgit v0.12