[Zodb-checkins] CVS: Zope/lib/Components/ExtensionClass/src - ExtensionClass.c:1.42.4.2.4.1

Jim Fulton jim@zope.com
Mon, 1 Oct 2001 17:11:17 -0400


Update of /cvs-repository/Zope/lib/Components/ExtensionClass/src
In directory cvs.zope.org:/tmp/cvs-serv28789

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/src/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$";