Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
devel:languages:python:backports
python-wrapt
py313-classmethods.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File py313-classmethods.patch of Package python-wrapt
From 9a38c9f45a2e9d2a306deedce2e243b5e7a83ab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro@hroncok.cz> Date: Fri, 8 Mar 2024 00:40:11 +0100 Subject: [PATCH] Fix classmethod tests with Python 3.13+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/GrahamDumpleton/wrapt/issues/259 The failures were: =================================== 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 ========================= 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. Signed-off-by: Filipe LaĆns <lains@riseup.net> --- tests/test_outer_classmethod.py | 18 ++++++++++-------- tests/test_synchronized_lock.py | 26 ++++++++++++++------------ 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/tests/test_outer_classmethod.py b/tests/test_outer_classmethod.py index ab807646..c08d34a5 100644 --- a/tests/test_outer_classmethod.py +++ b/tests/test_outer_classmethod.py @@ -128,18 +128,20 @@ def test_class_call_function(self): # 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 + # Starting with Python 3.13 the old behavior is back. + # For more details see https://github.com/python/cpython/issues/89519 _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: + if (3, 9) <= PYXY < (3, 13): self.assertEqual(instance, Class) self.assertEqual(args, _args) + else: + self.assertEqual(instance, None) + self.assertEqual(args, (Class,)+_args) self.assertEqual(kwargs, _kwargs) self.assertEqual(wrapped.__module__, _function.__module__) @@ -176,12 +178,12 @@ def test_instance_call_function(self): @wrapt.decorator def _decorator(wrapped, instance, args, kwargs): - if PYXY < (3, 9): - self.assertEqual(instance, None) - self.assertEqual(args, (Class,)+_args) - else: + if (3, 9) <= PYXY < (3, 13): self.assertEqual(instance, Class) self.assertEqual(args, _args) + else: + self.assertEqual(instance, None) + self.assertEqual(args, (Class,)+_args) self.assertEqual(kwargs, _kwargs) self.assertEqual(wrapped.__module__, _function.__module__) diff --git a/tests/test_synchronized_lock.py b/tests/test_synchronized_lock.py index 0e43f7af..7c41aa5a 100644 --- a/tests/test_synchronized_lock.py +++ b/tests/test_synchronized_lock.py @@ -165,36 +165,38 @@ def test_synchronized_outer_classmethod(self): # 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 + # Starting with Python 3.13 the old behavior is back. + # For more details see https://github.com/python/cpython/issues/89519 - if PYXY < (3, 9): - _lock0 = getattr(C4.function2, '_synchronized_lock', None) - else: + if (3, 9) <= PYXY < (3, 13): _lock0 = getattr(C4, '_synchronized_lock', None) + else: + _lock0 = getattr(C4.function2, '_synchronized_lock', None) self.assertEqual(_lock0, None) c4.function2() - if PYXY < (3, 9): - _lock1 = getattr(C4.function2, '_synchronized_lock', None) - else: + if (3, 9) <= PYXY < (3, 13): _lock1 = getattr(C4, '_synchronized_lock', None) + else: + _lock1 = getattr(C4.function2, '_synchronized_lock', None) self.assertNotEqual(_lock1, None) C4.function2() - if PYXY < (3, 9): - _lock2 = getattr(C4.function2, '_synchronized_lock', None) - else: + if (3, 9) <= PYXY < (3, 13): _lock2 = getattr(C4, '_synchronized_lock', None) + else: + _lock2 = getattr(C4.function2, '_synchronized_lock', None) self.assertNotEqual(_lock2, None) self.assertEqual(_lock2, _lock1) C4.function2() - if PYXY < (3, 9): - _lock3 = getattr(C4.function2, '_synchronized_lock', None) - else: + if (3, 9) <= PYXY < (3, 13): _lock3 = getattr(C4, '_synchronized_lock', None) + else: + _lock3 = getattr(C4.function2, '_synchronized_lock', None) self.assertNotEqual(_lock3, None) self.assertEqual(_lock3, _lock2)
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor