[Zope3-checkins] CVS: Zope3/src/zope/proxy/context/tests - test_decorator.py:1.4

Steve Alexander steve@cat-box.net
Fri, 9 May 2003 10:03:26 -0400


Update of /cvs-repository/Zope3/src/zope/proxy/context/tests
In directory cvs.zope.org:/tmp/cvs-serv17056/src/zope/proxy/context/tests

Modified Files:
	test_decorator.py 
Log Message:
More development of decorators.
Found a memory leak in Python 2.2.2 and the 2.2 maintenance branch.
This leak is demonstrated in zope.proxy.tests.test_proxy test_leak.
The leak is not apparrent in Python 2.3 from CVS.


=== Zope3/src/zope/proxy/context/tests/test_decorator.py 1.3 => 1.4 ===
--- Zope3/src/zope/proxy/context/tests/test_decorator.py:1.3	Thu May  8 11:16:33 2003
+++ Zope3/src/zope/proxy/context/tests/test_decorator.py	Fri May  9 10:02:55 2003
@@ -23,8 +23,9 @@
 
     proxy_class = decorator.Decorator
 
-    def new_proxy(self, o, c=None, mixinfactory=None, names=()):
-        return self.proxy_class(o, c, mixinfactory, names)
+    def new_proxy(self, o, c=None, mixinfactory=None, names=None,
+                  attrdict=None):
+        return self.proxy_class(o, c, mixinfactory, names, attrdict)
 
     def test_subclass_constructor(self):
         class MyWrapper(self.proxy_class):
@@ -36,7 +37,7 @@
         self.assertEquals(wrapper.getdict(w), {'key': 'value'})
 
         # __new__ catches too many positional args:
-        self.assertRaises(TypeError, MyWrapper, 1, 2, 3, 4, 5)
+        self.assertRaises(TypeError, MyWrapper, 1, 2, 3, 4, 5, 6)
 
     def test_decorator_basics(self):
         # check that default arguments are set correctly as per the interface
@@ -47,6 +48,14 @@
         self.assertEquals(decorator.getnames(w), ())
         self.assert_(decorator.getmixinfactory(w) is None)
 
+        # getnamesdict is not in the official decorator interface, but it
+        # is provided so that the caching dict can be unit-tested from Python.
+
+        # dictproxy instances are not comparable for equality with dict
+        # instances
+        # self.assertEquals(decorator.getnamesdict(w), {})
+        self.assertEquals(len(decorator.getnamesdict(w)), 0)
+
         # check that non-default arguments are set correctly
         class SomeObject(object):
             def bar(self):
@@ -54,6 +63,9 @@
         obj = SomeObject()
 
         class MixinFactory(object):
+            def __init__(self, inner, outer):
+                self.inner = inner
+                self.outer = outer
             def foo(self):
                 pass
             def bar(self):
@@ -62,11 +74,13 @@
         c = object()
         f = MixinFactory
         n = ('foo',)
-        w = self.proxy_class(obj, c, f, n)
+        ad = {'baz':23}
+        w = self.proxy_class(obj, c, f, n, ad)
 
-        # getnamesdict is not in the official decorator interface, but it
-        # is provided so that the caching dict can be unit-tested from Python.
-        self.assertEquals(decorator.getnamesdict(w).keys(), ['foo',])
+        keys = decorator.getnamesdict(w).keys()
+        keys.sort()
+        self.assertEquals(keys, ['baz', 'foo'])
+        self.assertEquals(decorator.getnamesdict(w)['baz'], 23)
 
         self.assert_(wrapper.getcontext(w) is c)
         self.assert_(decorator.getmixin(w) is None)
@@ -76,9 +90,19 @@
         # Check that accessing a non-name does not create the mixin.
         w.bar()
         self.assert_(decorator.getmixin(w) is None)
+        # Check that accessing something from the attrdict does not create the
+        # mixin.
+        w.baz
+        self.assert_(decorator.getmixin(w) is None)
+
         # Check that accessing a name creates the mixin.
         w.foo()
-        self.assert_(type(decorator.getmixin(w)) is MixinFactory)
+        mixin = decorator.getmixin(w)
+        self.assert_(type(mixin) is MixinFactory)
+
+        # Check that the mixin factory is constructed with the correct args.
+        self.assert_(mixin.inner is obj)
+        self.assert_(mixin.outer is w)
 
         # check that getmixincreate works
         w = self.proxy_class(obj, c, f, n)
@@ -94,14 +118,17 @@
         obj = SomeObject()
 
         class MixinFactory(object):
+            def __init__(self, inner, outer):
+                pass
             def foo(self):
                 pass
             def bar(self):
                 pass
+            spoo = 23
 
         c = object()
         f = MixinFactory
-        n = ('foo',)
+        n = ('foo', 'spoo')
         w = self.proxy_class(obj, c, f, n)
 
         self.assert_(decorator.getmixin(w) is None)
@@ -113,6 +140,7 @@
         w.foo()
         mixin2 = decorator.getmixin(w)
         self.assert_(mixin is mixin2)
+        self.assertEqual(w.spoo, 23)
 
     def test_typeerror_if_no_factory(self):
         w = self.proxy_class(object(), None, None, ('foo',))
@@ -123,6 +151,8 @@
         obj = object()
 
         class MixinFactory(object):
+            def __init__(self, inner, outer):
+                pass
             def setFoo(self, value):
                 self.fooval = value
             def getFoo(self):
@@ -131,7 +161,7 @@
                 del self.fooval
             foo = property(getFoo, setFoo, delFoo)
 
-        w = self.proxy_class(obj, None, MixinFactory, ('foo',))
+        w = self.proxy_class(obj, None, MixinFactory, ('foo',), {'baz': 23})
         mixin = decorator.getmixincreate(w)
         self.failIf(hasattr(mixin, 'fooval'))
         self.assertRaises(AttributeError, getattr, w, 'foo')
@@ -141,6 +171,10 @@
         del w.foo
         self.failIf(hasattr(mixin, 'fooval'))
 
+        # check that trying to set something in attrdict fails.
+        self.assertRaises(AttributeError, setattr, w, 'baz', 23)
+        self.assertRaises(AttributeError, delattr, w, 'baz')
+
     def test_decorated_slots(self):
         obj = object()
 
@@ -236,7 +270,7 @@
         obj = object()
         a = [1, 2, 3]
         b = []
-        factory = lambda: a
+        factory = lambda inner, outer: a
         names = ('__iter__',)
         for x in self.proxy_class(obj, None, factory, names):
             b.append(x)
@@ -248,7 +282,7 @@
         obj = object()
         a = [1, 2, 3]
         b = []
-        factory = lambda: iter(a)
+        factory = lambda inner, outer: iter(a)
         names = ('__iter__',)
         for x in self.proxy_class(obj, None, factory, names):
             b.append(x)
@@ -273,7 +307,7 @@
             def __iter__(self):
                 obj = object()
                 names = ('__iter__', 'next')
-                factory = lambda: iter(self.data)
+                factory = lambda inner, outer: iter(self.data)
                 return self.test.proxy_class(obj, None, factory, names)
 
         a = [1, 2, 3]