Commit 7ea258d2 authored by Jim Fulton's avatar Jim Fulton

Added lots of new machinery to handle wrapping of acquired objects.

parent 1730fc9e
/* /*
$Id: Acquisition.c,v 1.15 1998/01/21 19:00:48 jim Exp $ $Id: Acquisition.c,v 1.16 1998/03/23 20:23:35 jim Exp $
Acquisition Wrappers -- Implementation of acquisition through wrappers Acquisition Wrappers -- Implementation of acquisition through wrappers
...@@ -153,6 +153,7 @@ staticforward PyExtensionClass Wrappertype, XaqWrappertype; ...@@ -153,6 +153,7 @@ staticforward PyExtensionClass Wrappertype, XaqWrappertype;
#define isWrapper(O) ((O)->ob_type==(PyTypeObject*)&Wrappertype || \ #define isWrapper(O) ((O)->ob_type==(PyTypeObject*)&Wrappertype || \
(O)->ob_type==(PyTypeObject*)&XaqWrappertype) (O)->ob_type==(PyTypeObject*)&XaqWrappertype)
#define WRAPPER(O) ((Wrapper*)(O))
static PyObject * static PyObject *
Wrapper__init__(Wrapper *self, PyObject *args) Wrapper__init__(Wrapper *self, PyObject *args)
...@@ -172,6 +173,23 @@ Wrapper__init__(Wrapper *self, PyObject *args) ...@@ -172,6 +173,23 @@ Wrapper__init__(Wrapper *self, PyObject *args)
/* ---------- */ /* ---------- */
static PyObject *
__of__(PyObject *inst, PyObject *parent)
{
PyObject *r, *t;
UNLESS(r=PyObject_GetAttr(inst, py__of__)) return NULL;
UNLESS(t=PyTuple_New(1)) goto err;
PyTuple_SET_ITEM(t,0,parent);
ASSIGN(r,PyObject_CallObject(r,t));
PyTuple_SET_ITEM(t,0,NULL);
Py_DECREF(t);
return r;
err:
Py_DECREF(r);
return NULL;
}
static PyObject * static PyObject *
newWrapper(PyObject *obj, PyObject *container, PyTypeObject *Wrappertype) newWrapper(PyObject *obj, PyObject *container, PyTypeObject *Wrappertype)
{ {
...@@ -205,14 +223,57 @@ Wrapper_dealloc(Wrapper *self) ...@@ -205,14 +223,57 @@ Wrapper_dealloc(Wrapper *self)
} }
static PyObject * static PyObject *
Wrapper_getattro(Wrapper *self, PyObject *oname) Wrapper_special(Wrapper *self, char *name, PyObject *oname)
{
PyObject *r=0;
if(strcmp(name,"base")==0)
{
if(self->obj)
{
r=self->obj;
while(isWrapper(r) && WRAPPER(r)->obj) r=WRAPPER(r)->obj;
}
else r=Py_None;
Py_INCREF(r);
return r;
}
if(strcmp(name,"parent")==0)
{
if(self->container) r=self->container;
else r=Py_None;
Py_INCREF(r);
return r;
}
if(strcmp(name,"self")==0)
{
if(self->obj) r=self->obj;
else r=Py_None;
Py_INCREF(r);
return r;
}
if(strcmp(name,"acquire")==0)
{
return Py_FindAttr(OBJECT(self),oname);
}
}
static PyObject *
Wrapper_acquire(Wrapper *self, PyObject *oname,
PyObject *filter, PyObject *extra, PyObject *orig,
int sob, int sco)
{ {
PyObject *r; PyObject *r;
char *name; char *name;
int ir;
if(self->obj && (r=PyObject_GetAttr(self->obj,oname))) name=PyString_AsString(oname);
if(*name++=='a' && *name++=='q' && *name++=='_'
&& (r=Wrapper_special(self, name, oname))) return r;
if(sob && self->obj)
{ {
if(r != Acquired) if(r=PyObject_GetAttr(self->obj,oname))
{ {
if(r->ob_type==self->ob_type) if(r->ob_type==self->ob_type)
{ {
...@@ -222,72 +283,97 @@ Wrapper_getattro(Wrapper *self, PyObject *oname) ...@@ -222,72 +283,97 @@ Wrapper_getattro(Wrapper *self, PyObject *oname)
ASSIGN(((Wrapper*)r)->container,OBJECT(self)); ASSIGN(((Wrapper*)r)->container,OBJECT(self));
} }
else else
ASSIGN(r, newWrapper(((Wrapper*)r)->obj, ASSIGN(r,newWrapper(((Wrapper*)r)->obj,
OBJECT(self),self->ob_type)); OBJECT(self), self->ob_type));
} }
else if(PyECMethod_Check(r) && PyECMethod_Self(r)==self->obj) else if(PyECMethod_Check(r) && PyECMethod_Self(r)==self->obj)
ASSIGN(r,PyECMethod_New(r,OBJECT(self))); ASSIGN(r,PyECMethod_New(r,OBJECT(self)));
else if(has__of__(r)) else if(has__of__(r)) ASSIGN(r,__of__(r,OBJECT(self)));
ASSIGN(r,CallMethodO(r,py__of__,Build("(O)", self), NULL)); if(filter)
return r; switch(apply_filter(filter,OBJECT(self),oname,r,extra,orig))
{
case -1: return NULL;
case 1: return r;
}
else return r;
} }
PyErr_Clear();
} }
if(self->obj) PyErr_Clear();
if(sco && self->container)
name=PyString_AsString(oname); {
if(*name != '_' if(isWrapper(self->container))
#ifdef IMPLICIT_ACQUIRE___ROLES__
|| strcmp(name,"__roles__")==0
#endif
|| r==Acquired
)
{
if(*name++=='a' && *name++=='q' && *name++=='_')
{ {
if(strcmp(name,"acquire")==0) if(self->obj && self->obj->ob_type == (PyTypeObject*)&Wrappertype)
{ {
return Py_FindAttr(OBJECT(self),oname); if(WRAPPER(self->obj)->container==
} WRAPPER(self->container)->container) sob=1, sco=0;
if(strcmp(name,"parent")==0) else if(WRAPPER(self->obj)->container==
{ WRAPPER(self->container)->obj) sob=0, sco=1;
if(self->container) r=self->container; else sob=1, sco=1;
else r=Py_None; r=Wrapper_acquire((Wrapper*)self->container,
Py_INCREF(r); oname,filter,extra,orig, sob, sco);
return r; }
} else
if(strcmp(name,"self")==0) r=Wrapper_acquire((Wrapper*)self->container,
{ oname,filter,extra,orig,1,1);
if(self->obj) r=self->obj;
else r=Py_None;
Py_INCREF(r);
return r;
}
}
if(self->container)
if(r) goto acquired;
}
else
{ {
if((r=PyObject_GetAttr(self->container,oname))) if((r=PyObject_GetAttr(self->container,oname)))
return r; if(filter)
PyErr_Clear(); switch(apply_filter(filter,self->container,oname,r,extra,orig))
{
case -1: return NULL;
case 1: goto acquired;
}
else goto acquired;
} }
PyErr_Clear();
} }
if(*name++=='_' && strcmp(name,"_init__")==0)
return Py_FindAttr(OBJECT(self),oname);
PyErr_SetObject(PyExc_AttributeError,oname); PyErr_SetObject(PyExc_AttributeError,oname);
return NULL; return NULL;
acquired:
if(has__of__(r)) ASSIGN(r,__of__(r,OBJECT(self)));
return r;
} }
static PyObject * static PyObject *
Xaq_getattro(Wrapper *self, PyObject *oname) handle_Acquired(Wrapper *self, PyObject *oname, PyObject *r)
{
UNLESS(self->container)
{
PyErr_SetObject(PyExc_AttributeError, oname);
return NULL;
}
if(isWrapper(self->container))
ASSIGN(r,Wrapper_acquire(WRAPPER(self->container),
oname,NULL,NULL,NULL,1,1));
else
ASSIGN(r,PyObject_GetAttr(self->container,oname));
if(r && has__of__(r)) ASSIGN(r, __of__(r,OBJECT(self)));
return r;
}
static PyObject *
Wrapper_getattro_(Wrapper *self, PyObject *oname, int sob, int sco)
{ {
PyObject *r; PyObject *r;
char *name; char *name;
if(self->obj && (r=PyObject_GetAttr(self->obj,oname))) name=PyString_AsString(oname);
if(*name=='a' && name[1]=='q' && name[2]=='_'
&& (r=Wrapper_special(self, name+3, oname))) return r;
if(sob && self->obj && (r=PyObject_GetAttr(self->obj,oname)))
{ {
if(r==Acquired) return Wrapper_getattro(self,oname); if(r == Acquired) return handle_Acquired(self, oname, r);
if(r->ob_type==self->ob_type) if(r->ob_type==self->ob_type)
{ {
if(r->ob_refcnt==1) if(r->ob_refcnt==1)
...@@ -297,52 +383,104 @@ Xaq_getattro(Wrapper *self, PyObject *oname) ...@@ -297,52 +383,104 @@ Xaq_getattro(Wrapper *self, PyObject *oname)
} }
else else
ASSIGN(r, newWrapper(((Wrapper*)r)->obj, ASSIGN(r, newWrapper(((Wrapper*)r)->obj,
OBJECT(self), self->ob_type)); OBJECT(self),self->ob_type));
} }
else if(PyECMethod_Check(r) && PyECMethod_Self(r)==self->obj) else if(PyECMethod_Check(r) && PyECMethod_Self(r)==self->obj)
ASSIGN(r,PyECMethod_New(r,OBJECT(self))); ASSIGN(r,PyECMethod_New(r,OBJECT(self)));
else if(has__of__(r)) else if(has__of__(r))
ASSIGN(r,CallMethodO(r,py__of__,Build("(O)", self), NULL)); ASSIGN(r,__of__(r,OBJECT(self)));
return r; return r;
} }
if(self->obj) PyErr_Clear(); if(self->obj) PyErr_Clear();
name=PyString_AsString(oname); if((*name != '_'
#ifdef IMPLICIT_ACQUIRE___ROLES__
|| strcmp(name,"__roles__")==0
#endif
)
&& self->container && sco)
{
if(self->container->ob_type == self->ob_type &&
self->obj->ob_type==self->ob_type)
{
if(WRAPPER(self->obj)->container==
WRAPPER(self->container)->container) sob=1, sco=0;
else if(WRAPPER(self->obj)->container==
WRAPPER(self->container)->obj) sob=0, sco=1;
else sob=1, sco=1;
r=Wrapper_getattro_(WRAPPER(self->container), oname, sob, sco);
}
else r=PyObject_GetAttr(self->container,oname);
if(*name=='a' && strcmp(name,"acquire")==0) if(r)
{
if(has__of__(r))
ASSIGN(r, __of__(r,OBJECT(self)));
return r;
}
PyErr_Clear();
}
if(*name++=='_' && strcmp(name,"_init__")==0)
return Py_FindAttr(OBJECT(self),oname); return Py_FindAttr(OBJECT(self),oname);
PyErr_SetObject(PyExc_AttributeError,oname);
return NULL;
}
static PyObject *
Wrapper_getattro(Wrapper *self, PyObject *oname)
{
return Wrapper_getattro_(self, oname, 1, 1);
}
static PyObject *
Xaq_getattro(Wrapper *self, PyObject *oname)
{
PyObject *r;
char *name;
name=PyString_AsString(oname);
if(*name=='_') if(*name=='_')
{ {
if(strcmp(name,"__init__")==0) return Py_FindAttr(OBJECT(self),oname); if(strcmp(name,"__init__")==0) return Py_FindAttr(OBJECT(self),oname);
#ifdef IMPLICIT_ACQUIRE___ROLES__ #ifdef IMPLICIT_ACQUIRE___ROLES__
if(strcmp(name,"__roles__")==0) return Wrapper_getattro(self,oname); if(strcmp(name,"__roles__")==0) return Wrapper_getattro_(self,oname,1,1);
#endif #endif
} }
if(*name++=='a' && *name++=='q' && *name++=='_') if(*name=='a')
{ {
if(strcmp(name,"acquire")==0) if(name[1]=='c')
{
return Py_FindAttr(OBJECT(self),oname);
}
if(strcmp(name,"parent")==0)
{ {
if(self->container) r=self->container; if(strcmp(name+2,"quire")==0)
else r=Py_None; return Py_FindAttr(OBJECT(self),oname);
Py_INCREF(r); }
return r; else if(name[1]=='q' && name[2]=='_'
} && (r=Wrapper_special(self, name+3, oname))) return r;
if(strcmp(name,"self")==0) }
if(self->obj && (r=PyObject_GetAttr(self->obj,oname)))
{
if(r==Acquired) return handle_Acquired(self,oname,r);
if(r->ob_type==self->ob_type)
{ {
if(self->obj) r=self->obj; if(r->ob_refcnt==1)
else r=Py_None; {
Py_INCREF(r); Py_INCREF(self);
return r; ASSIGN(((Wrapper*)r)->container,OBJECT(self));
}
else
ASSIGN(r, newWrapper(((Wrapper*)r)->obj,
OBJECT(self), self->ob_type));
} }
else if(PyECMethod_Check(r) && PyECMethod_Self(r)==self->obj)
ASSIGN(r,PyECMethod_New(r,OBJECT(self)));
else if(has__of__(r)) ASSIGN(r,__of__(r,OBJECT(self)));
return r;
} }
if(self->obj) PyErr_Clear();
PyErr_SetObject(PyExc_AttributeError,oname); PyErr_SetObject(PyExc_AttributeError,oname);
return NULL; return NULL;
...@@ -377,89 +515,6 @@ err: ...@@ -377,89 +515,6 @@ err:
return -1; return -1;
} }
static PyObject *
Wrapper_acquire(Wrapper *self, PyObject *oname,
PyObject *filter, PyObject *extra, PyObject *orig)
{
PyObject *r;
char *name;
int ir;
if(self->obj)
{
if(r=PyObject_GetAttr(self->obj,oname))
{
if(r->ob_type==self->ob_type)
{
if(r->ob_refcnt==1)
{
Py_INCREF(self);
ASSIGN(((Wrapper*)r)->container,OBJECT(self));
}
else
ASSIGN(r,newWrapper(((Wrapper*)r)->obj,
OBJECT(self), self->ob_type));
}
else if(PyECMethod_Check(r) && PyECMethod_Self(r)==self->obj)
ASSIGN(r,PyECMethod_New(r,OBJECT(self)));
else if(has__of__(r))
ASSIGN(r,CallMethodO(r,py__of__,Build("(O)", self), NULL));
if(filter)
switch(apply_filter(filter,OBJECT(self),oname,r,extra,orig))
{
case -1: return NULL;
case 1: return r;
}
else return r;
}
PyErr_Clear();
}
name=PyString_AsString(oname);
if(*name++=='a' && *name++=='q' && *name++=='_')
{
if(strcmp(name,"parent")==0)
{
if(self->container) r=self->container;
else r=Py_None;
Py_INCREF(r);
return r;
}
if(strcmp(name,"self")==0)
{
if(self->obj) r=self->obj;
else r=Py_None;
Py_INCREF(r);
return r;
}
}
if(self->container)
{
if(isWrapper(self->container))
{
if((r=Wrapper_acquire((Wrapper*)self->container,
oname,filter,extra,orig)))
return r;
}
else
{
if((r=PyObject_GetAttr(self->container,oname)))
if(filter)
switch(apply_filter(filter,self->container,oname,r,extra,orig))
{
case -1: return NULL;
case 1: return r;
}
else return r;
}
PyErr_Clear();
}
PyErr_SetObject(PyExc_AttributeError,oname);
return NULL;
}
static int static int
Wrapper_setattro(Wrapper *self, PyObject *name, PyObject *v) Wrapper_setattro(Wrapper *self, PyObject *name, PyObject *v)
{ {
...@@ -520,8 +575,6 @@ Wrapper_call(Wrapper *self, PyObject *args, PyObject *kw) ...@@ -520,8 +575,6 @@ Wrapper_call(Wrapper *self, PyObject *args, PyObject *kw)
return CallMethodO(OBJECT(self),py__call__,args,kw); return CallMethodO(OBJECT(self),py__call__,args,kw);
} }
/* Code to handle accessing Wrapper objects as sequence objects */ /* Code to handle accessing Wrapper objects as sequence objects */
static int static int
...@@ -679,7 +732,7 @@ Wrapper_acquire_method(Wrapper *self, PyObject *args) ...@@ -679,7 +732,7 @@ Wrapper_acquire_method(Wrapper *self, PyObject *args)
UNLESS(PyArg_ParseTuple(args,"O|OO",&name,&filter,&extra)) return NULL; UNLESS(PyArg_ParseTuple(args,"O|OO",&name,&filter,&extra)) return NULL;
return Wrapper_acquire(self,name,filter,extra,OBJECT(self)); return Wrapper_acquire(self,name,filter,extra,OBJECT(self),1,1);
} }
static struct PyMethodDef Wrapper_methods[] = { static struct PyMethodDef Wrapper_methods[] = {
...@@ -804,7 +857,7 @@ void ...@@ -804,7 +857,7 @@ void
initAcquisition() initAcquisition()
{ {
PyObject *m, *d; PyObject *m, *d;
char *rev="$Revision: 1.15 $"; char *rev="$Revision: 1.16 $";
PURE_MIXIN_CLASS(Acquirer, PURE_MIXIN_CLASS(Acquirer,
"Base class for objects that implicitly" "Base class for objects that implicitly"
" acquire attributes from containers\n" " acquire attributes from containers\n"
...@@ -823,7 +876,7 @@ initAcquisition() ...@@ -823,7 +876,7 @@ initAcquisition()
/* Create the module and add the functions */ /* Create the module and add the functions */
m = Py_InitModule4("Acquisition", methods, m = Py_InitModule4("Acquisition", methods,
"Provide base classes for acquiring objects\n\n" "Provide base classes for acquiring objects\n\n"
"$Id: Acquisition.c,v 1.15 1998/01/21 19:00:48 jim Exp $\n", "$Id: Acquisition.c,v 1.16 1998/03/23 20:23:35 jim Exp $\n",
OBJECT(NULL),PYTHON_API_VERSION); OBJECT(NULL),PYTHON_API_VERSION);
d = PyModule_GetDict(m); d = PyModule_GetDict(m);
...@@ -846,6 +899,9 @@ initAcquisition() ...@@ -846,6 +899,9 @@ initAcquisition()
/***************************************************************************** /*****************************************************************************
$Log: Acquisition.c,v $ $Log: Acquisition.c,v $
Revision 1.16 1998/03/23 20:23:35 jim
Added lots of new machinery to handle wrapping of acquired objects.
Revision 1.15 1998/01/21 19:00:48 jim Revision 1.15 1998/01/21 19:00:48 jim
Fixed __len__ bugs and added free lists for methods and wrappers Fixed __len__ bugs and added free lists for methods and wrappers
......
/* /*
$Id: Acquisition.c,v 1.15 1998/01/21 19:00:48 jim Exp $ $Id: Acquisition.c,v 1.16 1998/03/23 20:23:35 jim Exp $
Acquisition Wrappers -- Implementation of acquisition through wrappers Acquisition Wrappers -- Implementation of acquisition through wrappers
...@@ -153,6 +153,7 @@ staticforward PyExtensionClass Wrappertype, XaqWrappertype; ...@@ -153,6 +153,7 @@ staticforward PyExtensionClass Wrappertype, XaqWrappertype;
#define isWrapper(O) ((O)->ob_type==(PyTypeObject*)&Wrappertype || \ #define isWrapper(O) ((O)->ob_type==(PyTypeObject*)&Wrappertype || \
(O)->ob_type==(PyTypeObject*)&XaqWrappertype) (O)->ob_type==(PyTypeObject*)&XaqWrappertype)
#define WRAPPER(O) ((Wrapper*)(O))
static PyObject * static PyObject *
Wrapper__init__(Wrapper *self, PyObject *args) Wrapper__init__(Wrapper *self, PyObject *args)
...@@ -172,6 +173,23 @@ Wrapper__init__(Wrapper *self, PyObject *args) ...@@ -172,6 +173,23 @@ Wrapper__init__(Wrapper *self, PyObject *args)
/* ---------- */ /* ---------- */
static PyObject *
__of__(PyObject *inst, PyObject *parent)
{
PyObject *r, *t;
UNLESS(r=PyObject_GetAttr(inst, py__of__)) return NULL;
UNLESS(t=PyTuple_New(1)) goto err;
PyTuple_SET_ITEM(t,0,parent);
ASSIGN(r,PyObject_CallObject(r,t));
PyTuple_SET_ITEM(t,0,NULL);
Py_DECREF(t);
return r;
err:
Py_DECREF(r);
return NULL;
}
static PyObject * static PyObject *
newWrapper(PyObject *obj, PyObject *container, PyTypeObject *Wrappertype) newWrapper(PyObject *obj, PyObject *container, PyTypeObject *Wrappertype)
{ {
...@@ -205,14 +223,57 @@ Wrapper_dealloc(Wrapper *self) ...@@ -205,14 +223,57 @@ Wrapper_dealloc(Wrapper *self)
} }
static PyObject * static PyObject *
Wrapper_getattro(Wrapper *self, PyObject *oname) Wrapper_special(Wrapper *self, char *name, PyObject *oname)
{
PyObject *r=0;
if(strcmp(name,"base")==0)
{
if(self->obj)
{
r=self->obj;
while(isWrapper(r) && WRAPPER(r)->obj) r=WRAPPER(r)->obj;
}
else r=Py_None;
Py_INCREF(r);
return r;
}
if(strcmp(name,"parent")==0)
{
if(self->container) r=self->container;
else r=Py_None;
Py_INCREF(r);
return r;
}
if(strcmp(name,"self")==0)
{
if(self->obj) r=self->obj;
else r=Py_None;
Py_INCREF(r);
return r;
}
if(strcmp(name,"acquire")==0)
{
return Py_FindAttr(OBJECT(self),oname);
}
}
static PyObject *
Wrapper_acquire(Wrapper *self, PyObject *oname,
PyObject *filter, PyObject *extra, PyObject *orig,
int sob, int sco)
{ {
PyObject *r; PyObject *r;
char *name; char *name;
int ir;
if(self->obj && (r=PyObject_GetAttr(self->obj,oname))) name=PyString_AsString(oname);
if(*name++=='a' && *name++=='q' && *name++=='_'
&& (r=Wrapper_special(self, name, oname))) return r;
if(sob && self->obj)
{ {
if(r != Acquired) if(r=PyObject_GetAttr(self->obj,oname))
{ {
if(r->ob_type==self->ob_type) if(r->ob_type==self->ob_type)
{ {
...@@ -222,72 +283,97 @@ Wrapper_getattro(Wrapper *self, PyObject *oname) ...@@ -222,72 +283,97 @@ Wrapper_getattro(Wrapper *self, PyObject *oname)
ASSIGN(((Wrapper*)r)->container,OBJECT(self)); ASSIGN(((Wrapper*)r)->container,OBJECT(self));
} }
else else
ASSIGN(r, newWrapper(((Wrapper*)r)->obj, ASSIGN(r,newWrapper(((Wrapper*)r)->obj,
OBJECT(self),self->ob_type)); OBJECT(self), self->ob_type));
} }
else if(PyECMethod_Check(r) && PyECMethod_Self(r)==self->obj) else if(PyECMethod_Check(r) && PyECMethod_Self(r)==self->obj)
ASSIGN(r,PyECMethod_New(r,OBJECT(self))); ASSIGN(r,PyECMethod_New(r,OBJECT(self)));
else if(has__of__(r)) else if(has__of__(r)) ASSIGN(r,__of__(r,OBJECT(self)));
ASSIGN(r,CallMethodO(r,py__of__,Build("(O)", self), NULL)); if(filter)
return r; switch(apply_filter(filter,OBJECT(self),oname,r,extra,orig))
{
case -1: return NULL;
case 1: return r;
}
else return r;
} }
PyErr_Clear();
} }
if(self->obj) PyErr_Clear();
if(sco && self->container)
name=PyString_AsString(oname); {
if(*name != '_' if(isWrapper(self->container))
#ifdef IMPLICIT_ACQUIRE___ROLES__
|| strcmp(name,"__roles__")==0
#endif
|| r==Acquired
)
{
if(*name++=='a' && *name++=='q' && *name++=='_')
{ {
if(strcmp(name,"acquire")==0) if(self->obj && self->obj->ob_type == (PyTypeObject*)&Wrappertype)
{ {
return Py_FindAttr(OBJECT(self),oname); if(WRAPPER(self->obj)->container==
} WRAPPER(self->container)->container) sob=1, sco=0;
if(strcmp(name,"parent")==0) else if(WRAPPER(self->obj)->container==
{ WRAPPER(self->container)->obj) sob=0, sco=1;
if(self->container) r=self->container; else sob=1, sco=1;
else r=Py_None; r=Wrapper_acquire((Wrapper*)self->container,
Py_INCREF(r); oname,filter,extra,orig, sob, sco);
return r; }
} else
if(strcmp(name,"self")==0) r=Wrapper_acquire((Wrapper*)self->container,
{ oname,filter,extra,orig,1,1);
if(self->obj) r=self->obj;
else r=Py_None;
Py_INCREF(r);
return r;
}
}
if(self->container)
if(r) goto acquired;
}
else
{ {
if((r=PyObject_GetAttr(self->container,oname))) if((r=PyObject_GetAttr(self->container,oname)))
return r; if(filter)
PyErr_Clear(); switch(apply_filter(filter,self->container,oname,r,extra,orig))
{
case -1: return NULL;
case 1: goto acquired;
}
else goto acquired;
} }
PyErr_Clear();
} }
if(*name++=='_' && strcmp(name,"_init__")==0)
return Py_FindAttr(OBJECT(self),oname);
PyErr_SetObject(PyExc_AttributeError,oname); PyErr_SetObject(PyExc_AttributeError,oname);
return NULL; return NULL;
acquired:
if(has__of__(r)) ASSIGN(r,__of__(r,OBJECT(self)));
return r;
} }
static PyObject * static PyObject *
Xaq_getattro(Wrapper *self, PyObject *oname) handle_Acquired(Wrapper *self, PyObject *oname, PyObject *r)
{
UNLESS(self->container)
{
PyErr_SetObject(PyExc_AttributeError, oname);
return NULL;
}
if(isWrapper(self->container))
ASSIGN(r,Wrapper_acquire(WRAPPER(self->container),
oname,NULL,NULL,NULL,1,1));
else
ASSIGN(r,PyObject_GetAttr(self->container,oname));
if(r && has__of__(r)) ASSIGN(r, __of__(r,OBJECT(self)));
return r;
}
static PyObject *
Wrapper_getattro_(Wrapper *self, PyObject *oname, int sob, int sco)
{ {
PyObject *r; PyObject *r;
char *name; char *name;
if(self->obj && (r=PyObject_GetAttr(self->obj,oname))) name=PyString_AsString(oname);
if(*name=='a' && name[1]=='q' && name[2]=='_'
&& (r=Wrapper_special(self, name+3, oname))) return r;
if(sob && self->obj && (r=PyObject_GetAttr(self->obj,oname)))
{ {
if(r==Acquired) return Wrapper_getattro(self,oname); if(r == Acquired) return handle_Acquired(self, oname, r);
if(r->ob_type==self->ob_type) if(r->ob_type==self->ob_type)
{ {
if(r->ob_refcnt==1) if(r->ob_refcnt==1)
...@@ -297,52 +383,104 @@ Xaq_getattro(Wrapper *self, PyObject *oname) ...@@ -297,52 +383,104 @@ Xaq_getattro(Wrapper *self, PyObject *oname)
} }
else else
ASSIGN(r, newWrapper(((Wrapper*)r)->obj, ASSIGN(r, newWrapper(((Wrapper*)r)->obj,
OBJECT(self), self->ob_type)); OBJECT(self),self->ob_type));
} }
else if(PyECMethod_Check(r) && PyECMethod_Self(r)==self->obj) else if(PyECMethod_Check(r) && PyECMethod_Self(r)==self->obj)
ASSIGN(r,PyECMethod_New(r,OBJECT(self))); ASSIGN(r,PyECMethod_New(r,OBJECT(self)));
else if(has__of__(r)) else if(has__of__(r))
ASSIGN(r,CallMethodO(r,py__of__,Build("(O)", self), NULL)); ASSIGN(r,__of__(r,OBJECT(self)));
return r; return r;
} }
if(self->obj) PyErr_Clear(); if(self->obj) PyErr_Clear();
name=PyString_AsString(oname); if((*name != '_'
#ifdef IMPLICIT_ACQUIRE___ROLES__
|| strcmp(name,"__roles__")==0
#endif
)
&& self->container && sco)
{
if(self->container->ob_type == self->ob_type &&
self->obj->ob_type==self->ob_type)
{
if(WRAPPER(self->obj)->container==
WRAPPER(self->container)->container) sob=1, sco=0;
else if(WRAPPER(self->obj)->container==
WRAPPER(self->container)->obj) sob=0, sco=1;
else sob=1, sco=1;
r=Wrapper_getattro_(WRAPPER(self->container), oname, sob, sco);
}
else r=PyObject_GetAttr(self->container,oname);
if(*name=='a' && strcmp(name,"acquire")==0) if(r)
{
if(has__of__(r))
ASSIGN(r, __of__(r,OBJECT(self)));
return r;
}
PyErr_Clear();
}
if(*name++=='_' && strcmp(name,"_init__")==0)
return Py_FindAttr(OBJECT(self),oname); return Py_FindAttr(OBJECT(self),oname);
PyErr_SetObject(PyExc_AttributeError,oname);
return NULL;
}
static PyObject *
Wrapper_getattro(Wrapper *self, PyObject *oname)
{
return Wrapper_getattro_(self, oname, 1, 1);
}
static PyObject *
Xaq_getattro(Wrapper *self, PyObject *oname)
{
PyObject *r;
char *name;
name=PyString_AsString(oname);
if(*name=='_') if(*name=='_')
{ {
if(strcmp(name,"__init__")==0) return Py_FindAttr(OBJECT(self),oname); if(strcmp(name,"__init__")==0) return Py_FindAttr(OBJECT(self),oname);
#ifdef IMPLICIT_ACQUIRE___ROLES__ #ifdef IMPLICIT_ACQUIRE___ROLES__
if(strcmp(name,"__roles__")==0) return Wrapper_getattro(self,oname); if(strcmp(name,"__roles__")==0) return Wrapper_getattro_(self,oname,1,1);
#endif #endif
} }
if(*name++=='a' && *name++=='q' && *name++=='_') if(*name=='a')
{ {
if(strcmp(name,"acquire")==0) if(name[1]=='c')
{
return Py_FindAttr(OBJECT(self),oname);
}
if(strcmp(name,"parent")==0)
{ {
if(self->container) r=self->container; if(strcmp(name+2,"quire")==0)
else r=Py_None; return Py_FindAttr(OBJECT(self),oname);
Py_INCREF(r); }
return r; else if(name[1]=='q' && name[2]=='_'
} && (r=Wrapper_special(self, name+3, oname))) return r;
if(strcmp(name,"self")==0) }
if(self->obj && (r=PyObject_GetAttr(self->obj,oname)))
{
if(r==Acquired) return handle_Acquired(self,oname,r);
if(r->ob_type==self->ob_type)
{ {
if(self->obj) r=self->obj; if(r->ob_refcnt==1)
else r=Py_None; {
Py_INCREF(r); Py_INCREF(self);
return r; ASSIGN(((Wrapper*)r)->container,OBJECT(self));
}
else
ASSIGN(r, newWrapper(((Wrapper*)r)->obj,
OBJECT(self), self->ob_type));
} }
else if(PyECMethod_Check(r) && PyECMethod_Self(r)==self->obj)
ASSIGN(r,PyECMethod_New(r,OBJECT(self)));
else if(has__of__(r)) ASSIGN(r,__of__(r,OBJECT(self)));
return r;
} }
if(self->obj) PyErr_Clear();
PyErr_SetObject(PyExc_AttributeError,oname); PyErr_SetObject(PyExc_AttributeError,oname);
return NULL; return NULL;
...@@ -377,89 +515,6 @@ err: ...@@ -377,89 +515,6 @@ err:
return -1; return -1;
} }
static PyObject *
Wrapper_acquire(Wrapper *self, PyObject *oname,
PyObject *filter, PyObject *extra, PyObject *orig)
{
PyObject *r;
char *name;
int ir;
if(self->obj)
{
if(r=PyObject_GetAttr(self->obj,oname))
{
if(r->ob_type==self->ob_type)
{
if(r->ob_refcnt==1)
{
Py_INCREF(self);
ASSIGN(((Wrapper*)r)->container,OBJECT(self));
}
else
ASSIGN(r,newWrapper(((Wrapper*)r)->obj,
OBJECT(self), self->ob_type));
}
else if(PyECMethod_Check(r) && PyECMethod_Self(r)==self->obj)
ASSIGN(r,PyECMethod_New(r,OBJECT(self)));
else if(has__of__(r))
ASSIGN(r,CallMethodO(r,py__of__,Build("(O)", self), NULL));
if(filter)
switch(apply_filter(filter,OBJECT(self),oname,r,extra,orig))
{
case -1: return NULL;
case 1: return r;
}
else return r;
}
PyErr_Clear();
}
name=PyString_AsString(oname);
if(*name++=='a' && *name++=='q' && *name++=='_')
{
if(strcmp(name,"parent")==0)
{
if(self->container) r=self->container;
else r=Py_None;
Py_INCREF(r);
return r;
}
if(strcmp(name,"self")==0)
{
if(self->obj) r=self->obj;
else r=Py_None;
Py_INCREF(r);
return r;
}
}
if(self->container)
{
if(isWrapper(self->container))
{
if((r=Wrapper_acquire((Wrapper*)self->container,
oname,filter,extra,orig)))
return r;
}
else
{
if((r=PyObject_GetAttr(self->container,oname)))
if(filter)
switch(apply_filter(filter,self->container,oname,r,extra,orig))
{
case -1: return NULL;
case 1: return r;
}
else return r;
}
PyErr_Clear();
}
PyErr_SetObject(PyExc_AttributeError,oname);
return NULL;
}
static int static int
Wrapper_setattro(Wrapper *self, PyObject *name, PyObject *v) Wrapper_setattro(Wrapper *self, PyObject *name, PyObject *v)
{ {
...@@ -520,8 +575,6 @@ Wrapper_call(Wrapper *self, PyObject *args, PyObject *kw) ...@@ -520,8 +575,6 @@ Wrapper_call(Wrapper *self, PyObject *args, PyObject *kw)
return CallMethodO(OBJECT(self),py__call__,args,kw); return CallMethodO(OBJECT(self),py__call__,args,kw);
} }
/* Code to handle accessing Wrapper objects as sequence objects */ /* Code to handle accessing Wrapper objects as sequence objects */
static int static int
...@@ -679,7 +732,7 @@ Wrapper_acquire_method(Wrapper *self, PyObject *args) ...@@ -679,7 +732,7 @@ Wrapper_acquire_method(Wrapper *self, PyObject *args)
UNLESS(PyArg_ParseTuple(args,"O|OO",&name,&filter,&extra)) return NULL; UNLESS(PyArg_ParseTuple(args,"O|OO",&name,&filter,&extra)) return NULL;
return Wrapper_acquire(self,name,filter,extra,OBJECT(self)); return Wrapper_acquire(self,name,filter,extra,OBJECT(self),1,1);
} }
static struct PyMethodDef Wrapper_methods[] = { static struct PyMethodDef Wrapper_methods[] = {
...@@ -804,7 +857,7 @@ void ...@@ -804,7 +857,7 @@ void
initAcquisition() initAcquisition()
{ {
PyObject *m, *d; PyObject *m, *d;
char *rev="$Revision: 1.15 $"; char *rev="$Revision: 1.16 $";
PURE_MIXIN_CLASS(Acquirer, PURE_MIXIN_CLASS(Acquirer,
"Base class for objects that implicitly" "Base class for objects that implicitly"
" acquire attributes from containers\n" " acquire attributes from containers\n"
...@@ -823,7 +876,7 @@ initAcquisition() ...@@ -823,7 +876,7 @@ initAcquisition()
/* Create the module and add the functions */ /* Create the module and add the functions */
m = Py_InitModule4("Acquisition", methods, m = Py_InitModule4("Acquisition", methods,
"Provide base classes for acquiring objects\n\n" "Provide base classes for acquiring objects\n\n"
"$Id: Acquisition.c,v 1.15 1998/01/21 19:00:48 jim Exp $\n", "$Id: Acquisition.c,v 1.16 1998/03/23 20:23:35 jim Exp $\n",
OBJECT(NULL),PYTHON_API_VERSION); OBJECT(NULL),PYTHON_API_VERSION);
d = PyModule_GetDict(m); d = PyModule_GetDict(m);
...@@ -846,6 +899,9 @@ initAcquisition() ...@@ -846,6 +899,9 @@ initAcquisition()
/***************************************************************************** /*****************************************************************************
$Log: Acquisition.c,v $ $Log: Acquisition.c,v $
Revision 1.16 1998/03/23 20:23:35 jim
Added lots of new machinery to handle wrapping of acquired objects.
Revision 1.15 1998/01/21 19:00:48 jim Revision 1.15 1998/01/21 19:00:48 jim
Fixed __len__ bugs and added free lists for methods and wrappers Fixed __len__ bugs and added free lists for methods and wrappers
......
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