Hello community, here is the log from the commit of package python-wrapt for openSUSE:Factory checked in at 2020-03-11 18:45:32 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-wrapt (Old) and /work/SRC/openSUSE:Factory/.python-wrapt.new.3160 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-wrapt" Wed Mar 11 18:45:32 2020 rev:9 rq:783021 version:1.12.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-wrapt/python-wrapt.changes 2019-07-30 13:04:38.402398839 +0200 +++ /work/SRC/openSUSE:Factory/.python-wrapt.new.3160/python-wrapt.changes 2020-03-11 18:49:26.099516293 +0100 @@ -1,0 +2,17 @@ +Mon Mar 9 16:25:43 UTC 2020 - Dirk Mueller <[email protected]> + +- update to 1.12.0: + * Provided that you only want to support Python 3.7, when deriving from + a base class which has a decorator applied to it, you no longer need + to access the true type of the base class using ``__wrapped__`` in + the inherited class list of the derived class. + * When using the ``synchronized`` decorator on instance methods of a + class, if the class declared special methods to override the result for + when the class instance was tested as a boolean so that it returned + ``False`` all the time, the synchronized method would fail when called. + * When using an adapter function to change the signature of the decorated + function, ``inspect.signature()`` was returning the wrong signature + when an instance method was inspected by accessing the method via the + class type. + +------------------------------------------------------------------- Old: ---- 1.11.2.tar.gz New: ---- 1.12.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-wrapt.spec ++++++ --- /var/tmp/diff_new_pack.YhHN7Z/_old 2020-03-11 18:49:26.843516626 +0100 +++ /var/tmp/diff_new_pack.YhHN7Z/_new 2020-03-11 18:49:26.851516629 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-wrapt # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LLC # Copyright (c) 2015 LISA GmbH, Bingen, Germany. # # All modifications and additions to the file contributed by third parties @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-wrapt -Version: 1.11.2 +Version: 1.12.0 Release: 0 Summary: A Python module for decorators, wrappers and monkey patching License: BSD-2-Clause ++++++ 1.11.2.tar.gz -> 1.12.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wrapt-1.11.2/.travis.yml new/wrapt-1.12.0/.travis.yml --- old/wrapt-1.11.2/.travis.yml 2019-06-18 03:10:12.000000000 +0200 +++ new/wrapt-1.12.0/.travis.yml 2020-02-17 00:26:17.000000000 +0100 @@ -17,7 +17,7 @@ dist: xenial sudo: true env: TOX_ARGS="-e py37-install-extensions,py37-disable-extensions,py37-without-extensions" - - python: "pypy3.5" + - python: "pypy3" env: TOX_ARGS="-e pypy-without-extensions" install: - pip install tox coveralls diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wrapt-1.11.2/docs/changes.rst new/wrapt-1.12.0/docs/changes.rst --- old/wrapt-1.11.2/docs/changes.rst 2019-06-18 03:10:12.000000000 +0200 +++ new/wrapt-1.12.0/docs/changes.rst 2020-02-17 00:26:17.000000000 +0100 @@ -1,8 +1,30 @@ Release Notes ============= +Version 1.12.0 +-------------- + +**Features Changed** + +* Provided that you only want to support Python 3.7, when deriving from + a base class which has a decorator applied to it, you no longer need + to access the true type of the base class using ``__wrapped__`` in + the inherited class list of the derived class. + +**Bugs Fixed** + +* When using the ``synchronized`` decorator on instance methods of a + class, if the class declared special methods to override the result for + when the class instance was tested as a boolean so that it returned + ``False`` all the time, the synchronized method would fail when called. + +* When using an adapter function to change the signature of the decorated + function, ``inspect.signature()`` was returning the wrong signature + when an instance method was inspected by accessing the method via the + class type. + Version 1.11.2 ---------------- +-------------- **Bugs Fixed** @@ -10,7 +32,7 @@ destructor of wrapped object. Version 1.11.1 ---------------- +-------------- **Bugs Fixed** @@ -35,7 +57,7 @@ should have been used. Version 1.11.0 ---------------- +-------------- **Bugs Fixed** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wrapt-1.11.2/docs/conf.py new/wrapt-1.12.0/docs/conf.py --- old/wrapt-1.11.2/docs/conf.py 2019-06-18 03:10:12.000000000 +0200 +++ new/wrapt-1.12.0/docs/conf.py 2020-02-17 00:26:17.000000000 +0100 @@ -48,9 +48,9 @@ # built documents. # # The short X.Y version. -version = '1.11' +version = '1.12' # The full version, including alpha/beta/rc tags. -release = '1.11.2' +release = '1.12.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wrapt-1.11.2/docs/decorators.rst new/wrapt-1.12.0/docs/decorators.rst --- old/wrapt-1.11.2/docs/decorators.rst 2019-06-18 03:10:12.000000000 +0200 +++ new/wrapt-1.12.0/docs/decorators.rst 2020-02-17 00:26:17.000000000 +0100 @@ -432,9 +432,9 @@ original wrapped function is returned. If however the decorator is a signature changing decorator, this is not going to be what is desired. -In this circumstance it is necessary to pass a dummy function to the -decorator via the optional ``adapter`` argument. When this is done, the -argument specification will be sourced from the prototype for this dummy +In this circumstance you can pass a dummy function to the decorator via +the optional ``adapter`` argument. When this is done, the argument +specification will be sourced from the prototype for this dummy function. :: @@ -476,6 +476,80 @@ system. In the latter, the arguments required of the adapter would though instead appear. +If you need to generate the argument specification based on the function +being wrapped dynamically, you can instead pass a tuple of the form +which is returned by ``inspect.getargspec()``, or a string of the form +which is returned by ``inspect.formatargspec()``. In these two cases the +decorator will automatically compile a stub function to use as the +adapter. This eliminates the need for a caller to generate the stub +function if generating the signature on the fly. + +:: + + def argspec_factory(wrapped): + argspec = inspect.getargspec(wrapped) + + args = argspec.args[1:] + defaults = argspec.defaults and argspec.defaults[-len(argspec.args):] + + return inspect.ArgSpec(args, argspec.varargs, + argspec.keywords, defaults) + + def session(wrapped): + @wrapt.decorator(adapter=argspec_factory(wrapped)) + def _session(wrapped, instance, args, kwargs): + with transaction() as session: + return wrapped(session, *args, **kwargs) + + return _session(wrapped) + +This mechanism and the original mechanism to pass a function, require +that the adapter function has to be created in advance. If the adapter +needs to be generated on demand for the specific function to be +wrapped, then it is necessary to use a closure around the definition of +the decorator as above, such that the generator can be passed in. + +As a convenience, instead of using such a closure, you can instead use: + +:: + + def argspec_factory(wrapped): + argspec = inspect.getargspec(wrapped) + + args = argspec.args[1:] + defaults = argspec.defaults and argspec.defaults[-len(argspec.args):] + + return inspect.ArgSpec(args, argspec.varargs, + argspec.keywords, defaults) + + @wrapt.decorator(adapter=wrapt.adapter_factory(argspec_factory)) + def _session(wrapped, instance, args, kwargs): + with transaction() as session: + return wrapped(session, *args, **kwargs) + +The result of ``wrapt.adapter_factory()`` will be recognised as indicating +that the creation of the adapter is to be deferred until the decorator is +being applied to a function. The factory function for generating the +adapter function or specification on demand will be passed the function +being wrapped by the decorator. + +If wishing to create a library of routines for generating adapter functions +or specifications dynamically, then you can do so by creating classes which +derive from ``wrapt.AdapterFactory`` as that is the type which is +recognised as indicating lazy evaluation of the adapter function. For +example, ``wrapt.adapter_factory()`` is itself implemented as: + +:: + + class DelegatedAdapterFactory(wrapt.AdapterFactory): + def __init__(self, factory): + super(DelegatedAdapterFactory, self).__init__() + self.factory = factory + def __call__(self, wrapped): + return self.factory(wrapped) + + adapter_factory = DelegatedAdapterFactory + Decorating Functions -------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wrapt-1.11.2/docs/issues.rst new/wrapt-1.12.0/docs/issues.rst --- old/wrapt-1.11.2/docs/issues.rst 2019-06-18 03:10:12.000000000 +0200 +++ new/wrapt-1.12.0/docs/issues.rst 2020-02-17 00:26:17.000000000 +0100 @@ -75,3 +75,7 @@ In this case of trying to decorate a base class in a class hierarchy, it may turn out to be more appropriate to use a meta class instead of trying to decorate the base class. + +Note that as of Python 3.7 and wrapt 1.12.0, accessing the true type of the +base class using ``__wrapped__`` is not required. Such code though will not +work for versions of Python older than Python 3.7. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wrapt-1.11.2/setup.py new/wrapt-1.12.0/setup.py --- old/wrapt-1.11.2/setup.py 2019-06-18 03:10:12.000000000 +0200 +++ new/wrapt-1.12.0/setup.py 2020-02-17 00:26:17.000000000 +0100 @@ -42,13 +42,14 @@ 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy', ] setup_kwargs = dict( name='wrapt', - version='1.11.2', + version='1.12.0', description='Module for decorators, wrappers and monkey patching.', long_description=open('README.rst').read(), author='Graham Dumpleton', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wrapt-1.11.2/src/wrapt/__init__.py new/wrapt-1.12.0/src/wrapt/__init__.py --- old/wrapt-1.11.2/src/wrapt/__init__.py 2019-06-18 03:10:12.000000000 +0200 +++ new/wrapt-1.12.0/src/wrapt/__init__.py 2020-02-17 00:26:17.000000000 +0100 @@ -1,4 +1,4 @@ -__version_info__ = ('1', '11', '2') +__version_info__ = ('1', '12', '0') __version__ = '.'.join(__version_info__) from .wrappers import (ObjectProxy, CallableObjectProxy, FunctionWrapper, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wrapt-1.11.2/src/wrapt/_wrappers.c new/wrapt-1.12.0/src/wrapt/_wrappers.c --- old/wrapt-1.11.2/src/wrapt/_wrappers.c 2019-06-18 03:10:12.000000000 +0200 +++ new/wrapt-1.12.0/src/wrapt/_wrappers.c 2020-02-17 00:26:17.000000000 +0100 @@ -1328,6 +1328,19 @@ /* ------------------------------------------------------------------------- */ +static PyObject *WraptObjectProxy_mro_entries( + WraptObjectProxyObject *self, PyObject *args, PyObject *kwds) +{ + if (!self->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } + + return Py_BuildValue("(O)", self->wrapped); +} + +/* ------------------------------------------------------------------------- */ + static PyObject *WraptObjectProxy_get_name( WraptObjectProxyObject *self) { @@ -1746,6 +1759,10 @@ { "__round__", (PyCFunction)WraptObjectProxy_round, METH_NOARGS, 0 }, #endif { "__complex__", (PyCFunction)WraptObjectProxy_complex, METH_NOARGS, 0 }, +#if PY_MAJOR_VERSION > 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 7) + { "__mro_entries__", (PyCFunction)WraptObjectProxy_mro_entries, + METH_VARARGS | METH_KEYWORDS, 0 }, +#endif { NULL, NULL }, }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wrapt-1.11.2/src/wrapt/decorators.py new/wrapt-1.12.0/src/wrapt/decorators.py --- old/wrapt-1.11.2/src/wrapt/decorators.py 2019-06-18 03:10:12.000000000 +0200 +++ new/wrapt-1.12.0/src/wrapt/decorators.py 2020-02-17 00:26:17.000000000 +0100 @@ -99,11 +99,6 @@ if 'signature' not in globals(): return self._self_adapter.__signature__ else: - # Can't allow this to fail on Python 3 else it falls - # through to using __wrapped__, but that will be the - # wrong function we want to derive the signature - # from. Thus generate the signature ourselves. - return signature(self._self_adapter) if PY2: @@ -117,6 +112,13 @@ return _AdapterFunctionSurrogate(self.__wrapped__.__func__, self._self_parent._self_adapter) + @property + def __signature__(self): + if 'signature' not in globals(): + return self.__wrapped__.__signature__ + else: + return signature(self._self_parent._self_adapter) + if PY2: im_func = __func__ @@ -496,7 +498,7 @@ # desired context is held. If instance is None then the # wrapped function is used as the context. - with _synchronized_lock(instance or wrapped): + with _synchronized_lock(instance if instance is not None else wrapped): return wrapped(*args, **kwargs) class _FinalDecorator(FunctionWrapper): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wrapt-1.11.2/src/wrapt/wrappers.py new/wrapt-1.12.0/src/wrapt/wrappers.py --- old/wrapt-1.11.2/src/wrapt/wrappers.py 2019-06-18 03:10:12.000000000 +0200 +++ new/wrapt-1.12.0/src/wrapt/wrappers.py 2020-02-17 00:26:17.000000000 +0100 @@ -134,6 +134,10 @@ def __round__(self): return round(self.__wrapped__) + if sys.hexversion >= 0x03070000: + def __mro_entries__(self, bases): + return (self.__wrapped__,) + def __lt__(self, other): return self.__wrapped__ < other diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wrapt-1.11.2/tests/conftest.py new/wrapt-1.12.0/tests/conftest.py --- old/wrapt-1.11.2/tests/conftest.py 2019-06-18 03:10:12.000000000 +0200 +++ new/wrapt-1.12.0/tests/conftest.py 2020-02-17 00:26:17.000000000 +0100 @@ -11,6 +11,8 @@ def pytest_pycollect_makemodule(path, parent): if '_py33' in path.basename and version < (3, 3): return DummyCollector(path, parent=parent) + if '_py37' in path.basename and version < (3, 7): + return DummyCollector(path, parent=parent) if '_py3' in path.basename and version < (3, 0): return DummyCollector(path, parent=parent) if '_py2' in path.basename and version >= (3, 0): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wrapt-1.11.2/tests/test_adapter.py new/wrapt-1.12.0/tests/test_adapter.py --- old/wrapt-1.11.2/tests/test_adapter.py 2019-06-18 03:10:12.000000000 +0200 +++ new/wrapt-1.12.0/tests/test_adapter.py 2020-02-17 00:26:17.000000000 +0100 @@ -104,7 +104,7 @@ class TestDynamicAdapter(unittest.TestCase): - def test_dynamic_adapter(self): + def test_dynamic_adapter_function(self): def _adapter(arg1, arg2, arg3=None, *args, **kwargs): pass argspec = inspect.getargspec(_adapter) @@ -131,6 +131,78 @@ self.assertEqual(inspect.getargspec(_function_2), argspec) + def test_dynamic_adapter_instancemethod(self): + def _adapter(self, arg1, arg2, arg3=None, *args, **kwargs): pass + + argspec = inspect.getargspec(_adapter) + + @wrapt.decorator(adapter=argspec) + def _wrapper_1(wrapped, instance, args, kwargs): + return wrapped(*args, **kwargs) + + class Class1(object): + @_wrapper_1 + def function(self): + pass + + instance1 = Class1() + + self.assertEqual(inspect.getargspec(Class1.function), argspec) + self.assertEqual(inspect.getargspec(instance1.function), argspec) + + args = inspect.formatargspec(*argspec) + + @wrapt.decorator(adapter=args) + def _wrapper_2(wrapped, instance, args, kwargs): + return wrapped(*args, **kwargs) + + class Class2(object): + @_wrapper_2 + def function(self): + pass + + instance2 = Class2() + + self.assertEqual(inspect.getargspec(Class2.function), argspec) + self.assertEqual(inspect.getargspec(instance2.function), argspec) + + def test_dynamic_adapter_classmethod(self): + def _adapter(cls, arg1, arg2, arg3=None, *args, **kwargs): pass + + argspec = inspect.getargspec(_adapter) + + @wrapt.decorator(adapter=argspec) + def _wrapper_1(wrapped, instance, args, kwargs): + return wrapped(*args, **kwargs) + + class Class1(object): + @_wrapper_1 + @classmethod + def function(cls): + pass + + instance1 = Class1() + + self.assertEqual(inspect.getargspec(Class1.function), argspec) + self.assertEqual(inspect.getargspec(instance1.function), argspec) + + args = inspect.formatargspec(*argspec) + + @wrapt.decorator(adapter=args) + def _wrapper_2(wrapped, instance, args, kwargs): + return wrapped(*args, **kwargs) + + class Class2(object): + @_wrapper_2 + @classmethod + def function(self): + pass + + instance2 = Class2() + + self.assertEqual(inspect.getargspec(Class2.function), argspec) + self.assertEqual(inspect.getargspec(instance2.function), argspec) + def test_adapter_factory(self): def factory(wrapped): argspec = inspect.getargspec(wrapped) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wrapt-1.11.2/tests/test_class.py new/wrapt-1.12.0/tests/test_class.py --- old/wrapt-1.11.2/tests/test_class.py 2019-06-18 03:10:12.000000000 +0200 +++ new/wrapt-1.12.0/tests/test_class.py 2020-02-17 00:26:17.000000000 +0100 @@ -26,8 +26,42 @@ class1d = decorators.passthru_decorator(class1) -class Testintrospection(unittest.TestCase): +class TestIntrospection(unittest.TestCase): def test_getmembers(self): class1o_members = inspect.getmembers(class1o) class1d_members = inspect.getmembers(class1d) + +class TestInheritance(unittest.TestCase): + + def test_single_inheritance(self): + @wrapt.decorator + def passthru(wrapped, instance, args, kwargs): + return wrapped(*args, **kwargs) + + @passthru + class BaseClass(object): + def __init__(self): + self.value = 1 + + class DerivedClass(BaseClass.__wrapped__): + def __init__(self): + super(DerivedClass, self).__init__() + self.value = 2 + + base = BaseClass() + + self.assertEqual(type(base), BaseClass.__wrapped__) + self.assertTrue(isinstance(base, BaseClass.__wrapped__)) + self.assertEqual(base.value, 1) + + self.assertEqual(type(base).__mro__, (BaseClass.__wrapped__, object)) + + derived = DerivedClass() + + self.assertEqual(type(derived), DerivedClass) + self.assertTrue(isinstance(derived, BaseClass.__wrapped__)) + self.assertTrue(isinstance(derived, DerivedClass)) + self.assertEqual(derived.value, 2) + + self.assertEqual(type(derived).__mro__, (DerivedClass, BaseClass.__wrapped__, object)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wrapt-1.11.2/tests/test_class_py37.py new/wrapt-1.12.0/tests/test_class_py37.py --- old/wrapt-1.11.2/tests/test_class_py37.py 1970-01-01 01:00:00.000000000 +0100 +++ new/wrapt-1.12.0/tests/test_class_py37.py 2020-02-17 00:26:17.000000000 +0100 @@ -0,0 +1,102 @@ +from __future__ import print_function + +import unittest +import inspect +import imp + +import wrapt + +from compat import PY2, PY3, exec_ + +class TestInheritance(unittest.TestCase): + + def test_single_inheritance(self): + @wrapt.decorator + def passthru(wrapped, instance, args, kwargs): + return wrapped(*args, **kwargs) + + @passthru + class BaseClass(object): + def __init__(self): + self.value = 1 + + class DerivedClass(BaseClass): + def __init__(self): + super(DerivedClass, self).__init__() + self.value = 2 + + base = BaseClass() + + self.assertEqual(type(base), BaseClass.__wrapped__) + self.assertTrue(isinstance(base, BaseClass.__wrapped__)) + self.assertEqual(base.value, 1) + + self.assertEqual(type(base).__mro__, (BaseClass.__wrapped__, object)) + self.assertEqual(BaseClass.__mro_entries__(()), (BaseClass.__wrapped__,)) + + derived = DerivedClass() + + self.assertEqual(type(derived), DerivedClass) + self.assertTrue(isinstance(derived, BaseClass.__wrapped__)) + self.assertTrue(isinstance(derived, DerivedClass)) + self.assertEqual(derived.value, 2) + + self.assertEqual(type(derived).__mro__, (DerivedClass, BaseClass.__wrapped__, object)) + + def test_multiple_inheritance(self): + @wrapt.decorator + def passthru(wrapped, instance, args, kwargs): + return wrapped(*args, **kwargs) + + @passthru + class BaseClass1(object): + pass + + @passthru + class BaseClass2(object): + pass + + class DerivedClass(BaseClass1, BaseClass2): + pass + + derived = DerivedClass() + + self.assertEqual(type(derived), DerivedClass) + self.assertTrue(isinstance(derived, BaseClass1.__wrapped__)) + self.assertTrue(isinstance(derived, BaseClass2.__wrapped__)) + self.assertTrue(isinstance(derived, DerivedClass)) + + self.assertEqual(type(derived).__mro__, (DerivedClass, + BaseClass1.__wrapped__, BaseClass2.__wrapped__, object)) + + def test_multiple_inheritance_common(self): + @wrapt.decorator + def passthru(wrapped, instance, args, kwargs): + return wrapped(*args, **kwargs) + + @passthru + class CommonClass(object): + pass + + @passthru + class BaseClass1(CommonClass): + pass + + @passthru + class BaseClass2(CommonClass): + pass + + class DerivedClass(BaseClass1, BaseClass2): + pass + + derived = DerivedClass() + + self.assertEqual(type(derived), DerivedClass) + self.assertTrue(isinstance(derived, CommonClass.__wrapped__)) + self.assertTrue(isinstance(derived, BaseClass1.__wrapped__)) + self.assertTrue(isinstance(derived, BaseClass2.__wrapped__)) + self.assertTrue(isinstance(derived, DerivedClass)) + + self.assertEqual(type(derived).__mro__, (DerivedClass, + BaseClass1.__wrapped__, BaseClass2.__wrapped__, + CommonClass.__wrapped__, object)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wrapt-1.11.2/tests/test_synchronized_lock.py new/wrapt-1.12.0/tests/test_synchronized_lock.py --- old/wrapt-1.11.2/tests/test_synchronized_lock.py 2019-06-18 03:10:12.000000000 +0200 +++ new/wrapt-1.12.0/tests/test_synchronized_lock.py 2020-02-17 00:26:17.000000000 +0100 @@ -55,6 +55,18 @@ c4 = C4() +class C5(object): + + def __bool__(self): + return False + __nonzero__=__bool__ + + @wrapt.synchronized + def function1(self): + print('function1') + +c5 = C5() + class TestSynchronized(unittest.TestCase): def test_synchronized_function(self): @@ -261,5 +273,16 @@ self.assertNotEqual(_lock3, None) self.assertEqual(_lock3, _lock2) + def test_synchronized_false_instance(self): + c5.function1() + + self.assertEqual(bool(c5), False) + + _lock1 = getattr(C5, '_synchronized_lock', None) + self.assertEqual(_lock1, None) + + _lock2 = getattr(c5, '_synchronized_lock', None) + self.assertNotEqual(_lock2, None) + if __name__ == '__main__': unittest.main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wrapt-1.11.2/tox.ini new/wrapt-1.12.0/tox.ini --- old/wrapt-1.11.2/tox.ini 2019-06-18 03:10:12.000000000 +0200 +++ new/wrapt-1.12.0/tox.ini 2020-02-17 00:26:17.000000000 +0100 @@ -1,6 +1,6 @@ [tox] envlist = - py{27,34,35,36,37}-{without,install,disable}-extensions, + py{27,34,35,36,37,38}-{without,install,disable}-extensions, pypy-without-extensions [testenv]
