[Zodb-checkins] CVS: Zope/lib/Components/ExtensionClass - ExtensionClass.c:1.42.4.2.4.1
Jim Fulton
jim@zope.com
Mon, 1 Oct 2001 17:59:14 -0400
Update of /cvs-repository/Zope/lib/Components/ExtensionClass
In directory cvs.zope.org:/tmp/cvs-serv6727
Modified Files:
Tag: EC_getattr_speedups-branch
ExtensionClass.c
Log Message:
Changed the basic attribute to use dictionary concrete API where
possible largely to avoid raising and catching errors.
=== Zope/lib/Components/ExtensionClass/ExtensionClass.c 1.42.4.2 => 1.42.4.2.4.1 ===
static void
-init_py_names()
+init_py_names(void)
{
#define INIT_PY_NAME(N) py ## N = PyString_FromString(#N)
INIT_PY_NAME(__add__);
@@ -622,24 +622,6 @@
return NULL;
}
-static int
-CMethod_setattro(CMethod *self, PyObject *oname, PyObject *v)
-{
- int r;
-
- if (self->self && ! PyEval_GetRestricted()) /* Psuedo attributes */
- {
- UNLESS(oname=Py_BuildValue("sO", self->name, oname)) return -1;
- UNLESS_ASSIGN(oname,PyString_Format(concat_fmt, oname)) return -1;
- r=PyObject_SetAttr(self->self, oname, v);
- Py_DECREF(oname);
- return r;
- }
-
- PyErr_SetObject(PyExc_AttributeError, oname);
- return -1;
-}
-
static PyTypeObject CMethodType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
@@ -940,42 +922,6 @@
return PyObject_GetAttr(self->meth, oname);
}
-static int
-PMethod_setattro(PMethod *self, PyObject *oname, PyObject *v)
-{
- int r;
- PyObject *spam;
-
- if (self->meth)
- {
- if ((spam=PyObject_GetAttr(self->meth, oname)))
- {
- Py_DECREF(spam);
- PyErr_SetString(PyExc_TypeError,
- "Attempt to overwrite shared method attribute");
- return -1;
- }
- else PyErr_Clear();
-
- if (self->self && ! PyEval_GetRestricted()) /* Psuedo attrs */
- {
- PyObject *myname;
-
- UNLESS(myname=PyObject_GetAttr(self->meth, py__name__)) return -1;
- oname=Py_BuildValue("OO", myname, oname);
- Py_DECREF(myname);
- UNLESS(oname) return -1;
- UNLESS_ASSIGN(oname,PyString_Format(concat_fmt, oname)) return -1;
- r=PyObject_SetAttr(self->self, oname, v);
- Py_DECREF(oname);
- return r;
- }
- }
-
- PyErr_SetObject(PyExc_AttributeError, oname);
- return -1;
-}
-
static PyTypeObject PMethodType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
@@ -1703,35 +1649,45 @@
if (ClassHasInstDict(self))
{
r= INSTANCE_DICT(inst);
- if ((r = PyObject_GetItem(r,oname)) && NeedsToBeBound(r))
- {
- ASSIGN(r, CallMethodO(r, py__of__, Build("(O)", inst), NULL));
- UNLESS(r) return NULL;
- }
- }
- UNLESS(r)
- {
- if (*name=='_' && name[1]=='_'
- &&
- ( (name[2]=='b' && strcmp(name+2,"bases__")==0)
- || (name[2]=='d' && strcmp(name+2,"dict__")==0)
- )
- )
- {
- PyErr_SetObject(PyExc_AttributeError, oname);
- return NULL;
- }
-
- PyErr_Clear();
+ if (PyDict_Check(r))
+ {
+ r = PyDict_GetItem(r,oname);
+ Py_XINCREF(r);
+ }
+ else
+ {
+ UNLESS (r = PyObject_GetItem(r,oname))
+ PyErr_Clear();
+ }
- UNLESS(r=CCL_getattr(self,oname,0)) return NULL;
+ if (r)
+ {
+ if (NeedsToBeBound(r))
+ {
+ ASSIGN(r, CallMethodO(r, py__of__, Build("(O)", inst), NULL));
+ }
+ return r;
+ }
+ }
- /* We got something from our class, maybe its an unbound method. */
- if (UnboundCMethod_Check(r))
- ASSIGN(r,(PyObject*)bindCMethod((CMethod*)r,inst));
- else if (UnboundPMethod_Check(r))
- ASSIGN(r,bindPMethod((PMethod*)r,inst));
+ if (*name=='_' && name[1]=='_'
+ &&
+ ( (name[2]=='b' && strcmp(name+2,"bases__")==0)
+ || (name[2]=='d' && strcmp(name+2,"dict__")==0)
+ )
+ )
+ {
+ PyErr_SetObject(PyExc_AttributeError, oname);
+ return NULL;
}
+
+ UNLESS(r=CCL_getattr(self,oname,0)) return NULL;
+
+ /* We got something from our class, maybe its an unbound method. */
+ if (UnboundCMethod_Check(r))
+ ASSIGN(r,(PyObject*)bindCMethod((CMethod*)r,inst));
+ else if (UnboundPMethod_Check(r))
+ ASSIGN(r,bindPMethod((PMethod*)r,inst));
return r;
}
@@ -1758,44 +1714,67 @@
subclass_simple_setattr(PyObject *self, char *name, PyObject *v);
static PyObject *
+CCL_getattr2(PyObject *self, PyObject *oname, int look_super)
+{
+ PyObject *r=0, *b, *d;
+
+ if (ExtensionClass_Check(self))
+ {
+ b=((PyExtensionClass*)self)->bases;
+ d=((PyExtensionClass*)self)->class_dictionary;
+ }
+ else if (PyClass_Check(self))
+ {
+ b=((PyClassObject*)self)->cl_bases;
+ d=((PyClassObject*)self)->cl_dict;
+ }
+ else
+ {
+ UNLESS (r=PyObject_GetAttr(self, oname)) PyErr_Clear();
+ return r;
+ }
+
+ if (! look_super && d)
+ {
+ if (PyDict_Check(d))
+ {
+ if((r=PyDict_GetItem(d, oname)))
+ {
+ Py_INCREF(r);
+ return r;
+ }
+ }
+ else
+ {
+ if((r=PyObject_GetItem(d, oname))) return r;
+ PyErr_Clear();
+ }
+ }
+
+ if (b)
+ {
+ int n, i;
+
+ n = PyTuple_Check(b) ? PyTuple_GET_SIZE(b) : 0; /* I don't care ;) */
+ for (i=0; i < n; i++)
+ {
+ r=CCL_getattr2(PyTuple_GET_ITEM(b, i), oname, 0);
+ if (r) return r;
+ }
+ }
+
+ return NULL;
+}
+
+static PyObject *
CCL_getattr(PyExtensionClass *self, PyObject *oname, int look_super)
{
PyObject *r=0;
- if (! look_super) r=PyObject_GetItem(self->class_dictionary,oname);
- UNLESS(r)
+ UNLESS (r=CCL_getattr2(OBJECT(self), oname, look_super))
{
- if (self->bases)
- {
- int n, i;
- PyObject *c;
-
- n=PyTuple_Size(self->bases);
- for (i=0; i < n; i++)
- {
- PyErr_Clear();
- c=PyTuple_GET_ITEM(self->bases, i);
- if (ExtensionClass_Check(c))
- r=CCL_getattr(AsExtensionClass(c),oname,0);
- else
- r=PyObject_GetAttr(c,oname);
- if (r) break;
- }
- }
- UNLESS(r)
- {
- PyObject *t, *v, *tb;
-
- PyErr_Fetch(&t,&v,&tb);
- if (t==PyExc_KeyError && PyObject_Compare(v,oname) == 0)
- {
- Py_DECREF(t);
- t=PyExc_AttributeError;
- Py_INCREF(t);
- }
- PyErr_Restore(t,v,tb);
- return NULL;
- }
+ PyErr_SetObject(PyExc_AttributeError, oname);
+ return NULL;
}
if (PyFunction_Check(r) || NeedsToBeBound(r))
@@ -1807,6 +1786,21 @@
}
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 *
CCL_reduce(PyExtensionClass *self, PyObject *args)
{
return PyString_FromString(self->tp_name);
@@ -2163,14 +2157,24 @@
if (HasInstDict(inst))
{
r= INSTANCE_DICT(inst);
- r = PyObject_GetItem(r,oname);
- UNLESS(r)
- {
- PyErr_Clear();
- r=CCL_getattr(self,oname,0);
- }
+ if (PyDict_Check(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();
+ r=CCL_getattr(self,oname,0);
+ }
+ }
}
- else r=CCL_getattr(self,oname,0);
+ else
+ r=CCL_getattr(self,oname,0);
return r;
}
@@ -3527,7 +3531,7 @@
};
void
-initExtensionClass()
+initExtensionClass(void)
{
PyObject *m, *d;
char *rev="$Revision$";