diff -r 9c735dbeb978 Include/cobject.h --- a/Include/cobject.h Mon Mar 30 15:53:06 2009 -0500 +++ b/Include/cobject.h Tue Mar 31 13:43:27 2009 -0500 @@ -16,45 +16,67 @@ PyAPI_DATA(PyTypeObject) PyCObject_Type; +struct PyCObject; +typedef struct PyCObject PyCObject; + +typedef void (*PyCObject_Destructor)(PyObject *); + #define PyCObject_Check(op) (Py_TYPE(op) == &PyCObject_Type) -/* Create a PyCObject from a pointer to a C object and an optional - destructor function. If the second argument is non-null, then it - will be called with the first argument if and when the PyCObject is - destroyed. +/* Create a PyCObject from a pointer to a C object, a type string, + and an optional destructor function. If the destructor argument is + non-null, then it then it will be called with the PyObject containing + the cobject when it is destroyed. The "cobject" pointer must not + be NULL. The "type" string must point to a legal C string of + non-zero length, and this string must outlive the CObject. + Returns NULL on failure. +*/ +PyAPI_FUNC(PyObject *) PyCObject_FromVoidPtr(PyCObject_Destructor destructor, + void *cobject, const char *type); +/* Like PyCObject_FromVoidPtr(), but allows passing in an optional "context" + pointer. */ -PyAPI_FUNC(PyObject *) PyCObject_FromVoidPtr( - void *cobj, void (*destruct)(void*)); +PyAPI_FUNC(PyObject *) PyCObject_FromVoidPtrWithContext(PyCObject_Destructor destructor, + void *cobject, const char *type, void *context); +/* Retrieve a "cobject" from a PyCObject. + You must pass in the correct type. + Returns NULL on failure. +*/ +PyAPI_FUNC(void *) PyCObject_AsVoidPtr(PyObject *o, const char *type); -/* Create a PyCObject from a pointer to a C object, a description object, - and an optional destructor function. If the third argument is non-null, - then it will be called with the first and second arguments if and when - the PyCObject is destroyed. -*/ -PyAPI_FUNC(PyObject *) PyCObject_FromVoidPtrAndDesc( - void *cobj, void *desc, void (*destruct)(void*,void*)); +/* Retrieve the "destructor" from a PyCObject. */ +PyAPI_FUNC(PyCObject_Destructor) PyCObject_GetDestructor(PyObject *); -/* Retrieve a pointer to a C object from a PyCObject. */ -PyAPI_FUNC(void *) PyCObject_AsVoidPtr(PyObject *); +/* Retrieve a "type" string a PyCObject. */ +PyAPI_FUNC(const char *) PyCObject_GetType(PyObject *); -/* Retrieve a pointer to a description object from a PyCObject. */ -PyAPI_FUNC(void *) PyCObject_GetDesc(PyObject *); +/* Retrieve a "context" pointer from a PyCObject. */ +PyAPI_FUNC(void *) PyCObject_GetContext(PyObject *); /* Import a pointer to a C object from a module using a PyCObject. */ -PyAPI_FUNC(void *) PyCObject_Import(char *module_name, char *cobject_name); +PyAPI_FUNC(void *) PyCObject_Import(const char *module_name, const char *cobject_name, const char *cobject_type); -/* Modify a C object. Fails (==0) if object has a destructor. */ -PyAPI_FUNC(int) PyCObject_SetVoidPtr(PyObject *self, void *cobj); +/* Change the "cobject" stored in a CObject. + Returns 0 on success, and nonzero on failure. +*/ +PyAPI_FUNC(int) PyCObject_SetVoidPtr(PyObject *self, void *cobject, const char *type); +/* Change the "destructor" stored in a CObject. + Returns 0 on success, and nonzero on failure. +*/ +PyAPI_FUNC(int) PyCObject_SetDestructor(PyObject *self, PyCObject_Destructor destructor); -typedef struct { - PyObject_HEAD - void *cobject; - void *desc; - void (*destructor)(void *); -} PyCObject; +/* Change the "type" stored in a CObject. + Returns 0 on success, and nonzero on failure. +*/ +PyAPI_FUNC(int) PyCObject_SetType(PyObject *self, const char *type); + +/* Change the "context" stored in a CObject. + Returns 0 on success, and nonzero on failure. +*/ +PyAPI_FUNC(int) PyCObject_SetContext(PyObject *self, void *context); #ifdef __cplusplus diff -r 9c735dbeb978 Include/datetime.h --- a/Include/datetime.h Mon Mar 30 15:53:06 2009 -0500 +++ b/Include/datetime.h Tue Mar 31 13:43:27 2009 -0500 @@ -159,9 +159,6 @@ } PyDateTime_CAPI; -/* "magic" constant used to partially protect against developer mistakes. */ -#define DATETIME_API_MAGIC 0x414548d5 - #ifdef Py_BUILD_CORE /* Macros for type checking when building the Python core. */ @@ -187,15 +184,9 @@ #define PyDateTime_IMPORT \ PyDateTimeAPI = (PyDateTime_CAPI*) PyCObject_Import("datetime", \ + "datetime_CAPI", \ "datetime_CAPI") -/* This macro would be used if PyCObject_ImportEx() was created. -#define PyDateTime_IMPORT \ - PyDateTimeAPI = (PyDateTime_CAPI*) PyCObject_ImportEx("datetime", \ - "datetime_CAPI", \ - DATETIME_API_MAGIC) -*/ - /* Macros for type checking when not building the Python core. */ #define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType) #define PyDate_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DateType) diff -r 9c735dbeb978 Include/py_curses.h --- a/Include/py_curses.h Mon Mar 30 15:53:06 2009 -0500 +++ b/Include/py_curses.h Tue Mar 31 13:43:27 2009 -0500 @@ -94,9 +94,7 @@ if (module != NULL) { \ PyObject *module_dict = PyModule_GetDict(module); \ PyObject *c_api_object = PyDict_GetItemString(module_dict, "_C_API"); \ - if (PyCObject_Check(c_api_object)) { \ - PyCurses_API = (void **)PyCObject_AsVoidPtr(c_api_object); \ - } \ + PyCurses_API = (void **)PyCObject_AsVoidPtr(c_api_object, "PyCurses_API"); \ } \ } #endif diff -r 9c735dbeb978 Modules/_ctypes/callproc.c --- a/Modules/_ctypes/callproc.c Mon Mar 30 15:53:06 2009 -0500 +++ b/Modules/_ctypes/callproc.c Tue Mar 31 13:43:27 2009 -0500 @@ -78,6 +78,14 @@ #define DONT_USE_SEH #endif +static void pymem_destructor(PyObject *ptr) +{ + void *p = PyCObject_AsVoidPtr(ptr, "_ctypes_mem"); + if (p) { + PyMem_Free(p); + } +} + /* ctypes maintains thread-local storage that has space for two error numbers: private copies of the system 'errno' value and, on Windows, the system error code @@ -136,7 +144,7 @@ if (space == NULL) return NULL; memset(space, 0, sizeof(int) * 2); - errobj = PyCObject_FromVoidPtr(space, PyMem_Free); + errobj = PyCObject_FromVoidPtr(pymem_destructor, space, "_ctypes_mem"); if (errobj == NULL) return NULL; if (-1 == PyDict_SetItem(dict, error_object_name, @@ -145,7 +153,7 @@ return NULL; } } - *pspace = (int *)PyCObject_AsVoidPtr(errobj); + *pspace = (int *)PyCObject_AsVoidPtr(errobj, "_ctypes_mem"); return errobj; } @@ -662,7 +670,7 @@ return -1; } memset(pa->value.p, 0, size); - pa->keep = PyCObject_FromVoidPtr(pa->value.p, PyMem_Free); + pa->keep = PyCObject_FromVoidPtr(pymem_destructor, pa->value.p, "_ctypes_mem"); if (!pa->keep) { PyMem_Free(pa->value.p); return -1; diff -r 9c735dbeb978 Modules/_ctypes/cfield.c --- a/Modules/_ctypes/cfield.c Mon Mar 30 15:53:06 2009 -0500 +++ b/Modules/_ctypes/cfield.c Tue Mar 31 13:43:27 2009 -0500 @@ -6,6 +6,15 @@ #endif #include "ctypes.h" +static void pymem_destructor(PyObject *ptr) +{ + void *p = PyCObject_AsVoidPtr(ptr, "_ctypes_field_mem"); + if (p) { + PyMem_Free(p); + } +} + + /******************************************************************/ /* CField_Type @@ -1477,7 +1486,7 @@ return PyErr_NoMemory(); } memset(buffer, 0, size); - keep = PyCObject_FromVoidPtr(buffer, PyMem_Free); + keep = PyCObject_FromVoidPtr(pymem_destructor, buffer, "_ctypes_field_mem"); if (!keep) { Py_DECREF(value); PyMem_Free(buffer); diff -r 9c735dbeb978 Modules/_cursesmodule.c --- a/Modules/_cursesmodule.c Mon Mar 30 15:53:06 2009 -0500 +++ b/Modules/_cursesmodule.c Tue Mar 31 13:43:27 2009 -0500 @@ -2828,7 +2828,7 @@ ModDict = d; /* For PyCurses_InitScr to use later */ /* Add a CObject for the C API */ - c_api_object = PyCObject_FromVoidPtr((void *)PyCurses_API, NULL); + c_api_object = PyCObject_FromVoidPtr(NULL, (void *)PyCurses_API, "PyCurses_API"); PyDict_SetItemString(d, "_C_API", c_api_object); Py_DECREF(c_api_object); diff -r 9c735dbeb978 Modules/_elementtree.c --- a/Modules/_elementtree.c Mon Mar 30 15:53:06 2009 -0500 +++ b/Modules/_elementtree.c Tue Mar 31 13:43:27 2009 -0500 @@ -2809,7 +2809,7 @@ #if defined(USE_PYEXPAT_CAPI) /* link against pyexpat, if possible */ - capi = PyCObject_Import("pyexpat", "expat_CAPI"); + capi = PyCObject_Import("pyexpat", "expat_CAPI", "expat_CAPI"); if (capi && strcmp(capi->magic, PyExpat_CAPI_MAGIC) == 0 && capi->size <= sizeof(*expat_capi) && diff -r 9c735dbeb978 Modules/cjkcodecs/cjkcodecs.h --- a/Modules/cjkcodecs/cjkcodecs.h Mon Mar 30 15:53:06 2009 -0500 +++ b/Modules/cjkcodecs/cjkcodecs.h Tue Mar 31 13:43:27 2009 -0500 @@ -284,7 +284,7 @@ return NULL; } - codecobj = PyCObject_FromVoidPtr((void *)codec, NULL); + codecobj = PyCObject_FromVoidPtr(NULL, (void *)codec, "multibytecodec_CAPI"); if (codecobj == NULL) return NULL; @@ -309,7 +309,7 @@ int r; strcpy(mhname + sizeof("__map_") - 1, h->charset); r = PyModule_AddObject(module, mhname, - PyCObject_FromVoidPtr((void *)h, NULL)); + PyCObject_FromVoidPtr(NULL, (void *)h, "multibytecodec_CAPI")); if (r == -1) return -1; } @@ -371,7 +371,7 @@ } else { struct dbcs_map *map; - map = PyCObject_AsVoidPtr(o); + map = PyCObject_AsVoidPtr(o, "multibytecodec_CAPI"); if (encmap != NULL) *encmap = map->encmap; if (decmap != NULL) diff -r 9c735dbeb978 Modules/cjkcodecs/multibytecodec.c --- a/Modules/cjkcodecs/multibytecodec.c Mon Mar 30 15:53:06 2009 -0500 +++ b/Modules/cjkcodecs/multibytecodec.c Tue Mar 31 13:43:27 2009 -0500 @@ -1798,7 +1798,7 @@ return NULL; } - codec = PyCObject_AsVoidPtr(arg); + codec = PyCObject_AsVoidPtr(arg, "multibytecodec_CAPI"); if (codec->codecinit != NULL && codec->codecinit(codec->config) != 0) return NULL; diff -r 9c735dbeb978 Modules/datetimemodule.c --- a/Modules/datetimemodule.c Mon Mar 30 15:53:06 2009 -0500 +++ b/Modules/datetimemodule.c Tue Mar 31 13:43:27 2009 -0500 @@ -4792,8 +4792,7 @@ Py_INCREF(&PyDateTime_TZInfoType); PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType); - x = PyCObject_FromVoidPtrAndDesc(&CAPI, (void*) DATETIME_API_MAGIC, - NULL); + x = PyCObject_FromVoidPtr(NULL, &CAPI, "datetime_CAPI"); if (x == NULL) return NULL; PyModule_AddObject(m, "datetime_CAPI", x); diff -r 9c735dbeb978 Modules/pyexpat.c --- a/Modules/pyexpat.c Mon Mar 30 15:53:06 2009 -0500 +++ b/Modules/pyexpat.c Tue Mar 31 13:43:27 2009 -0500 @@ -1988,7 +1988,7 @@ capi.SetUserData = XML_SetUserData; /* export as cobject */ - capi_object = PyCObject_FromVoidPtr(&capi, NULL); + capi_object = PyCObject_FromVoidPtr(NULL, &capi, "expat_CAPI"); if (capi_object) PyModule_AddObject(m, "expat_CAPI", capi_object); return m; diff -r 9c735dbeb978 Modules/socketmodule.c --- a/Modules/socketmodule.c Mon Mar 30 15:53:06 2009 -0500 +++ b/Modules/socketmodule.c Tue Mar 31 13:43:27 2009 -0500 @@ -4231,7 +4231,7 @@ /* Export C API */ if (PyModule_AddObject(m, PySocket_CAPI_NAME, - PyCObject_FromVoidPtr((void *)&PySocketModuleAPI, NULL) + PyCObject_FromVoidPtr(NULL, (void *)&PySocketModuleAPI, "socket_CAPI") ) != 0) return NULL; diff -r 9c735dbeb978 Modules/socketmodule.h --- a/Modules/socketmodule.h Mon Mar 30 15:53:06 2009 -0500 +++ b/Modules/socketmodule.h Tue Mar 31 13:43:27 2009 -0500 @@ -241,7 +241,7 @@ goto onError; Py_DECREF(mod); DPRINTF(" API object %s found\n", apiname); - api = PyCObject_AsVoidPtr(v); + api = PyCObject_AsVoidPtr(v, "socket_CAPI"); if (api == NULL) goto onError; Py_DECREF(v); diff -r 9c735dbeb978 Modules/unicodedata.c --- a/Modules/unicodedata.c Mon Mar 30 15:53:06 2009 -0500 +++ b/Modules/unicodedata.c Tue Mar 31 13:43:27 2009 -0500 @@ -1222,7 +1222,7 @@ PyModule_AddObject(m, "ucd_3_2_0", v); /* Export C API */ - v = PyCObject_FromVoidPtr((void *) &hashAPI, NULL); + v = PyCObject_FromVoidPtr(NULL, (void *) &hashAPI, "unicode_name_CAPI"); if (v != NULL) PyModule_AddObject(m, "ucnhash_CAPI", v); return m; diff -r 9c735dbeb978 Objects/cobject.c --- a/Objects/cobject.c Mon Mar 30 15:53:06 2009 -0500 +++ b/Objects/cobject.c Tue Mar 31 13:43:27 2009 -0500 @@ -1,119 +1,209 @@ - /* Wrap void* pointers to be passed between C modules */ #include "Python.h" +/* Internal structure of PyCObject */ +struct PyCObject { + PyObject_HEAD + void *cobject; + const char *type; + void *context; + PyCObject_Destructor destructor; +}; -/* Declarations for objects of type PyCObject */ -typedef void (*destructor1)(void *); -typedef void (*destructor2)(void *, void*); - -PyObject * -PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *)) +static PyObject * +_PyCObject_FromVoidPtrWithContext(PyCObject_Destructor destructor, + void *cobject, const char *type, + void *context, + const char *nullcobjecterror, + const char *invalidtypeerror, + const char *allocationerror + ) { PyCObject *self; + if (!cobject) { + PyErr_SetString(PyExc_TypeError, nullcobjecterror); + return NULL; + } + + if (!type || !*type) { + PyErr_SetString(PyExc_TypeError, invalidtypeerror); + return NULL; + } + self = PyObject_NEW(PyCObject, &PyCObject_Type); - if (self == NULL) + if (self == NULL) { + PyErr_SetString(PyExc_TypeError, allocationerror); return NULL; - self->cobject=cobj; - self->destructor=destr; - self->desc=NULL; + } + + self->cobject = cobject; + self->destructor = destructor; + self->type = type; + self->context = context; return (PyObject *)self; } +#define FROM_VOID_PTR_WITH_CONTEXT(destructor, cobject, type, context, name) \ + (_PyCObject_FromVoidPtrWithContext(destructor, cobject, type, context, \ + name " called with null cobject pointer", \ + name " called with invalid type string", \ + name " memory allocation error")) + + +PyObject *PyCObject_FromVoidPtrWithContext(PyCObject_Destructor destructor, + void *cobject, const char *type, + void *context) +{ + return FROM_VOID_PTR_WITH_CONTEXT(destructor, cobject, type, context, "PyCObject_FromVoidPtrWithContext"); +} + PyObject * -PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc, - void (*destr)(void *, void *)) +PyCObject_FromVoidPtr(PyCObject_Destructor destructor, void *cobject, const char *type) +{ + return FROM_VOID_PTR_WITH_CONTEXT(destructor, cobject, type, NULL, "PyCObject_FromVoidPtr"); +} + + +static int _is_legal_cobject(PyObject *self, const char *nonCobject, const char *nullPointer) +{ + if (self) { + if (self->ob_type == &PyCObject_Type) + return 1; + PyErr_SetString(PyExc_TypeError, nonCobject); + } else { + PyErr_SetString(PyExc_TypeError, nullPointer); + } + return 0; +} + +#define is_legal_cobject(self, name) \ + (_is_legal_cobject(self, \ + name " called with invalid object", \ + name " called with null pointer")) + +static int _is_legal_cobject_and_type(PyObject *p, const char *type, const char *nonCobject, const char *nullPointer, const char *invalidType, const char *incorrectType) { PyCObject *self; + if (!_is_legal_cobject(p, nonCobject, nullPointer)) { + return 0; + } + self = (PyCObject *)p; + if (!type || !*type) { + PyErr_SetString(PyExc_TypeError, invalidType); + return 0; + } + if (strcmp(type, self->type)) { + PyErr_SetString(PyExc_TypeError, incorrectType); + return 0; + } + return 1; +} - if (!desc) { - PyErr_SetString(PyExc_TypeError, - "PyCObject_FromVoidPtrAndDesc called with null" - " description"); +#define is_legal_cobject_and_type(self, type, name) \ + (_is_legal_cobject_and_type(self, type, \ + name " called with invalid object", \ + name " called with null pointer", \ + name " called with invalid type", \ + name " called with incorrect type")) + + +void * +PyCObject_AsVoidPtr(PyObject *self, const char *type) +{ + if (!is_legal_cobject_and_type(self, type, "PyCObject_AsVoidPtr")) { return NULL; } - self = PyObject_NEW(PyCObject, &PyCObject_Type); - if (self == NULL) + return ((PyCObject *)self)->cobject; +} + +const char * +PyCObject_GetType(PyObject *self) +{ + if (!is_legal_cobject(self, "PyCObject_GetType")) { return NULL; - self->cobject = cobj; - self->destructor = (destructor1)destr; - self->desc = desc; - - return (PyObject *)self; + } + return ((PyCObject *)self)->type; } void * -PyCObject_AsVoidPtr(PyObject *self) +PyCObject_GetContext(PyObject *self) { - if (self) { - if (self->ob_type == &PyCObject_Type) - return ((PyCObject *)self)->cobject; - PyErr_SetString(PyExc_TypeError, - "PyCObject_AsVoidPtr with non-C-object"); + if (!is_legal_cobject(self, "PyCObject_GetContext")) { + return NULL; } - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_TypeError, - "PyCObject_AsVoidPtr called with null pointer"); - return NULL; + return ((PyCObject *)self)->context; } void * -PyCObject_GetDesc(PyObject *self) -{ - if (self) { - if (self->ob_type == &PyCObject_Type) - return ((PyCObject *)self)->desc; - PyErr_SetString(PyExc_TypeError, - "PyCObject_GetDesc with non-C-object"); - } - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_TypeError, - "PyCObject_GetDesc called with null pointer"); - return NULL; -} - -void * -PyCObject_Import(char *module_name, char *name) +PyCObject_Import(const char *module_name, const char *name, const char *type) { PyObject *m, *c; void *r = NULL; if ((m = PyImport_ImportModule(module_name))) { if ((c = PyObject_GetAttrString(m,name))) { - r = PyCObject_AsVoidPtr(c); + r = PyCObject_AsVoidPtr(c, type); Py_DECREF(c); - } + } Py_DECREF(m); } return r; } int -PyCObject_SetVoidPtr(PyObject *self, void *cobj) +PyCObject_SetVoidPtr(PyObject *self, void *cobject, const char *type) { - PyCObject* cself = (PyCObject*)self; - if (cself == NULL || !PyCObject_Check(cself) || - cself->destructor != NULL) { - PyErr_SetString(PyExc_TypeError, - "Invalid call to PyCObject_SetVoidPtr"); - return 0; + if (!is_legal_cobject_and_type(self, type, "PyCObject_SetVoidPtr")) { + return -1; } - cself->cobject = cobj; + + ((PyCObject *)self)->cobject = cobject; return 1; } +int +PyCObject_SetDestructor(PyObject *self, PyCObject_Destructor destructor) +{ + if (!is_legal_cobject(self, "PyCObject_SetDestructor")) { + return -1; + } + + ((PyCObject *)self)->destructor = destructor; + return 1; +} + +int +PyCObject_SetType(PyObject *self, const char *type) +{ + if (!is_legal_cobject(self, "PyCObject_SetType")) { + return -1; + } + + ((PyCObject *)self)->type = type; + return 0; +} + +int +PyCObject_SetContext(PyObject *self, void *context) +{ + if (!is_legal_cobject(self, "PyCObject_SetContext")) { + return -1; + } + + ((PyCObject *)self)->context = context; + return 0; +} + static void -PyCObject_dealloc(PyCObject *self) +PyCObject_dealloc(PyObject *ptr) { + PyCObject *self = (PyCObject *)ptr; if (self->destructor) { - if(self->desc) - ((destructor2)(self->destructor))(self->cobject, self->desc); - else - (self->destructor)(self->cobject); + self->destructor(ptr); } PyObject_DEL(self); } diff -r 9c735dbeb978 Objects/unicodeobject.c --- a/Objects/unicodeobject.c Mon Mar 30 15:53:06 2009 -0500 +++ b/Objects/unicodeobject.c Tue Mar 31 13:43:27 2009 -0500 @@ -3257,7 +3257,7 @@ Py_DECREF(m); if (api == NULL) goto ucnhashError; - ucnhash_CAPI = (_PyUnicode_Name_CAPI *)PyCObject_AsVoidPtr(api); + ucnhash_CAPI = (_PyUnicode_Name_CAPI *)PyCObject_AsVoidPtr(api, "unicode_name_CAPI"); Py_DECREF(api); if (ucnhash_CAPI == NULL) goto ucnhashError; diff -r 9c735dbeb978 Python/compile.c --- a/Python/compile.c Mon Mar 30 15:53:06 2009 -0500 +++ b/Python/compile.c Tue Mar 31 13:43:27 2009 -0500 @@ -506,7 +506,7 @@ /* Push the old compiler_unit on the stack. */ if (c->u) { - PyObject *wrapper = PyCObject_FromVoidPtr(c->u, NULL); + PyObject *wrapper = PyCObject_FromVoidPtr(NULL, c->u, "compiler_unit"); if (!wrapper || PyList_Append(c->c_stack, wrapper) < 0) { Py_XDECREF(wrapper); compiler_unit_free(u); @@ -537,7 +537,7 @@ n = PyList_GET_SIZE(c->c_stack) - 1; if (n >= 0) { wrapper = PyList_GET_ITEM(c->c_stack, n); - c->u = (struct compiler_unit *)PyCObject_AsVoidPtr(wrapper); + c->u = (struct compiler_unit *)PyCObject_AsVoidPtr(wrapper, "compiler_unit"); assert(c->u); /* we are deleting from a list so this really shouldn't fail */ if (PySequence_DelItem(c->c_stack, n) < 0) diff -r 9c735dbeb978 Python/getargs.c --- a/Python/getargs.c Mon Mar 30 15:53:06 2009 -0500 +++ b/Python/getargs.c Tue Mar 31 13:43:27 2009 -0500 @@ -140,19 +140,25 @@ /* Handle cleanup of allocated memory in case of exception */ static void -cleanup_ptr(void *ptr) +cleanup_ptr(PyObject *self) { - PyMem_FREE(ptr); + void *ptr = PyCObject_AsVoidPtr(self, "getargs_CAPI"); + if (ptr) { + PyMem_FREE(ptr); + } } static void -cleanup_buffer(void *ptr) +cleanup_buffer(PyObject *self) { - PyBuffer_Release((Py_buffer *) ptr); + Py_buffer *ptr = (Py_buffer *)PyCObject_AsVoidPtr(self, "getargs_CAPI"); + if (ptr) { + PyBuffer_Release(ptr); + } } static int -addcleanup(void *ptr, PyObject **freelist, void (*destr)(void *)) +addcleanup(void *ptr, PyObject **freelist, PyCObject_Destructor destr) { PyObject *cobj; if (!*freelist) { @@ -162,7 +168,7 @@ return -1; } } - cobj = PyCObject_FromVoidPtr(ptr, destr); + cobj = PyCObject_FromVoidPtr(destr, ptr, "getargs_CAPI"); if (!cobj) { destr(ptr); return -1; @@ -183,8 +189,7 @@ don't get called. */ Py_ssize_t len = PyList_GET_SIZE(freelist), i; for (i = 0; i < len; i++) - ((PyCObject *) PyList_GET_ITEM(freelist, i)) - ->destructor = NULL; + PyCObject_SetDestructor(PyList_GET_ITEM(freelist, i), NULL); } Py_XDECREF(freelist); return retval;