[Checkins] SVN: zope.proxy/trunk/ Fix 'non_overridable' decorator under pure Python.

Tres Seaver cvs-admin at zope.org
Wed Jun 6 20:13:35 UTC 2012


Log message for revision 126628:
  Fix 'non_overridable' decorator under pure Python.

Changed:
  _U  zope.proxy/trunk/
  U   zope.proxy/trunk/src/zope/proxy/__init__.py
  U   zope.proxy/trunk/src/zope/proxy/tests/test_proxy.py
  U   zope.proxy/trunk/tox.ini

-=-
Modified: zope.proxy/trunk/src/zope/proxy/__init__.py
===================================================================
--- zope.proxy/trunk/src/zope/proxy/__init__.py	2012-06-06 20:13:28 UTC (rev 126627)
+++ zope.proxy/trunk/src/zope/proxy/__init__.py	2012-06-06 20:13:32 UTC (rev 126628)
@@ -30,9 +30,8 @@
         p = getProxiedObject(p)
         yield p
 
-def non_overridable(func):
-    return property(lambda self: func.__get__(self))
 
+_MARKER = object()
 
 class PyProxyBase(object):
     """Reference implementation.
@@ -62,6 +61,9 @@
     def __reduce__(self):
         raise pickle.PicklingError
 
+    def __reduce_ex__(self, proto):
+        raise pickle.PicklingError
+
     # Rich comparison protocol
     def __lt__(self, other):
         return self._wrapped < other
@@ -89,6 +91,24 @@
         return hash(self._wrapped)
 
     # Attribute protocol
+    def __getattribute__(self, name):
+        wrapped = super(PyProxyBase, self).__getattribute__('_wrapped')
+        if name == '_wrapped':
+            return wrapped
+        try:
+            mine = super(PyProxyBase, self).__getattribute__(name)
+        except AttributeError:
+            mine = _MARKER
+        else:
+            if isinstance(mine, PyNonOverridable):
+                return mine.desc.__get__(self)
+        try:
+            return getattr(wrapped, name)
+        except AttributeError:
+            if mine is not _MARKER:
+                return mine
+            raise
+
     def __getattr__(self, name):
         return getattr(self._wrapped, name)
 
@@ -392,6 +412,10 @@
         obj = obj._wrapped
     return obj
 
+class PyNonOverridable(object):
+    def __init__(self, method_desc):
+        self.desc = method_desc
+
 try:
     # Python API:  not used in this module
     from zope.proxy._zope_proxy_proxy import ProxyBase
@@ -415,3 +439,7 @@
     queryProxy = py_queryProxy
     queryInnerProxy = py_queryInnerProxy
     removeAllProxies = py_removeAllProxies
+    non_overridable = PyNonOverridable
+else:
+    def non_overridable(func):
+        return property(lambda self: func.__get__(self))

Modified: zope.proxy/trunk/src/zope/proxy/tests/test_proxy.py
===================================================================
--- zope.proxy/trunk/src/zope/proxy/tests/test_proxy.py	2012-06-06 20:13:28 UTC (rev 126627)
+++ zope.proxy/trunk/src/zope/proxy/tests/test_proxy.py	2012-06-06 20:13:32 UTC (rev 126628)
@@ -117,7 +117,7 @@
                 """This class is expected to be a classic class."""
             w = self._makeOne(Thing())
             self.assertRaises(pickle.PicklingError,
-                            pickle.dumps, w)
+                              pickle.dumps, w)
 
     def test___eq___and___ne__(self):
         w = self._makeOne('foo')
@@ -187,6 +187,17 @@
         w = self._makeOne(o)
         self.assertEqual(w.foo, 1)
 
+    def test___getattr__delegates_to_wrapped_when_conflict(self):
+        class Proxy(self._getTargetClass()):
+            def foo(self):
+                return 'PROXY'
+        class Foo(object):
+            def foo(self):
+                return 'FOO'
+        o = Foo()
+        w = Proxy(o)
+        self.assertEqual(w.foo(), 'FOO')
+
     def test___setattr__delegates_to_wrapped(self):
         class Foo(object):
             pass

Modified: zope.proxy/trunk/tox.ini
===================================================================
--- zope.proxy/trunk/tox.ini	2012-06-06 20:13:28 UTC (rev 126627)
+++ zope.proxy/trunk/tox.ini	2012-06-06 20:13:32 UTC (rev 126628)
@@ -3,7 +3,7 @@
 # Jython support pending 2.7 support, due 2012-07-15 or so.  See:
 # http://fwierzbicki.blogspot.com/2012/03/adconion-to-fund-jython-27.html
 #   py26,py27,py32,jython,pypy,coverage
-    py26,py27,py32,coverage,docs
+    py26,py27,py32,pypy,coverage,docs
 
 [testenv]
 commands = 



More information about the checkins mailing list