=================================== FAILURES ===================================
_____________ TestCallingOuterClassMethod.test_class_call_function _____________
self = <test_outer_classmethod.TestCallingOuterClassMethod testMethod=test_class_call_function>
def test_class_call_function(self):
# Test calling classmethod. Prior to Python 3.9, the instance
# and class passed to the wrapper will both be None because our
# decorator is surrounded by the classmethod decorator. The
# classmethod decorator doesn't bind the method and treats it
# like a normal function, explicitly passing the class as the
# first argument with the actual arguments following that. This
# was only finally fixed in Python 3.9. For more details see:
# https://bugs.python.org/issue19072
_args = (1, 2)
_kwargs = {'one': 1, 'two': 2}
@wrapt.decorator
def _decorator(wrapped, instance, args, kwargs):
if PYXY < (3, 9):
self.assertEqual(instance, None)
self.assertEqual(args, (Class,)+_args)
else:
self.assertEqual(instance, Class)
self.assertEqual(args, _args)
self.assertEqual(kwargs, _kwargs)
self.assertEqual(wrapped.__module__, _function.__module__)
self.assertEqual(wrapped.__name__, _function.__name__)
return wrapped(*args, **kwargs)
@_decorator
def _function(*args, **kwargs):
return args, kwargs
class Class(object):
@classmethod
@_decorator
def _function(cls, *args, **kwargs):
return (args, kwargs)
> result = Class._function(*_args, **_kwargs)
tests/test_outer_classmethod.py:160:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests/test_outer_classmethod.py:141: in _decorator
self.assertEqual(instance, Class)
E AssertionError: None != <class 'test_outer_classmethod.TestCallin[54 chars]ass'>
___________ TestCallingOuterClassMethod.test_instance_call_function ____________
self = <test_outer_classmethod.TestCallingOuterClassMethod testMethod=test_instance_call_function>
def test_instance_call_function(self):
# Test calling classmethod via class instance. Prior to Python
# 3.9, the instance and class passed to the wrapper will both be
# None because our decorator is surrounded by the classmethod
# decorator. The classmethod decorator doesn't bind the method
# and treats it like a normal function, explicitly passing the
# class as the first argument with the actual arguments
# following that. This was only finally fixed in Python 3.9. For
# more details see: https://bugs.python.org/issue19072
_args = (1, 2)
_kwargs = {'one': 1, 'two': 2}
@wrapt.decorator
def _decorator(wrapped, instance, args, kwargs):
if PYXY < (3, 9):
self.assertEqual(instance, None)
self.assertEqual(args, (Class,)+_args)
else:
self.assertEqual(instance, Class)
self.assertEqual(args, _args)
self.assertEqual(kwargs, _kwargs)
self.assertEqual(wrapped.__module__, _function.__module__)
self.assertEqual(wrapped.__name__, _function.__name__)
return wrapped(*args, **kwargs)
@_decorator
def _function(*args, **kwargs):
return args, kwargs
class Class(object):
@classmethod
@_decorator
def _function(cls, *args, **kwargs):
return (args, kwargs)
> result = Class()._function(*_args, **_kwargs)
tests/test_outer_classmethod.py:202:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests/test_outer_classmethod.py:183: in _decorator
self.assertEqual(instance, Class)
E AssertionError: None != <class 'test_outer_classmethod.TestCallin[57 chars]ass'>
_____________ TestSynchronized.test_synchronized_outer_classmethod _____________
self = <test_synchronized_lock.TestSynchronized testMethod=test_synchronized_outer_classmethod>
def test_synchronized_outer_classmethod(self):
# Prior to Python 3.9 this isn't detected as a class method
# call, as the classmethod decorator doesn't bind the wrapped
# function to the class before calling and just calls it direct,
# explicitly passing the class as first argument. For more
# details see: https://bugs.python.org/issue19072
if PYXY < (3, 9):
_lock0 = getattr(C4.function2, '_synchronized_lock', None)
else:
_lock0 = getattr(C4, '_synchronized_lock', None)
self.assertEqual(_lock0, None)
c4.function2()
if PYXY < (3, 9):
_lock1 = getattr(C4.function2, '_synchronized_lock', None)
else:
_lock1 = getattr(C4, '_synchronized_lock', None)
> self.assertNotEqual(_lock1, None)
E AssertionError: None == None
tests/test_synchronized_lock.py:181: AssertionError
----------------------------- Captured stdout call -----------------------------
function2
=========================== short test summary info ============================
FAILED tests/test_outer_classmethod.py::TestCallingOuterClassMethod::test_class_call_function
FAILED tests/test_outer_classmethod.py::TestCallingOuterClassMethod::test_instance_call_function
FAILED tests/test_synchronized_lock.py::TestSynchronized::test_synchronized_outer_classmethod
======================== 3 failed, 435 passed in 0.83s =========================
Fixes https://github.com/GrahamDumpleton/wrapt/issues/259
The failures were:
To fix the same failures on Python 3.9, they were adjusted in the past. For details see https://github.com/GrahamDumpleton/wrapt/issues/160
However, Python 3.13 reverted the change from 3.9, so this adds an upper bound for the conditionals.
To make the conditionals easier to read, the if-else branches were switched.