[Zope-Checkins] CVS: Zope3/lib/python/Zope/Security - _Proxy.c:1.1.4.3

Jim Fulton jim@zope.com
Tue, 21 May 2002 08:19:18 -0400


Update of /cvs-repository/Zope3/lib/python/Zope/Security
In directory cvs.zope.org:/tmp/cvs-serv5183/Zope/Security

Modified Files:
      Tag: Zope-3x-branch
	_Proxy.c 
Log Message:
Changed security proxies to fall back to a default str and repr when
the proxied object's str and repr are not accessable.

This makes error messages and diagnosis a bit saner.


=== Zope3/lib/python/Zope/Security/_Proxy.c 1.1.4.2 => 1.1.4.3 ===
 #include <Python.h>
 
+static PyObject *__class__str = 0, *__name__str = 0, *__module__str = 0;
+
 typedef struct {
 	PyObject_HEAD
 	PyObject *proxy_object;
@@ -267,8 +269,79 @@
 	return -1;
 }
 
-UNOP(str, PyObject_Str)
-UNOP(repr, PyObject_Repr)
+static PyObject *
+default_repr(PyObject *object)
+{
+  PyObject *klass, *name=0, *module=0, *result=0;
+  char *sname, *smodule;
+
+  klass = PyObject_GetAttr(object, __class__str);
+  if (! klass)
+    return NULL;
+  
+  name  = PyObject_GetAttr(klass, __name__str);
+  if (! name) 
+    goto err;
+  sname = PyString_AsString(name);
+  if (! sname) 
+    goto err;
+  
+  module  = PyObject_GetAttr(klass, __module__str);
+  if (module) {
+    smodule = PyString_AsString(module);
+    if (! smodule) 
+      goto err;
+    result = PyString_FromFormat("<security proxied %s.%s instance at %p>",
+                                 smodule, sname, object);
+  }
+  else {
+    PyErr_Clear();
+    result = PyString_FromFormat("<security proxied %s instance at %p>",
+                                 sname, object);
+  }
+  
+ err:
+  
+  Py_DECREF(klass);
+  Py_XDECREF(name);
+  Py_XDECREF(module);
+
+  return result;
+}
+
+static PyObject *
+proxy_str(PyObject *self)
+{
+	PyObject *result = NULL;
+	PyObject *object = Proxy_GetObject(self);
+	PyObject *checker = Proxy_GetChecker(self);
+
+	if (check(checker, "__str__", object)) {
+		result = PyObject_Str(object);
+	}
+        else {
+                PyErr_Clear();
+                result = default_repr(object);
+        }
+	return result;
+}
+
+static PyObject *
+proxy_repr(PyObject *self)
+{
+	PyObject *result = NULL;
+	PyObject *object = Proxy_GetObject(self);
+	PyObject *checker = Proxy_GetChecker(self);
+
+	if (check(checker, "__repr__", object)) {
+		result = PyObject_Repr(object);
+	}
+        else {
+                PyErr_Clear();
+                result = default_repr(object);
+        }
+	return result;
+}
 
 static int
 proxy_compare(PyObject *self, PyObject *other)
@@ -805,6 +878,15 @@
 init_Proxy(void)
 {
 	PyObject *m;
+
+        __class__str = PyString_FromString("__class__");
+        if (! __class__str) return;
+
+        __name__str = PyString_FromString("__name__");
+        if (! __name__str) return;
+
+        __module__str = PyString_FromString("__module__");
+        if (! __module__str) return;
 
 	ProxyType.ob_type = &PyType_Type;
 	if (PyType_Ready(&ProxyType) < 0)