mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
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.
This commit is contained in:
parent
aac8c58f0b
commit
b2a57722a8
4 changed files with 71 additions and 3 deletions
|
@ -106,6 +106,7 @@ PyObject *PyMac_BuildFSRef(FSRef *); /* Convert FSRef to PyObject */
|
||||||
|
|
||||||
/* AE exports */
|
/* AE exports */
|
||||||
extern PyObject *AEDesc_New(AppleEvent *); /* XXXX Why passed by address?? */
|
extern PyObject *AEDesc_New(AppleEvent *); /* XXXX Why passed by address?? */
|
||||||
|
extern PyObject *AEDesc_NewBorrowed(AppleEvent *);
|
||||||
extern int AEDesc_Convert(PyObject *, AppleEvent *);
|
extern int AEDesc_Convert(PyObject *, AppleEvent *);
|
||||||
|
|
||||||
/* Cm exports */
|
/* Cm exports */
|
||||||
|
|
|
@ -35,6 +35,7 @@ extern PyObject *_AEDesc_New(AEDesc *);
|
||||||
extern int _AEDesc_Convert(PyObject *, AEDesc *);
|
extern int _AEDesc_Convert(PyObject *, AEDesc *);
|
||||||
|
|
||||||
#define AEDesc_New _AEDesc_New
|
#define AEDesc_New _AEDesc_New
|
||||||
|
#define AEDesc_NewBorrowed _AEDesc_NewBorrowed
|
||||||
#define AEDesc_Convert _AEDesc_Convert
|
#define AEDesc_Convert _AEDesc_Convert
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -70,6 +71,7 @@ PyTypeObject AEDesc_Type;
|
||||||
typedef struct AEDescObject {
|
typedef struct AEDescObject {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
AEDesc ob_itself;
|
AEDesc ob_itself;
|
||||||
|
int ob_owned;
|
||||||
} AEDescObject;
|
} AEDescObject;
|
||||||
|
|
||||||
PyObject *AEDesc_New(AEDesc *itself)
|
PyObject *AEDesc_New(AEDesc *itself)
|
||||||
|
@ -78,6 +80,7 @@ PyObject *AEDesc_New(AEDesc *itself)
|
||||||
it = PyObject_NEW(AEDescObject, &AEDesc_Type);
|
it = PyObject_NEW(AEDescObject, &AEDesc_Type);
|
||||||
if (it == NULL) return NULL;
|
if (it == NULL) return NULL;
|
||||||
it->ob_itself = *itself;
|
it->ob_itself = *itself;
|
||||||
|
it->ob_owned = 1;
|
||||||
return (PyObject *)it;
|
return (PyObject *)it;
|
||||||
}
|
}
|
||||||
int AEDesc_Convert(PyObject *v, AEDesc *p_itself)
|
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)
|
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);
|
self->ob_type->tp_free((PyObject *)self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -759,6 +762,20 @@ static PyObject *AEDesc_AEResolve(AEDescObject *_self, PyObject *_args)
|
||||||
return _res;
|
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[] = {
|
static PyMethodDef AEDesc_methods[] = {
|
||||||
{"AECoerceDesc", (PyCFunction)AEDesc_AECoerceDesc, 1,
|
{"AECoerceDesc", (PyCFunction)AEDesc_AECoerceDesc, 1,
|
||||||
PyDoc_STR("(DescType toType) -> (AEDesc result)")},
|
PyDoc_STR("(DescType toType) -> (AEDesc result)")},
|
||||||
|
@ -816,6 +833,8 @@ static PyMethodDef AEDesc_methods[] = {
|
||||||
PyDoc_STR("() -> None")},
|
PyDoc_STR("() -> None")},
|
||||||
{"AEResolve", (PyCFunction)AEDesc_AEResolve, 1,
|
{"AEResolve", (PyCFunction)AEDesc_AEResolve, 1,
|
||||||
PyDoc_STR("(short callbackFlags) -> (AEDesc theToken)")},
|
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}
|
{NULL, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1413,6 +1432,17 @@ GenericEventHandler(const AppleEvent *request, AppleEvent *reply, refcontype ref
|
||||||
return noErr;
|
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)
|
void init_AE(void)
|
||||||
{
|
{
|
||||||
|
@ -1424,6 +1454,7 @@ void init_AE(void)
|
||||||
upp_AEIdleProc = NewAEIdleUPP(AEIdleProc);
|
upp_AEIdleProc = NewAEIdleUPP(AEIdleProc);
|
||||||
upp_GenericEventHandler = NewAEEventHandlerUPP(GenericEventHandler);
|
upp_GenericEventHandler = NewAEEventHandlerUPP(GenericEventHandler);
|
||||||
PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_New);
|
PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_New);
|
||||||
|
PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_NewBorrowed);
|
||||||
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(AEDesc, AEDesc_Convert);
|
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(AEDesc, AEDesc_Convert);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,7 @@ extern PyObject *_AEDesc_New(AEDesc *);
|
||||||
extern int _AEDesc_Convert(PyObject *, AEDesc *);
|
extern int _AEDesc_Convert(PyObject *, AEDesc *);
|
||||||
|
|
||||||
#define AEDesc_New _AEDesc_New
|
#define AEDesc_New _AEDesc_New
|
||||||
|
#define AEDesc_NewBorrowed _AEDesc_NewBorrowed
|
||||||
#define AEDesc_Convert _AEDesc_Convert
|
#define AEDesc_Convert _AEDesc_Convert
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -155,12 +156,24 @@ GenericEventHandler(const AppleEvent *request, AppleEvent *reply, refcontype ref
|
||||||
Py_DECREF(res);
|
Py_DECREF(res);
|
||||||
return noErr;
|
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 + """
|
initstuff = initstuff + """
|
||||||
upp_AEIdleProc = NewAEIdleUPP(AEIdleProc);
|
upp_AEIdleProc = NewAEIdleUPP(AEIdleProc);
|
||||||
upp_GenericEventHandler = NewAEEventHandlerUPP(GenericEventHandler);
|
upp_GenericEventHandler = NewAEEventHandlerUPP(GenericEventHandler);
|
||||||
PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_New);
|
PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_New);
|
||||||
|
PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_NewBorrowed);
|
||||||
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(AEDesc, AEDesc_Convert);
|
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)
|
GlobalObjectDefinition.__init__(self, name, prefix or name, itselftype or name)
|
||||||
self.argref = "*"
|
self.argref = "*"
|
||||||
|
|
||||||
def outputFreeIt(self, name):
|
def outputStructMembers(self):
|
||||||
Output("AEDisposeDesc(&%s);", name)
|
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')
|
aedescobject = AEDescDefinition('AEDesc')
|
||||||
module.addobject(aedescobject)
|
module.addobject(aedescobject)
|
||||||
|
@ -209,6 +230,20 @@ aedescmethods = []
|
||||||
execfile('aegen.py')
|
execfile('aegen.py')
|
||||||
##execfile('aedatamodelgen.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 functions: module.add(f)
|
||||||
for f in aedescmethods: aedescobject.add(f)
|
for f in aedescmethods: aedescobject.add(f)
|
||||||
|
|
||||||
|
|
|
@ -534,6 +534,7 @@ GLUE_NEW(FSRef *, PyMac_BuildFSRef, "macfs")
|
||||||
GLUE_CONVERT(FSRef, PyMac_GetFSRef, "macfs")
|
GLUE_CONVERT(FSRef, PyMac_GetFSRef, "macfs")
|
||||||
|
|
||||||
GLUE_NEW(AppleEvent *, AEDesc_New, "Carbon.AE") /* XXXX Why by address? */
|
GLUE_NEW(AppleEvent *, AEDesc_New, "Carbon.AE") /* XXXX Why by address? */
|
||||||
|
GLUE_NEW(AppleEvent *, AEDesc_NewBorrowed, "Carbon.AE")
|
||||||
GLUE_CONVERT(AppleEvent, AEDesc_Convert, "Carbon.AE")
|
GLUE_CONVERT(AppleEvent, AEDesc_Convert, "Carbon.AE")
|
||||||
|
|
||||||
GLUE_NEW(Component, CmpObj_New, "Carbon.Cm")
|
GLUE_NEW(Component, CmpObj_New, "Carbon.Cm")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue