Commit 9e244f27 authored by Jason Madden's avatar Jason Madden

Fix getting methods as attributes.

parent a1932756
...@@ -117,6 +117,11 @@ class PyProxyBase(object): ...@@ -117,6 +117,11 @@ class PyProxyBase(object):
# __class__ is special cased in the C implementation # __class__ is special cased in the C implementation
return wrapped.__class__ return wrapped.__class__
if name in ('__reduce__', '__reduce_ex__'):
# These things we specifically override and no one
# can stop us, not even a subclass
return object.__getattribute__(self, name)
# First, look for descriptors in this object's type # First, look for descriptors in this object's type
type_self = type(self) type_self = type(self)
descriptor = _WrapperType_Lookup(type_self, name) descriptor = _WrapperType_Lookup(type_self, name)
...@@ -124,7 +129,6 @@ class PyProxyBase(object): ...@@ -124,7 +129,6 @@ class PyProxyBase(object):
# Nothing in the class, go straight to the wrapped object # Nothing in the class, go straight to the wrapped object
return getattr(wrapped, name) return getattr(wrapped, name)
if hasattr(descriptor, '__get__'): if hasattr(descriptor, '__get__'):
if not hasattr(descriptor, '__set__'): if not hasattr(descriptor, '__set__'):
# Non-data-descriptor: call through to the wrapped object # Non-data-descriptor: call through to the wrapped object
...@@ -132,7 +136,7 @@ class PyProxyBase(object): ...@@ -132,7 +136,7 @@ class PyProxyBase(object):
try: try:
return getattr(wrapped, name) return getattr(wrapped, name)
except AttributeError: except AttributeError:
raise pass
# Data-descriptor on this type. Call it # Data-descriptor on this type. Call it
return descriptor.__get__(self, type_self) return descriptor.__get__(self, type_self)
return descriptor return descriptor
......
...@@ -642,6 +642,18 @@ class PyProxyBaseTestCase(unittest.TestCase): ...@@ -642,6 +642,18 @@ class PyProxyBaseTestCase(unittest.TestCase):
self.assertRaises(AttributeError, setattr, proxy, 'attr', 42) self.assertRaises(AttributeError, setattr, proxy, 'attr', 42)
self.assertEqual(proxy.attr, "constant value") self.assertEqual(proxy.attr, "constant value")
def test_method_in_proxy_subclass(self):
class Proxy(self._getTargetClass()):
def __getitem__(self, k):
return k
proxy = Proxy(object())
# Both when called by the interpreter, which bypasses
# __getattribute__
self.assertEquals(proxy[42], 42)
# And when asked for as an attribute
self.assertNotEqual(getattr(proxy, '__getitem__'), self)
def test_string_to_int(self): def test_string_to_int(self):
# XXX Implementation difference: This works in the # XXX Implementation difference: This works in the
# Pure-Python version, but fails in CPython. # Pure-Python version, but fails in CPython.
......
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