Commit 49f5d5b6 authored by matt@zope.com's avatar matt@zope.com

Jim's changes to Extension Class -- Several PyObject_GetItem requests now check

if the object is a dictionary, and do a PyDict_GetItem instead if possible.
This avoids the error machinery overhead if the key is not found in the
dictionary.  PyDict_GetItem returns a borrowed reference, so the refcount
is also bumped in these cases.
parent 5dccf6b3
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE. DAMAGE.
$Id: ExtensionClass.c,v 1.46 2001/03/28 14:06:50 jeremy Exp $ $Id: ExtensionClass.c,v 1.47 2001/10/04 14:09:38 matt Exp $
If you have questions regarding this software, If you have questions regarding this software,
contact: contact:
...@@ -54,7 +54,7 @@ static char ExtensionClass_module_documentation[] = ...@@ -54,7 +54,7 @@ static char ExtensionClass_module_documentation[] =
" - They provide access to unbound methods,\n" " - They provide access to unbound methods,\n"
" - They can be called to create instances.\n" " - They can be called to create instances.\n"
"\n" "\n"
"$Id: ExtensionClass.c,v 1.46 2001/03/28 14:06:50 jeremy Exp $\n" "$Id: ExtensionClass.c,v 1.47 2001/10/04 14:09:38 matt Exp $\n"
; ;
#include <stdio.h> #include <stdio.h>
...@@ -1649,14 +1649,27 @@ ExtensionClass_FindInstanceAttribute(PyObject *inst, PyObject *oname, ...@@ -1649,14 +1649,27 @@ ExtensionClass_FindInstanceAttribute(PyObject *inst, PyObject *oname,
if (ClassHasInstDict(self)) if (ClassHasInstDict(self))
{ {
r= INSTANCE_DICT(inst); r= INSTANCE_DICT(inst);
if ((r = PyObject_GetItem(r,oname)) && NeedsToBeBound(r)) if (PyDict_Check(r))
{ {
ASSIGN(r, CallMethodO(r, py__of__, Build("(O)", inst), NULL)); r = PyDict_GetItem(r,oname);
UNLESS(r) return NULL; Py_XINCREF(r);
} }
else
{
UNLESS (r = PyObject_GetItem(r,oname))
PyErr_Clear();
} }
UNLESS(r)
if (r)
{
if (NeedsToBeBound(r))
{ {
ASSIGN(r, CallMethodO(r, py__of__, Build("(O)", inst), NULL));
}
return r;
}
}
if (*name=='_' && name[1]=='_' if (*name=='_' && name[1]=='_'
&& &&
( (name[2]=='b' && strcmp(name+2,"bases__")==0) ( (name[2]=='b' && strcmp(name+2,"bases__")==0)
...@@ -1668,8 +1681,6 @@ ExtensionClass_FindInstanceAttribute(PyObject *inst, PyObject *oname, ...@@ -1668,8 +1681,6 @@ ExtensionClass_FindInstanceAttribute(PyObject *inst, PyObject *oname,
return NULL; return NULL;
} }
PyErr_Clear();
UNLESS(r=CCL_getattr(self,oname,0)) return NULL; UNLESS(r=CCL_getattr(self,oname,0)) return NULL;
/* We got something from our class, maybe its an unbound method. */ /* We got something from our class, maybe its an unbound method. */
...@@ -1677,7 +1688,6 @@ ExtensionClass_FindInstanceAttribute(PyObject *inst, PyObject *oname, ...@@ -1677,7 +1688,6 @@ ExtensionClass_FindInstanceAttribute(PyObject *inst, PyObject *oname,
ASSIGN(r,(PyObject*)bindCMethod((CMethod*)r,inst)); ASSIGN(r,(PyObject*)bindCMethod((CMethod*)r,inst));
else if (UnboundPMethod_Check(r)) else if (UnboundPMethod_Check(r))
ASSIGN(r,bindPMethod((PMethod*)r,inst)); ASSIGN(r,bindPMethod((PMethod*)r,inst));
}
return r; return r;
} }
...@@ -1704,44 +1714,67 @@ static int ...@@ -1704,44 +1714,67 @@ static int
subclass_simple_setattr(PyObject *self, char *name, PyObject *v); subclass_simple_setattr(PyObject *self, char *name, PyObject *v);
static PyObject * static PyObject *
CCL_getattr(PyExtensionClass *self, PyObject *oname, int look_super) CCL_getattr2(PyObject *self, PyObject *oname, int look_super)
{ {
PyObject *r=0; PyObject *r=0, *b, *d;
if (! look_super) r=PyObject_GetItem(self->class_dictionary,oname); if (ExtensionClass_Check(self))
UNLESS(r)
{ {
if (self->bases) b=((PyExtensionClass*)self)->bases;
d=((PyExtensionClass*)self)->class_dictionary;
}
else if (PyClass_Check(self))
{ {
int n, i; b=((PyClassObject*)self)->cl_bases;
PyObject *c; d=((PyClassObject*)self)->cl_dict;
}
else
{
UNLESS (r=PyObject_GetAttr(self, oname)) PyErr_Clear();
return r;
}
n=PyTuple_Size(self->bases); if (! look_super && d)
for (i=0; i < n; i++)
{ {
PyErr_Clear(); if (PyDict_Check(d))
c=PyTuple_GET_ITEM(self->bases, i); {
if (ExtensionClass_Check(c)) if((r=PyDict_GetItem(d, oname)))
r=CCL_getattr(AsExtensionClass(c),oname,0); {
Py_INCREF(r);
return r;
}
}
else else
r=PyObject_GetAttr(c,oname); {
if (r) break; if((r=PyObject_GetItem(d, oname))) return r;
PyErr_Clear();
} }
} }
UNLESS(r)
if (b)
{ {
PyObject *t, *v, *tb; int n, i;
PyErr_Fetch(&t,&v,&tb); n = PyTuple_Check(b) ? PyTuple_GET_SIZE(b) : 0; /* I don't care ;) */
if (t==PyExc_KeyError && PyObject_Compare(v,oname) == 0) for (i=0; i < n; i++)
{ {
Py_DECREF(t); r=CCL_getattr2(PyTuple_GET_ITEM(b, i), oname, 0);
t=PyExc_AttributeError; if (r) return r;
Py_INCREF(t);
} }
PyErr_Restore(t,v,tb);
return NULL;
} }
return NULL;
}
static PyObject *
CCL_getattr(PyExtensionClass *self, PyObject *oname, int look_super)
{
PyObject *r=0;
UNLESS (r=CCL_getattr2(OBJECT(self), oname, look_super))
{
PyErr_SetObject(PyExc_AttributeError, oname);
return NULL;
} }
if (PyFunction_Check(r) || NeedsToBeBound(r)) if (PyFunction_Check(r) || NeedsToBeBound(r))
...@@ -1752,6 +1785,21 @@ CCL_getattr(PyExtensionClass *self, PyObject *oname, int look_super) ...@@ -1752,6 +1785,21 @@ CCL_getattr(PyExtensionClass *self, PyObject *oname, int look_super)
return r; return r;
} }
static PyObject *
CCL_getattrne(PyExtensionClass *self, PyObject *oname)
{
PyObject *r=0;
if ((r=CCL_getattr2(OBJECT(self), oname, 0)))
{
if (PyFunction_Check(r) || NeedsToBeBound(r))
ASSIGN(r,newPMethod(self,r));
else if (PyMethod_Check(r) && ! PyMethod_Self(r))
ASSIGN(r,newPMethod(self, PyMethod_Function(r)));
}
return r;
}
static PyObject * static PyObject *
CCL_reduce(PyExtensionClass *self, PyObject *args) CCL_reduce(PyExtensionClass *self, PyObject *args)
{ {
...@@ -2109,14 +2157,24 @@ subclass_getspecial(PyObject *inst, PyObject *oname) ...@@ -2109,14 +2157,24 @@ subclass_getspecial(PyObject *inst, PyObject *oname)
if (HasInstDict(inst)) if (HasInstDict(inst))
{ {
r= INSTANCE_DICT(inst); r= INSTANCE_DICT(inst);
r = PyObject_GetItem(r,oname); if (PyDict_Check(r))
UNLESS(r) {
if ((r = PyDict_GetItem(r,oname)))
Py_INCREF(r);
else
r=CCL_getattr(self,oname,0);
}
else
{
UNLESS (r = PyObject_GetItem(r,oname))
{ {
PyErr_Clear(); PyErr_Clear();
r=CCL_getattr(self,oname,0); r=CCL_getattr(self,oname,0);
} }
} }
else r=CCL_getattr(self,oname,0); }
else
r=CCL_getattr(self,oname,0);
return r; return r;
} }
...@@ -3476,7 +3534,7 @@ void ...@@ -3476,7 +3534,7 @@ void
initExtensionClass(void) initExtensionClass(void)
{ {
PyObject *m, *d; PyObject *m, *d;
char *rev="$Revision: 1.46 $"; char *rev="$Revision: 1.47 $";
PURE_MIXIN_CLASS(Base, "Minimalbase class for Extension Classes", NULL); PURE_MIXIN_CLASS(Base, "Minimalbase class for Extension Classes", NULL);
PMethodType.ob_type=&PyType_Type; PMethodType.ob_type=&PyType_Type;
......
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