Commit 9a2d8ad8 authored by Tres Seaver's avatar Tres Seaver

Fix 'non_overridable' decorator under pure Python.

parent 406f1ca7
......@@ -30,9 +30,8 @@ def ProxyIterator(p):
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 @@ class PyProxyBase(object):
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 @@ class PyProxyBase(object):
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 @@ def py_removeAllProxies(obj):
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 @@ except ImportError: #pragma NO COVER
queryProxy = py_queryProxy
queryInnerProxy = py_queryInnerProxy
removeAllProxies = py_removeAllProxies
non_overridable = PyNonOverridable
else:
def non_overridable(func):
return property(lambda self: func.__get__(self))
......@@ -117,7 +117,7 @@ class PyProxyBaseTestCase(unittest.TestCase):
"""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 @@ class PyProxyBaseTestCase(unittest.TestCase):
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
......
......@@ -3,7 +3,7 @@ envlist =
# 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 =
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment