580 lines
17 KiB
Python
580 lines
17 KiB
Python
from __future__ import print_function
|
|
|
|
import unittest
|
|
|
|
import wrapt
|
|
import wrapt.wrappers
|
|
|
|
from compat import PY2, PY3, exec_
|
|
|
|
class TestClassInheritence(unittest.TestCase):
|
|
|
|
def test_function_type_inheritence(self):
|
|
@wrapt.decorator
|
|
def _decorator(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
|
|
@_decorator
|
|
def _function(*args, **kwargs):
|
|
return args, kwargs
|
|
|
|
self.assertTrue(isinstance(_function, wrapt.FunctionWrapper))
|
|
self.assertTrue(isinstance(_function, wrapt.ObjectProxy))
|
|
|
|
def test_instancemethod_type_inheritence(self):
|
|
@wrapt.decorator
|
|
def _decorator(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
|
|
class Class(object):
|
|
@_decorator
|
|
def function(self, args, **kwargs):
|
|
return args, kwargs
|
|
|
|
self.assertTrue(isinstance(function, wrapt.FunctionWrapper))
|
|
self.assertTrue(isinstance(function, wrapt.ObjectProxy))
|
|
|
|
instance = Class()
|
|
|
|
self.assertFalse(isinstance(instance.function, wrapt.FunctionWrapper))
|
|
self.assertTrue(isinstance(instance.function, wrapt.ObjectProxy))
|
|
|
|
def test_classmethod_type_inheritence(self):
|
|
@wrapt.decorator
|
|
def _decorator(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
|
|
class Class(object):
|
|
@_decorator
|
|
@classmethod
|
|
def function(cls, *args, **kwargs):
|
|
return args, kwargs
|
|
|
|
self.assertTrue(isinstance(function, wrapt.FunctionWrapper))
|
|
self.assertTrue(isinstance(function, wrapt.ObjectProxy))
|
|
|
|
instance = Class()
|
|
|
|
self.assertFalse(isinstance(instance.function, wrapt.FunctionWrapper))
|
|
self.assertTrue(isinstance(instance.function, wrapt.ObjectProxy))
|
|
|
|
def test_staticmethod_type_inheritence(self):
|
|
@wrapt.decorator
|
|
def _decorator(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
|
|
class Class(object):
|
|
@_decorator
|
|
@staticmethod
|
|
def function(*args, **kwargs):
|
|
return args, kwargs
|
|
|
|
self.assertTrue(isinstance(function, wrapt.FunctionWrapper))
|
|
self.assertTrue(isinstance(function, wrapt.ObjectProxy))
|
|
|
|
instance = Class()
|
|
|
|
self.assertFalse(isinstance(instance.function, wrapt.FunctionWrapper))
|
|
self.assertTrue(isinstance(instance.function, wrapt.ObjectProxy))
|
|
|
|
class TestAttributeAccess(unittest.TestCase):
|
|
|
|
def test_function_attributes(self):
|
|
def decorator1(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
decorator2 = wrapt.decorator(decorator1)
|
|
|
|
def function1(*args, **kwargs):
|
|
return args, kwargs
|
|
function2 = decorator2(function1)
|
|
|
|
self.assertEqual(function2.__wrapped__, function1)
|
|
self.assertEqual(function2._self_wrapper, decorator1)
|
|
self.assertEqual(function2._self_binding, 'function')
|
|
|
|
def test_instancemethod_attributes(self):
|
|
def decorator1(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
decorator2 = wrapt.decorator(decorator1)
|
|
|
|
class Class(object):
|
|
def function1(self, *args, **kwargs):
|
|
return args, kwargs
|
|
function2 = decorator2(function1)
|
|
|
|
self.assertEqual(function2.__wrapped__, function1)
|
|
self.assertEqual(function2._self_wrapper, decorator1)
|
|
self.assertEqual(function2._self_binding, 'function')
|
|
|
|
instance = Class()
|
|
|
|
self.assertEqual(instance.function2.__wrapped__, instance.function1)
|
|
self.assertEqual(instance.function2._self_instance, instance)
|
|
self.assertEqual(instance.function2._self_wrapper, decorator1)
|
|
|
|
def test_classmethod_attributes(self):
|
|
def decorator1(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
decorator2 = wrapt.decorator(decorator1)
|
|
|
|
class Class(object):
|
|
@classmethod
|
|
def function1(cls, *args, **kwargs):
|
|
return args, kwargs
|
|
function2 = decorator2(function1)
|
|
|
|
self.assertEqual(function2.__wrapped__, function1)
|
|
self.assertEqual(function2._self_wrapper, decorator1)
|
|
self.assertEqual(function2._self_binding, 'classmethod')
|
|
|
|
instance = Class()
|
|
|
|
self.assertEqual(instance.function2.__wrapped__, instance.function1)
|
|
self.assertEqual(instance.function2._self_instance, instance)
|
|
self.assertEqual(instance.function2._self_wrapper, decorator1)
|
|
|
|
def test_staticmethod_attributes(self):
|
|
def decorator1(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
decorator2 = wrapt.decorator(decorator1)
|
|
|
|
class Class(object):
|
|
@staticmethod
|
|
def function1(*args, **kwargs):
|
|
return args, kwargs
|
|
function2 = decorator2(function1)
|
|
|
|
self.assertEqual(function2.__wrapped__, function1)
|
|
self.assertEqual(function2._self_wrapper, decorator1)
|
|
self.assertEqual(function2._self_binding, 'staticmethod')
|
|
|
|
def test_instancemethod_attributes_external_class(self):
|
|
def decorator1(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
decorator2 = wrapt.decorator(decorator1)
|
|
|
|
class Class(object):
|
|
def function1(self, *args, **kwargs):
|
|
return args, kwargs
|
|
|
|
function2 = decorator2(Class.function1)
|
|
|
|
self.assertEqual(function2._self_wrapper, decorator2)
|
|
|
|
# We can't identify this as being an instance method in
|
|
# Python 3 because there is no concept of unbound methods.
|
|
# We therefore don't try for Python 2 either.
|
|
|
|
self.assertEqual(function2._self_binding, 'function')
|
|
|
|
def test_classmethod_attributes_external_class(self):
|
|
def decorator1(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
decorator2 = wrapt.decorator(decorator1)
|
|
|
|
class Class(object):
|
|
@classmethod
|
|
def function1(cls, *args, **kwargs):
|
|
return args, kwargs
|
|
|
|
function2 = decorator2(Class.function1)
|
|
|
|
self.assertEqual(function2._self_wrapper, decorator2)
|
|
self.assertEqual(function2._self_binding, 'classmethod')
|
|
|
|
def test_staticmethod_attributes_external_class(self):
|
|
def decorator1(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
decorator2 = wrapt.decorator(decorator1)
|
|
|
|
class Class(object):
|
|
@staticmethod
|
|
def function1(*args, **kwargs):
|
|
return args, kwargs
|
|
|
|
function2 = decorator2(Class.function1)
|
|
|
|
self.assertEqual(function2._self_wrapper, decorator2)
|
|
|
|
# We can't identify this as being a static method because
|
|
# the binding has resulted in a normal function being returned.
|
|
|
|
self.assertEqual(function2._self_binding, 'function')
|
|
|
|
def test_instancemethod_attributes_external_instance(self):
|
|
def decorator1(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
decorator2 = wrapt.decorator(decorator1)
|
|
|
|
class Class(object):
|
|
def function1(self, *args, **kwargs):
|
|
return args, kwargs
|
|
|
|
function2 = decorator2(Class().function1)
|
|
|
|
self.assertEqual(function2._self_wrapper, decorator2)
|
|
|
|
# We can't identify this as being an instance method in
|
|
# Python 3 when it is a class so have to disable the check
|
|
# for Python 2. This has flow on effect of not working
|
|
# in the case of an instance either.
|
|
|
|
self.assertEqual(function2._self_binding, 'function')
|
|
|
|
def test_classmethod_attributes_external_instance(self):
|
|
def decorator1(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
decorator2 = wrapt.decorator(decorator1)
|
|
|
|
class Class(object):
|
|
@classmethod
|
|
def function1(cls, *args, **kwargs):
|
|
return args, kwargs
|
|
|
|
function2 = decorator2(Class().function1)
|
|
|
|
self.assertEqual(function2._self_wrapper, decorator2)
|
|
self.assertEqual(function2._self_binding, 'classmethod')
|
|
|
|
def test_staticmethod_attributes_external_instance(self):
|
|
def decorator1(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
decorator2 = wrapt.decorator(decorator1)
|
|
|
|
class Class(object):
|
|
@staticmethod
|
|
def function1(*args, **kwargs):
|
|
return args, kwargs
|
|
|
|
function2 = decorator2(Class().function1)
|
|
|
|
self.assertEqual(function2._self_wrapper, decorator2)
|
|
|
|
# We can't identify this as being a static method because
|
|
# the binding has resulted in a normal function being returned.
|
|
|
|
self.assertEqual(function2._self_binding, 'function')
|
|
|
|
class TestParentReference(unittest.TestCase):
|
|
|
|
def test_function_decorator(self):
|
|
@wrapt.decorator
|
|
def _decorator(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
|
|
@_decorator
|
|
def function():
|
|
pass
|
|
|
|
self.assertEqual(function._self_parent, None)
|
|
|
|
def test_class_decorator(self):
|
|
@wrapt.decorator
|
|
def _decorator(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
|
|
@_decorator
|
|
class Class:
|
|
pass
|
|
|
|
self.assertEqual(Class._self_parent, None)
|
|
|
|
def test_nested_class_decorator(self):
|
|
@wrapt.decorator
|
|
def _decorator(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
|
|
class Class:
|
|
@_decorator
|
|
class Nested:
|
|
pass
|
|
|
|
self.assertEqual(Class.Nested._self_parent, None)
|
|
|
|
def test_instancemethod(self):
|
|
@wrapt.decorator
|
|
def _decorator(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
|
|
class Class:
|
|
@_decorator
|
|
def function_im(self):
|
|
pass
|
|
|
|
c = Class()
|
|
|
|
self.assertNotEqual(c.function_im._self_parent, None)
|
|
self.assertNotEqual(Class.function_im._self_parent, None)
|
|
|
|
def test_classmethod(self):
|
|
@wrapt.decorator
|
|
def _decorator(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
|
|
class Class:
|
|
@_decorator
|
|
@classmethod
|
|
def function_cm(cls):
|
|
pass
|
|
|
|
self.assertNotEqual(Class.function_cm._self_parent, None)
|
|
|
|
def test_staticmethod_inner(self):
|
|
@wrapt.decorator
|
|
def _decorator(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
|
|
class Class:
|
|
@_decorator
|
|
@staticmethod
|
|
def function_sm_inner():
|
|
pass
|
|
|
|
self.assertNotEqual(Class.function_sm_inner._self_parent, None)
|
|
|
|
class TestGuardArgument(unittest.TestCase):
|
|
|
|
def test_boolean_false_guard_on_decorator(self):
|
|
@wrapt.decorator(enabled=False)
|
|
def _decorator(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
|
|
@_decorator
|
|
def function():
|
|
pass
|
|
|
|
self.assertFalse(isinstance(function, wrapt.FunctionWrapper))
|
|
|
|
def test_boolean_true_guard_on_decorator(self):
|
|
@wrapt.decorator(enabled=True)
|
|
def _decorator(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
|
|
@_decorator
|
|
def function():
|
|
pass
|
|
|
|
self.assertTrue(isinstance(function, wrapt.FunctionWrapper))
|
|
|
|
def test_boolean_dynamic_guard_on_decorator(self):
|
|
class Guard(object):
|
|
value = True
|
|
def __nonzero__(self):
|
|
return self.value
|
|
__bool__ = __nonzero__
|
|
|
|
guard = Guard()
|
|
|
|
result = []
|
|
|
|
@wrapt.decorator(enabled=guard)
|
|
def _decorator(wrapped, instance, args, kwargs):
|
|
result.append(1)
|
|
return wrapped(*args, **kwargs)
|
|
|
|
@_decorator
|
|
def function():
|
|
pass
|
|
|
|
self.assertTrue(isinstance(function, wrapt.FunctionWrapper))
|
|
|
|
function()
|
|
|
|
self.assertNotEqual(len(result), 0)
|
|
|
|
result = []
|
|
guard.value = False
|
|
|
|
function()
|
|
|
|
self.assertEqual(len(result), 0)
|
|
|
|
def test_function_guard_on_decorator(self):
|
|
value = True
|
|
def guard():
|
|
return value
|
|
|
|
result = []
|
|
|
|
@wrapt.decorator(enabled=guard)
|
|
def _decorator(wrapped, instance, args, kwargs):
|
|
result.append(1)
|
|
return wrapped(*args, **kwargs)
|
|
|
|
@_decorator
|
|
def function():
|
|
pass
|
|
|
|
self.assertTrue(isinstance(function, wrapt.FunctionWrapper))
|
|
|
|
function()
|
|
|
|
self.assertNotEqual(len(result), 0)
|
|
|
|
result = []
|
|
value = False
|
|
|
|
function()
|
|
|
|
self.assertEqual(len(result), 0)
|
|
|
|
def test_guard_on_instancemethod(self):
|
|
value = True
|
|
def guard():
|
|
return value
|
|
|
|
result = []
|
|
|
|
@wrapt.decorator(enabled=guard)
|
|
def _decorator(wrapped, instance, args, kwargs):
|
|
result.append(1)
|
|
return wrapped(*args, **kwargs)
|
|
|
|
class Class(object):
|
|
@_decorator
|
|
def function(self):
|
|
pass
|
|
|
|
c = Class()
|
|
|
|
self.assertTrue(isinstance(c.function, wrapt.BoundFunctionWrapper))
|
|
|
|
c.function()
|
|
|
|
self.assertNotEqual(len(result), 0)
|
|
|
|
result = []
|
|
value = False
|
|
|
|
self.assertTrue(isinstance(c.function, wrapt.BoundFunctionWrapper))
|
|
|
|
c.function()
|
|
|
|
self.assertEqual(len(result), 0)
|
|
|
|
class TestDerivedFunctionWrapper(unittest.TestCase):
|
|
|
|
def test_override_bound_type(self):
|
|
|
|
class _BoundFunctionWrapper(wrapt.BoundFunctionWrapper):
|
|
ATTRIBUTE = 1
|
|
|
|
class _FunctionWrapper(wrapt.FunctionWrapper):
|
|
__bound_function_wrapper__ = _BoundFunctionWrapper
|
|
|
|
def function():
|
|
pass
|
|
|
|
def wrapper(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
|
|
_wrapper = _FunctionWrapper(function, wrapper)
|
|
|
|
self.assertTrue(isinstance(_wrapper, _FunctionWrapper))
|
|
|
|
instance = object()
|
|
|
|
_bound_wrapper = _wrapper.__get__(instance, type(instance))
|
|
|
|
self.assertTrue(isinstance(_bound_wrapper, _BoundFunctionWrapper))
|
|
self.assertEqual(_bound_wrapper.ATTRIBUTE, 1)
|
|
|
|
class TestFunctionBinding(unittest.TestCase):
|
|
|
|
def test_double_binding(self):
|
|
|
|
def function():
|
|
pass
|
|
|
|
def wrapper(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
|
|
_wrapper = wrapt.FunctionWrapper(function, wrapper)
|
|
|
|
self.assertTrue(isinstance(_wrapper, wrapt.FunctionWrapper))
|
|
|
|
instance = object()
|
|
|
|
_bound_wrapper_1 = _wrapper.__get__(instance, type(instance))
|
|
|
|
self.assertTrue(_bound_wrapper_1._self_parent is _wrapper)
|
|
|
|
self.assertTrue(isinstance(_bound_wrapper_1,
|
|
wrapt.BoundFunctionWrapper))
|
|
self.assertEqual(_bound_wrapper_1._self_instance, instance)
|
|
|
|
_bound_wrapper_2 = _bound_wrapper_1.__get__(instance, type(instance))
|
|
|
|
self.assertTrue(_bound_wrapper_2._self_parent is _wrapper)
|
|
|
|
self.assertTrue(isinstance(_bound_wrapper_2,
|
|
wrapt.BoundFunctionWrapper))
|
|
self.assertEqual(_bound_wrapper_2._self_instance,
|
|
_bound_wrapper_1._self_instance)
|
|
|
|
self.assertTrue(_bound_wrapper_1 is _bound_wrapper_2)
|
|
|
|
def test_re_bind_after_none(self):
|
|
|
|
def function():
|
|
pass
|
|
|
|
def wrapper(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
|
|
_wrapper = wrapt.FunctionWrapper(function, wrapper)
|
|
|
|
self.assertTrue(isinstance(_wrapper, wrapt.FunctionWrapper))
|
|
|
|
instance = object()
|
|
|
|
_bound_wrapper_1 = _wrapper.__get__(None, type(instance))
|
|
|
|
self.assertTrue(_bound_wrapper_1._self_parent is _wrapper)
|
|
|
|
self.assertTrue(isinstance(_bound_wrapper_1,
|
|
wrapt.BoundFunctionWrapper))
|
|
self.assertEqual(_bound_wrapper_1._self_instance, None)
|
|
|
|
_bound_wrapper_2 = _bound_wrapper_1.__get__(instance, type(instance))
|
|
|
|
self.assertTrue(_bound_wrapper_2._self_parent is _wrapper)
|
|
|
|
self.assertTrue(isinstance(_bound_wrapper_2,
|
|
wrapt.BoundFunctionWrapper))
|
|
self.assertEqual(_bound_wrapper_2._self_instance, instance)
|
|
|
|
self.assertTrue(_bound_wrapper_1 is not _bound_wrapper_2)
|
|
|
|
class TestInvalidWrapper(unittest.TestCase):
|
|
|
|
def test_none_for_wrapped(self):
|
|
|
|
def run(*args):
|
|
def _wrapper(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
wrapper = wrapt.FunctionWrapper(None, _wrapper)
|
|
wrapper.__get__(list(), list)()
|
|
|
|
self.assertRaises(AttributeError, run, ())
|
|
|
|
class TestInvalidCalling(unittest.TestCase):
|
|
|
|
def test_missing_self_via_class(self):
|
|
@wrapt.decorator
|
|
def _decorator(wrapped, instance, args, kwargs):
|
|
return wrapped(*args, **kwargs)
|
|
|
|
class Class(object):
|
|
@_decorator
|
|
def method(self):
|
|
pass
|
|
|
|
def run(*args):
|
|
Class.method()
|
|
|
|
self.assertRaises(TypeError, run, ())
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|