Raise TypeError when attempt to delete __wrapped__ on pure Python implementation and del/update __qualname__ when __wrapped__ set.

This commit is contained in:
Graham Dumpleton
2013-09-21 21:16:20 +10:00
parent b47de0ba7f
commit 43bd3cd559
2 changed files with 55 additions and 4 deletions

View File

@@ -129,11 +129,25 @@ class ObjectProxy(six.with_metaclass(_ObjectProxyMetaType)):
return bool(self.__wrapped__)
def __setattr__(self, name, value):
if name.startswith('_self_') or name == '__wrapped__':
if name.startswith('_self_'):
object.__setattr__(self, name, value)
elif name == '__wrapped__':
object.__setattr__(self, name, value)
try:
object.__delattr__(self, '__qualname__')
except AttributeError:
pass
object.__setattr__(self, name, value)
try:
object.__setattr__(self, '__qualname__', value.__qualname__)
except AttributeError:
pass
elif name == '__qualname__':
setattr(self.__wrapped__, name, value)
object.__setattr__(self, name, value)
else:
setattr(self.__wrapped__, name, value)
@@ -141,11 +155,16 @@ class ObjectProxy(six.with_metaclass(_ObjectProxyMetaType)):
return getattr(self.__wrapped__, name)
def __delattr__(self, name):
if name.startswith('_self_') or name == '__wrapped__':
if name.startswith('_self_'):
object.__delattr__(self, name)
elif name == '__wrapped__':
raise TypeError('__wrapped__ must be an object')
elif name == '__qualname__':
object.__delattr__(self, name)
delattr(self.__wrapped__, name)
else:
delattr(self.__wrapped__, name)

View File

@@ -51,14 +51,46 @@ class TestAttributeAccess(unittest.TestCase):
return args, kwargs
function2 = wrapt.ObjectProxy(function1)
self.assertEqual(function2, function1)
self.assertEqual(function2.__wrapped__, function1)
self.assertEqual(function2.__name__, function1.__name__)
if six.PY3:
self.assertEqual(function2.__qualname__, function1.__qualname__)
function2.__wrapped__ = None
self.assertEqual(function2.__wrapped__, None)
self.assertFalse(hasattr(function1, '__wrapped__'))
self.assertEqual(function2, None)
self.assertEqual(function2.__wrapped__, None)
self.assertFalse(hasattr(function2, '__name__'))
if six.PY3:
self.assertFalse(hasattr(function2, '__qualname__'))
def function3(*args, **kwargs):
return args, kwargs
function2.__wrapped__ = function3
self.assertEqual(function2, function3)
self.assertEqual(function2.__wrapped__, function3)
self.assertEqual(function2.__name__, function3.__name__)
if six.PY3:
self.assertEqual(function2.__qualname__, function3.__qualname__)
def test_delete_wrapped(self):
def function1(*args, **kwargs):
return args, kwargs
function2 = wrapt.ObjectProxy(function1)
def run(*args):
del function2.__wrapped__
self.assertRaises(TypeError, run, ())
def test_proxy_attribute(self):
def function1(*args, **kwargs):
return args, kwargs