[Zope-CVS] CVS: Packages/ContextWrapper - test_wrapper.py:1.4 wrapper.c:1.4

Fred Drake Jr fdrake@acm.org
Tue, 13 Nov 2001 16:05:22 -0500


Update of /cvs-repository/Packages/ContextWrapper
In directory cvs.zope.org:/tmp/cvs-serv12028

Modified Files:
	test_wrapper.py wrapper.c 
Log Message:
Add code to proxy attribute accesses off the wrapped object, unless the
wrapper already has an attribute of the same name.


=== Packages/ContextWrapper/test_wrapper.py 1.3 => 1.4 ===
 
 
+class Thing:
+    pass
+
+class CallableThing:
+    def __call__(self):
+        return 'splat!'
+
+
 class WrapperTestCase(unittest.TestCase):
     def check_wrapper_basics(self, o1, o2, factory):
         w = factory(o1)
@@ -55,6 +63,31 @@
 
         w = wrapper.new(lambda a,*args,**kw:(a*3,args,kw))
         self.assert_(w(4,5,6,frob="nitz") == (12, (5, 6), {"frob": "nitz"}))
+
+    def test_wrapper_attributes(self):
+        o = Thing()
+        o.foo = 1
+        w = wrapper.new(o)
+        self.assert_(w.foo == 1)
+
+        o = CallableThing()
+        o.foo = 2
+        w = wrapper.new(o)
+        self.assert_(callable(w))
+        self.assert_(w.foo == 2)
+
+    def test_wrapper_subclass_attributes(self):
+        class MyWrapper(wrapper.WrapperType):
+            def __init__(self, ob):
+                self.foo = 1
+                super(MyWrapper, self).__init__(ob)
+
+        o = Thing()
+        o.foo = 'not 1'
+        o.bar = 2
+        w = MyWrapper(o)
+        self.assert_(w.foo == 1)
+        self.assert_(w.bar == 2)
 
 
 def test_suite():


=== Packages/ContextWrapper/wrapper.c 1.3 => 1.4 ===
 }
 
+static PyObject *
+wrap_getattro(WrapperObject *self, PyObject *name)
+{
+    PyObject *result;
+    result = PyObject_GenericGetAttr((PyObject *)self, name);
+    if (result == NULL) {
+        PyErr_Clear();
+        result = PyObject_GetAttr(self->wrap_object, name);
+    }
+    return result;
+}
+
 static PyTypeObject
 WrapperType = {
     PyObject_HEAD_INIT(NULL)
@@ -105,7 +117,7 @@
     0,					/* tp_hash */
     0,					/* tp_call */
     0,					/* tp_str */
-    0,					/* tp_getattro */
+    (getattrofunc)wrap_getattro,	/* tp_getattro */
     0,					/* tp_setattro */
     0,					/* tp_as_buffer */
     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */