diff options
author | Jack Jansen <jack.jansen@cwi.nl> | 2003-01-17 23:11:17 (GMT) |
---|---|---|
committer | Jack Jansen <jack.jansen@cwi.nl> | 2003-01-17 23:11:17 (GMT) |
commit | b2a57722a8ed9ba035707a50023105cdbfcfdaae (patch) | |
tree | 2d66a8b55a95b69eb1636c41ba4c0bab821769ae /Mac | |
parent | aac8c58f0b053fba8ae8b042bcc3afef47fed943 (diff) | |
download | cpython-b2a57722a8ed9ba035707a50023105cdbfcfdaae.zip cpython-b2a57722a8ed9ba035707a50023105cdbfcfdaae.tar.gz cpython-b2a57722a8ed9ba035707a50023105cdbfcfdaae.tar.bz2 |
It turns out that some calls return AEDesc records that are "borrowed",
the AEDesc data shouldn't be disposed when the Python object is.
Added a C call AEDesc_NewBorrowed() to create these objects and a Python
method old=AEDesc.AutoDispose(onoff) to change auto-dispose state.
Diffstat (limited to 'Mac')
-rw-r--r-- | Mac/Modules/ae/_AEmodule.c | 33 | ||||
-rw-r--r-- | Mac/Modules/ae/aesupport.py | 39 |
2 files changed, 69 insertions, 3 deletions
diff --git a/Mac/Modules/ae/_AEmodule.c b/Mac/Modules/ae/_AEmodule.c index bcb24a7..c5445dc 100644 --- a/Mac/Modules/ae/_AEmodule.c +++ b/Mac/Modules/ae/_AEmodule.c @@ -35,6 +35,7 @@ extern PyObject *_AEDesc_New(AEDesc *); extern int _AEDesc_Convert(PyObject *, AEDesc *); #define AEDesc_New _AEDesc_New +#define AEDesc_NewBorrowed _AEDesc_NewBorrowed #define AEDesc_Convert _AEDesc_Convert #endif @@ -70,6 +71,7 @@ PyTypeObject AEDesc_Type; typedef struct AEDescObject { PyObject_HEAD AEDesc ob_itself; + int ob_owned; } AEDescObject; PyObject *AEDesc_New(AEDesc *itself) @@ -78,6 +80,7 @@ PyObject *AEDesc_New(AEDesc *itself) it = PyObject_NEW(AEDescObject, &AEDesc_Type); if (it == NULL) return NULL; it->ob_itself = *itself; + it->ob_owned = 1; return (PyObject *)it; } int AEDesc_Convert(PyObject *v, AEDesc *p_itself) @@ -93,7 +96,7 @@ int AEDesc_Convert(PyObject *v, AEDesc *p_itself) static void AEDesc_dealloc(AEDescObject *self) { - AEDisposeDesc(&self->ob_itself); + if (self->ob_owned) AEDisposeDesc(&self->ob_itself); self->ob_type->tp_free((PyObject *)self); } @@ -759,6 +762,20 @@ static PyObject *AEDesc_AEResolve(AEDescObject *_self, PyObject *_args) return _res; } +static PyObject *AEDesc_AutoDispose(AEDescObject *_self, PyObject *_args) +{ + PyObject *_res = NULL; + + int onoff, old; + if (!PyArg_ParseTuple(_args, "i", &onoff)) + return NULL; + old = _self->ob_owned; + _self->ob_owned = onoff; + _res = Py_BuildValue("i", old); + return _res; + +} + static PyMethodDef AEDesc_methods[] = { {"AECoerceDesc", (PyCFunction)AEDesc_AECoerceDesc, 1, PyDoc_STR("(DescType toType) -> (AEDesc result)")}, @@ -816,6 +833,8 @@ static PyMethodDef AEDesc_methods[] = { PyDoc_STR("() -> None")}, {"AEResolve", (PyCFunction)AEDesc_AEResolve, 1, PyDoc_STR("(short callbackFlags) -> (AEDesc theToken)")}, + {"AutoDispose", (PyCFunction)AEDesc_AutoDispose, 1, + PyDoc_STR("(int)->int. Automatically AEDisposeDesc the object on Python object cleanup")}, {NULL, NULL, 0} }; @@ -1413,6 +1432,17 @@ GenericEventHandler(const AppleEvent *request, AppleEvent *reply, refcontype ref return noErr; } +PyObject *AEDesc_NewBorrowed(AEDesc *itself) +{ + PyObject *it; + + it = AEDesc_New(itself); + if (it) + ((AEDescObject *)it)->ob_owned = 0; + return (PyObject *)it; +} + + void init_AE(void) { @@ -1424,6 +1454,7 @@ void init_AE(void) upp_AEIdleProc = NewAEIdleUPP(AEIdleProc); upp_GenericEventHandler = NewAEEventHandlerUPP(GenericEventHandler); PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_New); + PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_NewBorrowed); PyMac_INIT_TOOLBOX_OBJECT_CONVERT(AEDesc, AEDesc_Convert); diff --git a/Mac/Modules/ae/aesupport.py b/Mac/Modules/ae/aesupport.py index 16b9c5d..89a571b 100644 --- a/Mac/Modules/ae/aesupport.py +++ b/Mac/Modules/ae/aesupport.py @@ -97,6 +97,7 @@ extern PyObject *_AEDesc_New(AEDesc *); extern int _AEDesc_Convert(PyObject *, AEDesc *); #define AEDesc_New _AEDesc_New +#define AEDesc_NewBorrowed _AEDesc_NewBorrowed #define AEDesc_Convert _AEDesc_Convert #endif @@ -155,12 +156,24 @@ GenericEventHandler(const AppleEvent *request, AppleEvent *reply, refcontype ref Py_DECREF(res); return noErr; } + +PyObject *AEDesc_NewBorrowed(AEDesc *itself) +{ + PyObject *it; + + it = AEDesc_New(itself); + if (it) + ((AEDescObject *)it)->ob_owned = 0; + return (PyObject *)it; +} + """ initstuff = initstuff + """ upp_AEIdleProc = NewAEIdleUPP(AEIdleProc); upp_GenericEventHandler = NewAEEventHandlerUPP(GenericEventHandler); PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_New); + PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_NewBorrowed); PyMac_INIT_TOOLBOX_OBJECT_CONVERT(AEDesc, AEDesc_Convert); """ @@ -197,8 +210,16 @@ class AEDescDefinition(PEP253Mixin, GlobalObjectDefinition): GlobalObjectDefinition.__init__(self, name, prefix or name, itselftype or name) self.argref = "*" - def outputFreeIt(self, name): - Output("AEDisposeDesc(&%s);", name) + def outputStructMembers(self): + GlobalObjectDefinition.outputStructMembers(self) + Output("int ob_owned;") + + def outputInitStructMembers(self): + GlobalObjectDefinition.outputInitStructMembers(self) + Output("it->ob_owned = 1;") + + def outputCleanupStructMembers(self): + Output("if (self->ob_owned) AEDisposeDesc(&self->ob_itself);") aedescobject = AEDescDefinition('AEDesc') module.addobject(aedescobject) @@ -209,6 +230,20 @@ aedescmethods = [] execfile('aegen.py') ##execfile('aedatamodelgen.py') +# Manual generator +AutoDispose_body = """ +int onoff, old; +if (!PyArg_ParseTuple(_args, "i", &onoff)) + return NULL; +old = _self->ob_owned; +_self->ob_owned = onoff; +_res = Py_BuildValue("i", old); +return _res; +""" +f = ManualGenerator("AutoDispose", AutoDispose_body) +f.docstring = lambda: "(int)->int. Automatically AEDisposeDesc the object on Python object cleanup" +aedescmethods.append(f) + for f in functions: module.add(f) for f in aedescmethods: aedescobject.add(f) |