aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2021-03-17 11:37:13 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2021-04-05 18:18:29 +0000
commit71072bd35e5e78660dea0a07743b15eec017dfde (patch)
tree446d5360c69fe51d7087bcaccc56030fb4008705
parent9d73706fe6efdf4a0a40e08dc0b456136a79e2cd (diff)
community/py3-wrapt: rebuild against python 3.9
upstream issue: https://github.com/GrahamDumpleton/wrapt/issues/160
-rw-r--r--community/py3-wrapt/APKBUILD11
-rw-r--r--community/py3-wrapt/python-3.9.patch179
2 files changed, 186 insertions, 4 deletions
diff --git a/community/py3-wrapt/APKBUILD b/community/py3-wrapt/APKBUILD
index d5a0b6c9e7e..565eb14f7af 100644
--- a/community/py3-wrapt/APKBUILD
+++ b/community/py3-wrapt/APKBUILD
@@ -3,7 +3,7 @@
pkgname=py3-wrapt
_pkgname=wrapt
pkgver=1.12.1
-pkgrel=0
+pkgrel=1
pkgdesc="Module for decorators, wrappers and monkey patching"
url="https://github.com/GrahamDumpleton/wrapt"
arch="all"
@@ -11,7 +11,9 @@ license="BSD-2-Clause"
depends="python3"
makedepends="python3-dev"
checkdepends="py3-pytest"
-source="https://github.com/GrahamDumpleton/wrapt/archive/$pkgver/py3-wrapt-$pkgver.tar.gz"
+source="https://github.com/GrahamDumpleton/wrapt/archive/$pkgver/py3-wrapt-$pkgver.tar.gz
+ python-3.9.patch
+ "
builddir="$srcdir/$_pkgname-$pkgver"
build() {
@@ -19,11 +21,12 @@ build() {
}
check() {
- PYTHONPATH="$(echo $PWD/build/lib.*)" py.test-3 -v
+ PYTHONPATH="$(echo $PWD/build/lib*)" py.test-3 -v
}
package() {
python3 setup.py install --prefix=/usr --root="$pkgdir"
}
-sha512sums="33e964cb3aa2437bc7d084a98f622f7c5c8c719d97806796ae0317d35130bdb2679a9dd87be7077e2cae1eb32b65d152349fa7cc138cb392d5999cbfdcecc9ac py3-wrapt-1.12.1.tar.gz"
+sha512sums="33e964cb3aa2437bc7d084a98f622f7c5c8c719d97806796ae0317d35130bdb2679a9dd87be7077e2cae1eb32b65d152349fa7cc138cb392d5999cbfdcecc9ac py3-wrapt-1.12.1.tar.gz
+372323f80578bc1fe2fdf8d3a5dc67b79956180048f8036be429b3e2fed4c9f3ce3d29a2c9e8b6128a2ab64cf7d21dc1e7026e8df14a062a94bd8518aca5b50a python-3.9.patch"
diff --git a/community/py3-wrapt/python-3.9.patch b/community/py3-wrapt/python-3.9.patch
new file mode 100644
index 00000000000..29617ae1bc6
--- /dev/null
+++ b/community/py3-wrapt/python-3.9.patch
@@ -0,0 +1,179 @@
+From 33708e76578c173333d1879a4a21baddf8fcdb6a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= <mgorny@gentoo.org>
+Date: Fri, 29 May 2020 16:06:07 +0200
+Subject: [PATCH] Update for fixed outer @classmethod behavior in Python 3.9
+
+Fixes #160
+---
+ docs/decorators.rst | 18 ++++++-------
+ tests/test_outer_classmethod.py | 45 +++++++++++++++++++++------------
+ tests/test_synchronized_lock.py | 22 ++++++++--------
+ 3 files changed, 49 insertions(+), 36 deletions(-)
+
+diff --git a/docs/decorators.rst b/docs/decorators.rst
+index b8200d6..94201de 100644
+--- a/docs/decorators.rst
++++ b/docs/decorators.rst
+@@ -641,15 +641,15 @@ When calling the wrapped function in the decorator wrapper function, the
+ instance is already bound to ``wrapped`` and will be passed automatically
+ as the first argument to the original wrapped function.
+
+-Note that due to a bug in Python ``classmethod.__get__()``, whereby it does
+-not apply the descriptor protocol to the function wrapped by ``@classmethod``,
+-the above only applies where the decorator wraps the ``@classmethod``
+-decorator. If the decorator is placed inside of the ``@classmethod``
+-decorator, then ``instance`` will be ``None`` and the decorator wrapper
+-function will see the call as being the same as a normal function. As a
+-result, always place any decorator outside of the ``@classmethod``
+-decorator. Hopefully this issue in Python can be addressed in a future
+-Python version.
++Note that due to a bug in Python prior to 3.9 ``classmethod.__get__()``,
++whereby it does not apply the descriptor protocol to the function
++wrapped by ``@classmethod``, the above only applies where the decorator
++wraps the ``@classmethod`` decorator. If the decorator is placed inside
++of the ``@classmethod`` decorator, then ``instance`` will be ``None``
++and the decorator wrapper function will see the call as being the same
++as a normal function. As a result, always place any decorator outside of
++the ``@classmethod`` decorator if you need to support earlier Python
++versions.
+
+ Decorating Static Methods
+ -------------------------
+diff --git a/tests/test_outer_classmethod.py b/tests/test_outer_classmethod.py
+index 6b4af4f..9c2fcb8 100644
+--- a/tests/test_outer_classmethod.py
++++ b/tests/test_outer_classmethod.py
+@@ -3,6 +3,7 @@
+ import unittest
+ import inspect
+ import imp
++import sys
+
+ import wrapt
+
+@@ -121,20 +122,26 @@ def test_instance_isinstance(self):
+ class TestCallingOuterClassMethod(unittest.TestCase):
+
+ def test_class_call_function(self):
+- # Test calling classmethod. 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.
++ # Test calling classmethod. In Python 3.9, the class will be
++ # passed as instance. In older versions of Python, 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.
+
+ _args = (1, 2)
+ _kwargs = {'one': 1, 'two': 2}
+
+ @wrapt.decorator
+ def _decorator(wrapped, instance, args, kwargs):
+- self.assertEqual(instance, None)
+- self.assertEqual(args, (Class,)+_args)
++ if sys.hexversion >= 0x03090000:
++ 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__)
+ self.assertEqual(wrapped.__name__, _function.__name__)
+@@ -155,20 +162,26 @@ def _function(cls, *args, **kwargs):
+ self.assertEqual(result, (_args, _kwargs))
+
+ def test_instance_call_function(self):
+- # Test calling classmethod via class instance. 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.
++ # Test calling classmethod via class instance. In Python 3.9,
++ # the class will be passed as instance. In older versions
++ # of Python, 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.
+
+ _args = (1, 2)
+ _kwargs = {'one': 1, 'two': 2}
+
+ @wrapt.decorator
+ def _decorator(wrapped, instance, args, kwargs):
+- self.assertEqual(instance, None)
+- self.assertEqual(args, (Class,)+_args)
++ if sys.hexversion >= 0x03090000:
++ 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__)
+ self.assertEqual(wrapped.__name__, _function.__name__)
+diff --git a/tests/test_synchronized_lock.py b/tests/test_synchronized_lock.py
+index 6e7eb12..b8f60f3 100644
+--- a/tests/test_synchronized_lock.py
++++ b/tests/test_synchronized_lock.py
+@@ -1,5 +1,6 @@
+ from __future__ import print_function
+
++import sys
+ import unittest
+
+ import wrapt
+@@ -157,34 +158,33 @@ def test_synchronized_inner_classmethod(self):
+ self.assertEqual(_lock3, _lock2)
+
+ def test_synchronized_outer_classmethod(self):
+- # XXX If all was good, this would be detected as a class
++ # Bug in Python < 3.9:
++ # If all was good, this would be detected as a class
+ # method call, but 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. This screws things up. Would be nice if
+- # Python were fixed, but that isn't likely to happen.
++ # first argument. This screws things up.
+
+- #_lock0 = getattr(C4, '_synchronized_lock', None)
+- _lock0 = getattr(C4.function2, '_synchronized_lock', None)
++ lock_target = (C4 if sys.hexversion >= 0x03090000
++ else C4.function2)
++
++ _lock0 = getattr(lock_target, '_synchronized_lock', None)
+ self.assertEqual(_lock0, None)
+
+ c4.function2()
+
+- #_lock1 = getattr(C4, '_synchronized_lock', None)
+- _lock1 = getattr(C4.function2, '_synchronized_lock', None)
++ _lock1 = getattr(lock_target, '_synchronized_lock', None)
+ self.assertNotEqual(_lock1, None)
+
+ C4.function2()
+
+- #_lock2 = getattr(C4, '_synchronized_lock', None)
+- _lock2 = getattr(C4.function2, '_synchronized_lock', None)
++ _lock2 = getattr(lock_target, '_synchronized_lock', None)
+ self.assertNotEqual(_lock2, None)
+ self.assertEqual(_lock2, _lock1)
+
+ C4.function2()
+
+- #_lock3 = getattr(C4, '_synchronized_lock', None)
+- _lock3 = getattr(C4.function2, '_synchronized_lock', None)
++ _lock3 = getattr(lock_target, '_synchronized_lock', None)
+ self.assertNotEqual(_lock3, None)
+ self.assertEqual(_lock3, _lock2)
+