Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-logilab-common for openSUSE:Factory checked in at 2022-09-30 17:57:51 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-logilab-common (Old) and /work/SRC/openSUSE:Factory/.python-logilab-common.new.2275 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-logilab-common" Fri Sep 30 17:57:51 2022 rev:10 rq:1007070 version:1.9.7 Changes: -------- --- /work/SRC/openSUSE:Factory/python-logilab-common/python-logilab-common.changes 2022-02-15 00:10:56.471365590 +0100 +++ /work/SRC/openSUSE:Factory/.python-logilab-common.new.2275/python-logilab-common.changes 2022-09-30 17:58:09.081294388 +0200 @@ -1,0 +2,6 @@ +Thu Sep 29 14:53:49 UTC 2022 - Yogalakshmi Arunachalam <yarunacha...@suse.com> + +- Update to 1.9.7 + No log + +------------------------------------------------------------------- Old: ---- logilab-common-1.8.3.tar.gz New: ---- logilab-common-1.9.7.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-logilab-common.spec ++++++ --- /var/tmp/diff_new_pack.HSL4HI/_old 2022-09-30 17:58:10.137296645 +0200 +++ /var/tmp/diff_new_pack.HSL4HI/_new 2022-09-30 17:58:10.145296663 +0200 @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-logilab-common -Version: 1.8.3 +Version: 1.9.7 Release: 0 Summary: Python lowlevel functionality shared by logilab projects License: LGPL-2.1-or-later ++++++ logilab-common-1.8.3.tar.gz -> logilab-common-1.9.7.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logilab-common-1.8.3/PKG-INFO new/logilab-common-1.9.7/PKG-INFO --- old/logilab-common-1.8.3/PKG-INFO 2022-01-04 16:19:42.000000000 +0100 +++ new/logilab-common-1.9.7/PKG-INFO 2022-06-07 16:22:58.951329500 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: logilab-common -Version: 1.8.3 +Version: 1.9.7 Summary: collection of low-level Python packages and modules used by Logilab projects Home-page: http://www.logilab.org/project/logilab-common Author: Logilab diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logilab-common-1.8.3/__pkginfo__.py new/logilab-common-1.9.7/__pkginfo__.py --- old/logilab-common-1.8.3/__pkginfo__.py 2022-01-04 16:17:46.000000000 +0100 +++ new/logilab-common-1.9.7/__pkginfo__.py 2022-06-07 16:22:37.000000000 +0200 @@ -21,6 +21,7 @@ __docformat__ = "restructuredtext en" import os +import sys from os.path import join distname = "logilab-common" @@ -28,7 +29,7 @@ subpackage_of = "logilab" subpackage_master = True -numversion = (1, 8, 3) +numversion = (1, 9, 7) version = ".".join([str(num) for num in numversion]) license = "LGPL" # 2.1 or later @@ -42,18 +43,21 @@ scripts = [join("bin", "logilab-pytest")] include_dirs = [join("test", "data")] -install_requires = [ - "setuptools", - "mypy-extensions", - "typing_extensions", -] +__depends__ = { + "setuptools": None, + "mypy-extensions": None, + "typing_extensions": None, +} tests_require = [ "pytz", "egenix-mx-base", ] if os.name == "nt": - install_requires.append("colorama") + __depends__["colorama"] = None + +if sys.version_info < (3, 8): + __depends__["importlib_metadata"] = None classifiers = [ "Topic :: Utilities", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logilab-common-1.8.3/logilab/common/decorators.py new/logilab-common-1.9.7/logilab/common/decorators.py --- old/logilab-common-1.8.3/logilab/common/decorators.py 2022-01-04 15:03:47.000000000 +0100 +++ new/logilab-common-1.9.7/logilab/common/decorators.py 2022-06-07 16:22:38.000000000 +0200 @@ -25,7 +25,7 @@ from time import process_time, time from inspect import isgeneratorfunction -from typing import Any, Optional, Callable, Union +from typing import Any, Optional, Callable, overload, TypeVar from inspect import getfullargspec @@ -121,9 +121,22 @@ return _cache[key] +_T = TypeVar("_T", bound=Callable) + + +@overload def cached( - callableobj: Optional[Callable] = None, keyarg: Optional[int] = None, **kwargs: Any -) -> Union[Callable, cached_decorator]: + callableobj: None = None, keyarg: Optional[int] = None, **kwargs: Any +) -> Callable[[_T], _T]: + ... + + +@overload +def cached(callableobj: _T = None, keyarg: Optional[int] = None, **kwargs: Any) -> _T: + ... + + +def cached(callableobj=None, keyarg=None, **kwargs): """Simple decorator to cache result of method call.""" kwargs["keyarg"] = keyarg decorator = cached_decorator(**kwargs) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logilab-common-1.8.3/logilab/common/deprecation.py new/logilab-common-1.9.7/logilab/common/deprecation.py --- old/logilab-common-1.8.3/logilab/common/deprecation.py 2020-12-17 15:03:52.000000000 +0100 +++ new/logilab-common-1.9.7/logilab/common/deprecation.py 2022-06-07 16:22:38.000000000 +0200 @@ -21,14 +21,20 @@ import os import sys +import inspect from enum import Enum from warnings import warn from functools import WRAPPER_ASSIGNMENTS, WRAPPER_UPDATES from typing import Any, Callable, Dict, Optional, Type from typing_extensions import Protocol +if sys.version_info >= (3, 8): + from importlib import metadata as importlib_metadata +else: + import importlib_metadata -def get_real__name__(some_callable: Callable) -> str: + +def _unstack_all_deprecation_decorators(function): """ This is another super edge magic case which is needed because we uses lazy_wraps because of logilab.common.modutils.LazyObject and because @@ -38,12 +44,18 @@ Therefor, to get the real callable name when several lazy_wrapped decorator are used we need to travers the __wrapped__ attributes chain. """ + while hasattr(function, "__wrapped__"): + function = function.__wrapped__ + + return function - targeted_callable = some_callable - while hasattr(targeted_callable, "__wrapped__"): - targeted_callable = targeted_callable.__wrapped__ # type: ignore - return targeted_callable.__name__ +def get_real__name__(some_callable: Callable) -> str: + return _unstack_all_deprecation_decorators(some_callable).__name__ + + +def get_real__module__(some_callable: Callable) -> str: + return _unstack_all_deprecation_decorators(some_callable).__module__ def lazy_wraps(wrapped: Callable) -> Callable: @@ -145,6 +157,42 @@ return file_name +_cached_path_to_package: Optional[Dict[str, Optional[str]]] = None + + +def _get_package_name(python_object) -> Optional[str]: + # only do this work if we are in a pytest session + if "COLLECT_DEPRECATION_WARNINGS_PACKAGE_NAME" not in os.environ: + return None + + global _cached_path_to_package + + if _cached_path_to_package is None: + _cached_path_to_package = {} + # mypy fails to understand the result of .discover(): Cannot + # instantiate abstract class 'Distribution' with abstract attributes + # 'locate_file' and 'read_text' + for distribution in importlib_metadata.Distribution().discover(): # type: ignore + # sometime distribution has a "name" attribute, sometime not + if distribution.files and hasattr(distribution, "name"): + for file in distribution.files: + _cached_path_to_package[str(distribution.locate_file(file))] = distribution.name + continue + + if distribution.files and "name" in distribution.metadata: + for file in distribution.files: + _cached_path_to_package[ + str(distribution.locate_file(file)) + ] = distribution.metadata["name"] + + try: + return _cached_path_to_package.get( + inspect.getfile(_unstack_all_deprecation_decorators(python_object)) + ) + except TypeError: + return None + + def send_warning( reason: str, deprecation_class: Type[DeprecationWarning], @@ -189,16 +237,26 @@ Mostly used with isinstance """ - def __init__(self, reason: str): + def __init__(self, reason: str, package: str = None, version: str = None): self.reason: str = reason + self.package = package + self.version = version def __str__(self) -> str: return self.reason class TargetRenamedDeprecationWarning(StructuredDeprecationWarning): - def __init__(self, reason: str, kind: DeprecationWarningKind, old_name: str, new_name: str): - super().__init__(reason) + def __init__( + self, + reason: str, + kind: DeprecationWarningKind, + old_name: str, + new_name: str, + package: str = None, + version: str = None, + ): + super().__init__(reason, package=package, version=version) self.operation = DeprecationWarningOperation.RENAMED self.kind: DeprecationWarningKind = kind # callable, class, module, argument, attribute self.old_name: str = old_name @@ -206,15 +264,24 @@ class TargetDeprecatedDeprecationWarning(StructuredDeprecationWarning): - def __init__(self, reason: str, kind: DeprecationWarningKind): - super().__init__(reason) + def __init__( + self, reason: str, kind: DeprecationWarningKind, package: str = None, version: str = None + ): + super().__init__(reason, package=package, version=version) self.operation = DeprecationWarningOperation.DEPRECATED self.kind: DeprecationWarningKind = kind # callable, class, module, argument, attribute class TargetRemovedDeprecationWarning(StructuredDeprecationWarning): - def __init__(self, reason: str, kind: DeprecationWarningKind, name: str): - super().__init__(reason) + def __init__( + self, + reason: str, + kind: DeprecationWarningKind, + name: str, + package: str = None, + version: str = None, + ): + super().__init__(reason, package=package, version=version) self.operation = DeprecationWarningOperation.REMOVED self.kind: DeprecationWarningKind = kind # callable, class, module, argument, attribute self.name: str = name @@ -229,8 +296,10 @@ new_name: str, old_module: str, new_module: str, + package: str = None, + version: str = None, ): - super().__init__(reason) + super().__init__(reason, package=package, version=version) self.operation = DeprecationWarningOperation.MOVED self.kind: DeprecationWarningKind = kind # callable, class, module, argument, attribute self.old_name: str = old_name @@ -266,10 +335,12 @@ "kind": DeprecationWarningKind.CALLABLE, "old_name": old_name, "new_name": get_real__name__(new_function), + "version": version, + "package": _get_package_name(new_function), }, stacklevel=3, version=version, - module_name=new_function.__module__, + module_name=get_real__module__(new_function), ) return new_function(*args, **kwargs) @@ -305,10 +376,12 @@ deprecation_class_kwargs={ "kind": DeprecationWarningKind.ARGUMENT, "name": old_argument_name, + "version": version, + "package": _get_package_name(func), }, stacklevel=3, version=version, - module_name=func.__module__, + module_name=get_real__module__(func), ) del kwargs[old_argument_name] @@ -337,11 +410,15 @@ send_warning( message, - TargetDeprecatedDeprecationWarning, - {"kind": DeprecationWarningKind.CALLABLE}, - version, - stacklevel + 1, - module_name=func.__module__, + deprecation_class=TargetDeprecatedDeprecationWarning, + deprecation_class_kwargs={ + "kind": DeprecationWarningKind.CALLABLE, + "version": version, + "package": _get_package_name(func), + }, + version=version, + stacklevel=stacklevel + 1, + module_name=get_real__module__(func), ) return func(*args, **kwargs) @@ -368,7 +445,7 @@ def __call__(cls, *args, **kwargs): message = getattr(cls, "__deprecation_warning__", "%(cls)s is deprecated") % { - "cls": cls.__name__ + "cls": get_real__name__(cls) } send_warning( message, @@ -378,7 +455,11 @@ deprecation_class_kwargs=getattr( cls, "__deprecation_warning_class_kwargs__", - {"kind": DeprecationWarningKind.CLASS}, + { + "kind": DeprecationWarningKind.CLASS, + "package": _get_package_name(cls), + "version": getattr(cls, "__deprecation_warning_version__", None), + }, ), module_name=getattr( cls, "__deprecation_warning_module_name__", _get_module_name(1) @@ -419,8 +500,8 @@ def _class_wrap(klass: type) -> type: reason = ( - f"{klass.__name__}.{old_name} has been renamed and is deprecated, use " - f"{klass.__name__}.{new_name} instead" + f"{get_real__name__(klass)}.{old_name} has been renamed and is deprecated, use " + f"{get_real__name__(klass)}.{new_name} instead" ) def _get_old(self) -> Any: @@ -431,10 +512,12 @@ "kind": DeprecationWarningKind.ATTRIBUTE, "old_name": old_name, "new_name": new_name, + "version": version, + "package": _get_package_name(klass), }, stacklevel=3, version=version, - module_name=klass.__module__, + module_name=get_real__module__(klass), ) return getattr(self, new_name) @@ -446,10 +529,12 @@ "kind": DeprecationWarningKind.ATTRIBUTE, "old_name": old_name, "new_name": new_name, + "version": version, + "package": _get_package_name(klass), }, stacklevel=3, version=version, - module_name=klass.__module__, + module_name=get_real__module__(klass), ) setattr(self, new_name, value) @@ -461,10 +546,12 @@ "kind": DeprecationWarningKind.ATTRIBUTE, "old_name": old_name, "new_name": new_name, + "version": version, + "package": _get_package_name(klass), }, stacklevel=3, version=version, - module_name=klass.__module__, + module_name=get_real__module__(klass), ) delattr(self, new_name) @@ -508,10 +595,12 @@ "kind": DeprecationWarningKind.ARGUMENT, "old_name": old_name, "new_name": new_name, + "version": version, + "package": _get_package_name(func), }, stacklevel=3, version=version, - module_name=func.__module__, + module_name=get_real__module__(func), ) kwargs[new_name] = kwargs[old_name] del kwargs[old_name] @@ -556,6 +645,8 @@ def callnew(*args, **kwargs): from logilab.common.modutils import load_module_from_name + m = load_module_from_name(module_name) + send_warning( message, deprecation_class=TargetMovedDeprecationWarning, @@ -565,13 +656,14 @@ "new_name": new_name, "old_module": old_module, "new_module": module_name, + "version": version, + "package": _get_package_name(getattr(m, object_name)), }, version=version, stacklevel=stacklevel + 1, module_name=old_module, ) - m = load_module_from_name(module_name) return getattr(m, object_name)(*args, **kwargs) return callnew @@ -602,7 +694,7 @@ """ class_dict: Dict[str, Any] = {} if message is None: - message = "%s is deprecated, use %s instead" % (old_name, new_class.__name__) + message = "%s is deprecated, use %s instead" % (old_name, get_real__name__(new_class)) class_dict["__deprecation_warning__"] = message class_dict["__deprecation_warning_class__"] = deprecated_warning_class @@ -610,7 +702,9 @@ class_dict["__deprecation_warning_class_kwargs__"] = { "kind": DeprecationWarningKind.CLASS, "old_name": old_name, - "new_name": new_class.__name__, + "new_name": get_real__name__(new_class), + "version": version, + "package": _get_package_name(new_class), } else: class_dict["__deprecation_warning_class_kwargs__"] = deprecated_warning_kwargs @@ -631,7 +725,7 @@ def __init__(self, *args, **kwargs): msg = class_dict.get( "__deprecation_warning__", - f"{old_name} is deprecated, use {new_class.__name__} instead", + f"{old_name} is deprecated, use {get_real__name__(new_class)} instead", ) send_warning( msg, @@ -639,7 +733,9 @@ deprecation_class_kwargs={ "kind": DeprecationWarningKind.CLASS, "old_name": old_name, - "new_name": new_class.__name__, + "new_name": get_real__name__(new_class), + "version": version, + "package": _get_package_name(new_class), }, stacklevel=class_dict.get("__deprecation_warning_stacklevel__", 3), version=class_dict.get("__deprecation_warning_version__", None), @@ -659,7 +755,7 @@ another module """ if old_name is None: - old_name = new_class.__name__ + old_name = get_real__name__(new_class) old_module = _get_module_name(1) @@ -667,8 +763,8 @@ message = "class %s.%s is now available as %s.%s" % ( old_module, old_name, - new_class.__module__, - new_class.__name__, + get_real__module__(new_class), + get_real__name__(new_class), ) module_name = _get_module_name(1) @@ -677,13 +773,16 @@ old_name, new_class, message=message, + version=version, module_name=module_name, deprecated_warning_class=TargetMovedDeprecationWarning, deprecated_warning_kwargs={ "kind": DeprecationWarningKind.CLASS, "old_module": old_module, - "new_module": new_class.__module__, + "new_module": get_real__module__(new_class), "old_name": old_name, - "new_name": new_class.__name__, + "new_name": get_real__name__(new_class), + "version": version, + "package": _get_package_name(new_class), }, ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logilab-common-1.8.3/logilab/common/textutils.py new/logilab-common-1.9.7/logilab/common/textutils.py --- old/logilab-common-1.8.3/logilab/common/textutils.py 2020-12-17 15:03:52.000000000 +0100 +++ new/logilab-common-1.9.7/logilab/common/textutils.py 2022-06-07 16:22:38.000000000 +0200 @@ -120,7 +120,7 @@ replacement = MANUAL_UNICODE_MAP[letter] except KeyError: replacement = _uninormalize("NFKD", letter)[0] - if ord(replacement) >= 2 ** 7: + if ord(replacement) >= 2**7: if substitute is None: raise ValueError("can't deal with non-ascii based characters") replacement = substitute @@ -347,9 +347,9 @@ BYTE_UNITS = { "b": 1, "kb": 1024, - "mb": 1024 ** 2, - "gb": 1024 ** 3, - "tb": 1024 ** 4, + "mb": 1024**2, + "gb": 1024**3, + "tb": 1024**4, } TIME_UNITS = { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logilab-common-1.8.3/logilab_common.egg-info/PKG-INFO new/logilab-common-1.9.7/logilab_common.egg-info/PKG-INFO --- old/logilab-common-1.8.3/logilab_common.egg-info/PKG-INFO 2022-01-04 16:19:41.000000000 +0100 +++ new/logilab-common-1.9.7/logilab_common.egg-info/PKG-INFO 2022-06-07 16:22:57.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: logilab-common -Version: 1.8.3 +Version: 1.9.7 Summary: collection of low-level Python packages and modules used by Logilab projects Home-page: http://www.logilab.org/project/logilab-common Author: Logilab diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logilab-common-1.8.3/setup.py new/logilab-common-1.9.7/setup.py --- old/logilab-common-1.8.3/setup.py 2022-01-04 15:03:47.000000000 +0100 +++ new/logilab-common-1.9.7/setup.py 2022-06-07 16:22:38.000000000 +0200 @@ -34,6 +34,11 @@ with open(path.join(here, "README.rst"), encoding="utf-8") as f: long_description = f.read() +requires = {} +for entry in ("__depends__",): # "__recommends__"): + requires.update(pkginfo.get(entry, {})) +install_requires = ["{0} {1}".format(d, v and v or "").strip() for d, v in requires.items()] + setup( name=pkginfo["distname"], version=pkginfo["version"], @@ -50,7 +55,7 @@ include_package_data=True, namespace_packages=[pkginfo["subpackage_of"]], python_requires=">=3.6", - install_requires=pkginfo["install_requires"], + install_requires=install_requires, tests_require=pkginfo["tests_require"], scripts=pkginfo["scripts"], ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logilab-common-1.8.3/test/data/module2.py new/logilab-common-1.9.7/test/data/module2.py --- old/logilab-common-1.8.3/test/data/module2.py 2022-01-04 15:03:47.000000000 +0100 +++ new/logilab-common-1.9.7/test/data/module2.py 2022-06-07 16:22:38.000000000 +0200 @@ -78,7 +78,7 @@ c = b // 2 c = b - 2 c = b % 2 -c = b ** 2 +c = b**2 c = b << 2 c = b >> 2 c = ~b diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logilab-common-1.8.3/test/test_date.py new/logilab-common-1.9.7/test/test_date.py --- old/logilab-common-1.8.3/test/test_date.py 2020-12-17 15:03:52.000000000 +0100 +++ new/logilab-common-1.9.7/test/test_date.py 2022-06-07 16:22:38.000000000 +0200 @@ -78,12 +78,13 @@ def test_get_national_holidays(self): holidays = get_national_holidays - yield self.assertEqual, holidays(self.datecls(2008, 4, 29), self.datecls(2008, 5, 2)), [ - self.datecls(2008, 5, 1) - ] - yield self.assertEqual, holidays(self.datecls(2008, 5, 7), self.datecls(2008, 5, 8)), [] + self.assertEqual( + holidays(self.datecls(2008, 4, 29), self.datecls(2008, 5, 2)), + [self.datecls(2008, 5, 1)], + ) + self.assertEqual(holidays(self.datecls(2008, 5, 7), self.datecls(2008, 5, 8)), []) x = self.datetimecls(2008, 5, 7, 12, 12, 12) - yield self.assertEqual, holidays(x, x + self.timedeltacls(days=1)), [] + self.assertEqual(holidays(x, x + self.timedeltacls(days=1)), []) def test_open_days_now_and_before(self): nb = nb_open_days diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logilab-common-1.8.3/test/test_deprecation.py new/logilab-common-1.9.7/test/test_deprecation.py --- old/logilab-common-1.8.3/test/test_deprecation.py 2020-12-17 15:03:52.000000000 +0100 +++ new/logilab-common-1.9.7/test/test_deprecation.py 2022-06-07 16:22:38.000000000 +0200 @@ -57,17 +57,35 @@ pass AnyClass() - self.assertEqual(self.messages, ["[test_deprecation] AnyClass is deprecated"]) + + class AnyClass(object, metaclass=deprecation.class_deprecated): + __deprecation_warning_version__ = "1.2.3" + + AnyClass() + + self.assertEqual( + self.messages, + [ + "[test_deprecation] AnyClass is deprecated", + "[test_deprecation 1.2.3] AnyClass is deprecated", + ], + ) def test_class_renamed(self): class AnyClass(object): pass OldClass = deprecation.class_renamed("OldClass", AnyClass) - OldClass() + OldClass = deprecation.class_renamed("OldClass", AnyClass, version="1.2.3") + OldClass() + self.assertEqual( - self.messages, ["[test_deprecation] OldClass is deprecated, use AnyClass instead"] + self.messages, + [ + "[test_deprecation] OldClass is deprecated, use AnyClass instead", + "[test_deprecation 1.2.3] OldClass is deprecated, use AnyClass instead", + ], ) def test_class_renamed_conflict_metaclass(self): @@ -77,9 +95,10 @@ class AnyClass(metaclass=SomeMetaClass): pass - # make sure the "metaclass conflict: the metaclass of a derived class # must be a + # make sure the "metaclass conflict: the metaclass of a derived class must be a # (non-strict) subclass of the metaclasses of all its bases" exception won't be raised deprecation.class_renamed("OldClass", AnyClass) + deprecation.class_renamed("OldClass", AnyClass, version="1.2.3") def test_class_moved(self): class AnyClass(object): @@ -87,24 +106,33 @@ OldClass = deprecation.class_moved(new_class=AnyClass, old_name="OldName") OldClass() + OldClass = deprecation.class_moved(new_class=AnyClass, old_name="OldName", version="1.2.3") + OldClass() self.assertEqual( self.messages, [ "[test_deprecation] class test_deprecation.OldName is now available as " - "test_deprecation.AnyClass" + "test_deprecation.AnyClass", + "[test_deprecation 1.2.3] class test_deprecation.OldName is now available as " + "test_deprecation.AnyClass", ], ) self.messages = [] - AnyClass = deprecation.class_moved(new_class=AnyClass) + AnyClass2 = deprecation.class_moved(new_class=AnyClass) + AnyClass2() + + AnyClass3 = deprecation.class_moved(new_class=AnyClass, version="1.2.3") + AnyClass3() - AnyClass() self.assertEqual( self.messages, [ "[test_deprecation] class test_deprecation.AnyClass is now available as " - "test_deprecation.AnyClass" + "test_deprecation.AnyClass", + "[test_deprecation 1.2.3] class test_deprecation.AnyClass is now available as " + "test_deprecation.AnyClass", ], ) @@ -113,11 +141,17 @@ any_func() any_func = deprecation.callable_deprecated("message")(self.mk_func()) any_func() + any_func = deprecation.callable_deprecated(version="1.2.3")(self.mk_func()) + any_func() + any_func = deprecation.callable_deprecated("message", version="1.2.3")(self.mk_func()) + any_func() self.assertEqual( self.messages, [ '[test_deprecation] The function "any_func" is deprecated', "[test_deprecation] message", + '[test_deprecation 1.2.3] The function "any_func" is deprecated', + "[test_deprecation 1.2.3] message", ], ) @@ -133,11 +167,25 @@ pass any_func() + + @deprecation.callable_deprecated(version="1.2.3") + def any_func(): + pass + + any_func() + + @deprecation.callable_deprecated("message", version="1.2.3") + def any_func(): + pass + + any_func() self.assertEqual( self.messages, [ '[test_deprecation] The function "any_func" is deprecated', "[test_deprecation] message", + '[test_deprecation 1.2.3] The function "any_func" is deprecated', + "[test_deprecation 1.2.3] message", ], ) @@ -206,6 +254,32 @@ self.assertFalse(hasattr(some_class, "new")) self.assertFalse(hasattr(some_class, "old")) + def test_attribute_renamed_version(self): + @deprecation.attribute_renamed(old_name="old", new_name="new", version="1.2.3") + class SomeClass: + def __init__(self): + self.new = 42 + + some_class = SomeClass() + self.assertEqual(some_class.old, some_class.new) + self.assertEqual( + self.messages, + [ + "[test_deprecation 1.2.3] SomeClass.old has been renamed and is deprecated, " + "use SomeClass.new instead" + ], + ) + + some_class.old = 43 + self.assertEqual(some_class.old, 43) + self.assertEqual(some_class.old, some_class.new) + + self.assertTrue(hasattr(some_class, "new")) + self.assertTrue(hasattr(some_class, "old")) + del some_class.old + self.assertFalse(hasattr(some_class, "new")) + self.assertFalse(hasattr(some_class, "old")) + def test_argument_renamed(self): @deprecation.argument_renamed(old_name="old", new_name="new") def some_function(new): @@ -224,6 +298,24 @@ with self.assertRaises(ValueError): some_function(new=42, old=42) + def test_argument_renamed_version(self): + @deprecation.argument_renamed(old_name="old", new_name="new", version="1.2.3") + def some_function(new): + return new + + self.assertEqual(some_function(new=42), 42) + self.assertEqual(some_function(old=42), 42) + self.assertEqual( + self.messages, + [ + "[test_deprecation 1.2.3] argument old of callable some_function has been renamed " + "and is deprecated, use keyword argument new instead" + ], + ) + + with self.assertRaises(ValueError): + some_function(new=42, old=42) + def test_argument_removed(self): @deprecation.argument_removed("old") def some_function(new): @@ -239,6 +331,21 @@ ], ) + def test_argument_removed_version(self): + @deprecation.argument_removed("old", version="1.2.3") + def some_function(new): + return new + + self.assertEqual(some_function(new=42), 42) + self.assertEqual(some_function(new=10, old=20), 10) + self.assertEqual( + self.messages, + [ + "[test_deprecation 1.2.3] argument old of callable some_function has been removed " + "and is deprecated" + ], + ) + def test_callable_renamed(self): def any_func(): pass @@ -254,6 +361,21 @@ ], ) + def test_callable_renamed_version(self): + def any_func(): + pass + + old_func = deprecation.callable_renamed("old_func", any_func, version="1.2.3") + old_func() + + self.assertEqual( + self.messages, + [ + "[test_deprecation 1.2.3] old_func has been renamed and is deprecated, " + "uses any_func instead" + ], + ) + def test_callable_moved(self): module = "data.deprecation" moving_target = deprecation.callable_moved(module, "moving_target") @@ -266,6 +388,18 @@ ], ) + def test_callable_moved_version(self): + module = "data.deprecation" + moving_target = deprecation.callable_moved(module, "moving_target", version="1.2.3") + moving_target() + self.assertEqual( + self.messages, + [ + "[test_deprecation 1.2.3] object test_deprecation.moving_target has been moved to " + "data.deprecation.moving_target" + ], + ) + class StructuredDeprecatedWarningsTest(TestCase): def mock_warn(self, *args, **kwargs): @@ -294,6 +428,21 @@ self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.DEPRECATED) self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CLASS) + self.assertEqual(warning.version, None) + self.assertEqual(warning.package, "logilab-common") + + def test_class_deprecated_version(self): + class AnyClass(metaclass=deprecation.class_deprecated): + __deprecation_warning_version__ = "1.2.3" + + AnyClass() + self.assertEqual(len(self.collected_warnings), 1) + warning = self.collected_warnings.pop() + + self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.DEPRECATED) + self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CLASS) + self.assertEqual(warning.version, "1.2.3") + self.assertEqual(warning.package, "logilab-common") def test_class_renamed(self): class AnyClass: @@ -309,6 +458,25 @@ self.assertEqual(warning.old_name, "OldClass") self.assertEqual(warning.new_name, "AnyClass") self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CLASS) + self.assertEqual(warning.version, None) + self.assertEqual(warning.package, "logilab-common") + + def test_class_renamed_version(self): + class AnyClass: + pass + + OldClass = deprecation.class_renamed("OldClass", AnyClass, version="1.2.3") + + OldClass() + self.assertEqual(len(self.collected_warnings), 1) + warning = self.collected_warnings.pop() + + self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.RENAMED) + self.assertEqual(warning.old_name, "OldClass") + self.assertEqual(warning.new_name, "AnyClass") + self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CLASS) + self.assertEqual(warning.version, "1.2.3") + self.assertEqual(warning.package, "logilab-common") def test_class_moved(self): class AnyClass: @@ -326,6 +494,8 @@ self.assertEqual(warning.old_name, "OldName") self.assertEqual(warning.new_name, "AnyClass") self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CLASS) + self.assertEqual(warning.version, None) + self.assertEqual(warning.package, "logilab-common") self.collected_warnings = [] @@ -342,6 +512,45 @@ self.assertEqual(warning.old_name, "AnyClass") self.assertEqual(warning.new_name, "AnyClass") self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CLASS) + self.assertEqual(warning.version, None) + self.assertEqual(warning.package, "logilab-common") + + def test_class_moved_version(self): + class AnyClass: + pass + + OldClass = deprecation.class_moved(new_class=AnyClass, old_name="OldName", version="1.2.3") + OldClass() + + self.assertEqual(len(self.collected_warnings), 1) + warning = self.collected_warnings.pop() + + self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.MOVED) + self.assertEqual(warning.old_module, "test_deprecation") + self.assertEqual(warning.new_module, "test_deprecation") + self.assertEqual(warning.old_name, "OldName") + self.assertEqual(warning.new_name, "AnyClass") + self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CLASS) + self.assertEqual(warning.version, "1.2.3") + self.assertEqual(warning.package, "logilab-common") + + self.collected_warnings = [] + + AnyClass = deprecation.class_moved(new_class=AnyClass, version="1.2.3") + + AnyClass() + + self.assertEqual(len(self.collected_warnings), 1) + warning = self.collected_warnings.pop() + + self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.MOVED) + self.assertEqual(warning.old_module, "test_deprecation") + self.assertEqual(warning.new_module, "test_deprecation") + self.assertEqual(warning.old_name, "AnyClass") + self.assertEqual(warning.new_name, "AnyClass") + self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CLASS) + self.assertEqual(warning.version, "1.2.3") + self.assertEqual(warning.package, "logilab-common") def test_deprecated_func(self): any_func = deprecation.callable_deprecated()(self.mk_func()) @@ -352,6 +561,8 @@ self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.DEPRECATED) self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CALLABLE) + self.assertEqual(warning.version, None) + self.assertEqual(warning.package, "logilab-common") any_func = deprecation.callable_deprecated("message")(self.mk_func()) any_func() @@ -361,6 +572,31 @@ self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.DEPRECATED) self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CALLABLE) + self.assertEqual(warning.version, None) + self.assertEqual(warning.package, "logilab-common") + + def test_deprecated_func_version(self): + any_func = deprecation.callable_deprecated(version="1.2.3")(self.mk_func()) + any_func() + + self.assertEqual(len(self.collected_warnings), 1) + warning = self.collected_warnings.pop() + + self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.DEPRECATED) + self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CALLABLE) + self.assertEqual(warning.version, "1.2.3") + self.assertEqual(warning.package, "logilab-common") + + any_func = deprecation.callable_deprecated("message", version="1.2.3")(self.mk_func()) + any_func() + + self.assertEqual(len(self.collected_warnings), 1) + warning = self.collected_warnings.pop() + + self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.DEPRECATED) + self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CALLABLE) + self.assertEqual(warning.version, "1.2.3") + self.assertEqual(warning.package, "logilab-common") def test_deprecated_decorator(self): @deprecation.callable_deprecated() @@ -374,6 +610,8 @@ self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.DEPRECATED) self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CALLABLE) + self.assertEqual(warning.version, None) + self.assertEqual(warning.package, "logilab-common") @deprecation.callable_deprecated("message") def any_func(): @@ -386,6 +624,37 @@ self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.DEPRECATED) self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CALLABLE) + self.assertEqual(warning.version, None) + self.assertEqual(warning.package, "logilab-common") + + def test_deprecated_decorator_version(self): + @deprecation.callable_deprecated(version="1.2.3") + def any_func(): + pass + + any_func() + + self.assertEqual(len(self.collected_warnings), 1) + warning = self.collected_warnings.pop() + + self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.DEPRECATED) + self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CALLABLE) + self.assertEqual(warning.version, "1.2.3") + self.assertEqual(warning.package, "logilab-common") + + @deprecation.callable_deprecated("message", version="1.2.3") + def any_func(): + pass + + any_func() + + self.assertEqual(len(self.collected_warnings), 1) + warning = self.collected_warnings.pop() + + self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.DEPRECATED) + self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CALLABLE) + self.assertEqual(warning.version, "1.2.3") + self.assertEqual(warning.package, "logilab-common") def test_attribute_renamed(self): @deprecation.attribute_renamed(old_name="old", new_name="new") @@ -404,6 +673,52 @@ self.assertEqual(warning.old_name, "old") self.assertEqual(warning.new_name, "new") self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.ATTRIBUTE) + self.assertEqual(warning.version, None) + self.assertEqual(warning.package, "logilab-common") + + some_class.old = 43 + + self.assertEqual(len(self.collected_warnings), 1) + warning = self.collected_warnings.pop() + + self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.RENAMED) + self.assertEqual(warning.old_name, "old") + self.assertEqual(warning.new_name, "new") + self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.ATTRIBUTE) + self.assertEqual(warning.version, None) + self.assertEqual(warning.package, "logilab-common") + + del some_class.old + + self.assertEqual(len(self.collected_warnings), 1) + warning = self.collected_warnings.pop() + + self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.RENAMED) + self.assertEqual(warning.old_name, "old") + self.assertEqual(warning.new_name, "new") + self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.ATTRIBUTE) + self.assertEqual(warning.version, None) + self.assertEqual(warning.package, "logilab-common") + + def test_attribute_renamed_version(self): + @deprecation.attribute_renamed(old_name="old", new_name="new", version="1.2.3") + class SomeClass: + def __init__(self): + self.new = 42 + + some_class = SomeClass() + + some_class.old == some_class.new # trigger warning + + self.assertEqual(len(self.collected_warnings), 1) + warning = self.collected_warnings.pop() + + self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.RENAMED) + self.assertEqual(warning.old_name, "old") + self.assertEqual(warning.new_name, "new") + self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.ATTRIBUTE) + self.assertEqual(warning.version, "1.2.3") + self.assertEqual(warning.package, "logilab-common") some_class.old = 43 @@ -414,6 +729,8 @@ self.assertEqual(warning.old_name, "old") self.assertEqual(warning.new_name, "new") self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.ATTRIBUTE) + self.assertEqual(warning.version, "1.2.3") + self.assertEqual(warning.package, "logilab-common") del some_class.old @@ -424,6 +741,8 @@ self.assertEqual(warning.old_name, "old") self.assertEqual(warning.new_name, "new") self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.ATTRIBUTE) + self.assertEqual(warning.version, "1.2.3") + self.assertEqual(warning.package, "logilab-common") def test_argument_renamed(self): @deprecation.argument_renamed(old_name="old", new_name="new") @@ -439,6 +758,25 @@ self.assertEqual(warning.old_name, "old") self.assertEqual(warning.new_name, "new") self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.ARGUMENT) + self.assertEqual(warning.version, None) + self.assertEqual(warning.package, "logilab-common") + + def test_argument_renamed_version(self): + @deprecation.argument_renamed(old_name="old", new_name="new", version="1.2.3") + def some_function(new): + return new + + some_function(old=42) + + self.assertEqual(len(self.collected_warnings), 1) + warning = self.collected_warnings.pop() + + self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.RENAMED) + self.assertEqual(warning.old_name, "old") + self.assertEqual(warning.new_name, "new") + self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.ARGUMENT) + self.assertEqual(warning.version, "1.2.3") + self.assertEqual(warning.package, "logilab-common") def test_argument_removed(self): @deprecation.argument_removed("old") @@ -453,6 +791,24 @@ self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.REMOVED) self.assertEqual(warning.name, "old") self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.ARGUMENT) + self.assertEqual(warning.version, None) + self.assertEqual(warning.package, "logilab-common") + + def test_argument_removed_version(self): + @deprecation.argument_removed("old", version="1.2.3") + def some_function(new): + return new + + some_function(new=10, old=20) + + self.assertEqual(len(self.collected_warnings), 1) + warning = self.collected_warnings.pop() + + self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.REMOVED) + self.assertEqual(warning.name, "old") + self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.ARGUMENT) + self.assertEqual(warning.version, "1.2.3") + self.assertEqual(warning.package, "logilab-common") def test_callable_renamed(self): def any_func(): @@ -468,6 +824,25 @@ self.assertEqual(warning.old_name, "old_func") self.assertEqual(warning.new_name, "any_func") self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CALLABLE) + self.assertEqual(warning.version, None) + self.assertEqual(warning.package, "logilab-common") + + def test_callable_renamed_version(self): + def any_func(): + pass + + old_func = deprecation.callable_renamed("old_func", any_func, version="1.2.3") + old_func() + + self.assertEqual(len(self.collected_warnings), 1) + warning = self.collected_warnings.pop() + + self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.RENAMED) + self.assertEqual(warning.old_name, "old_func") + self.assertEqual(warning.new_name, "any_func") + self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CALLABLE) + self.assertEqual(warning.version, "1.2.3") + self.assertEqual(warning.package, "logilab-common") def test_callable_moved(self): module = "data.deprecation" @@ -483,6 +858,25 @@ self.assertEqual(warning.old_name, "moving_target") self.assertEqual(warning.new_name, "moving_target") self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CALLABLE) + self.assertEqual(warning.version, None) + self.assertEqual(warning.package, "logilab-common") + + def test_callable_moved_version(self): + module = "data.deprecation" + moving_target = deprecation.callable_moved(module, "moving_target", version="1.2.3") + moving_target() + + self.assertEqual(len(self.collected_warnings), 1) + warning = self.collected_warnings.pop() + + self.assertEqual(warning.operation, deprecation.DeprecationWarningOperation.MOVED) + self.assertEqual(warning.old_module, "test_deprecation") + self.assertEqual(warning.new_module, "data.deprecation") + self.assertEqual(warning.old_name, "moving_target") + self.assertEqual(warning.new_name, "moving_target") + self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CALLABLE) + self.assertEqual(warning.version, "1.2.3") + self.assertEqual(warning.package, "logilab-common") class DeprecatedWarningsTracebackLocationTest(TestCase): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logilab-common-1.8.3/test/test_testlib.py new/logilab-common-1.9.7/test/test_testlib.py --- old/logilab-common-1.8.3/test/test_testlib.py 2022-01-04 15:03:47.000000000 +0100 +++ new/logilab-common-1.9.7/test/test_testlib.py 2022-06-07 16:22:38.000000000 +0200 @@ -501,7 +501,7 @@ ("FooTC.whatever", 0), ] for pattern, expected_count in data: - yield self.assertRunCount, pattern, self.module, expected_count + self.assertRunCount(pattern, self.module, expected_count) def test_collect_with_pattern(self): data = [ @@ -516,7 +516,7 @@ ("ab", 0), ] for pattern, expected_count in data: - yield self.assertRunCount, pattern, self.module, expected_count + self.assertRunCount(pattern, self.module, expected_count) def test_testcase_with_custom_metaclass(self): class mymetaclass(type): @@ -553,7 +553,7 @@ ("MyTestCase.whatever", 0), ] for pattern, expected_count in data: - yield self.assertRunCount, pattern, MyMod, expected_count + self.assertRunCount(pattern, MyMod, expected_count) def test_collect_everything_and_skipped_patterns(self): testdata = [ @@ -562,7 +562,7 @@ (["foo", "bar"], 0), ] for skipped, expected_count in testdata: - yield self.assertRunCount, None, self.module, expected_count, skipped + self.assertRunCount(None, self.module, expected_count, skipped) def test_collect_specific_pattern_and_skip_some(self): testdata = [ @@ -571,7 +571,7 @@ ("bar", ["bar"], 0), ] for runpattern, skipped, expected_count in testdata: - yield self.assertRunCount, runpattern, self.module, expected_count, skipped + self.assertRunCount(runpattern, self.module, expected_count, skipped) def test_skip_classname(self): testdata = [ @@ -579,7 +579,7 @@ (["FooTC"], 1), ] for skipped, expected_count in testdata: - yield self.assertRunCount, None, self.module, expected_count, skipped + self.assertRunCount(None, self.module, expected_count, skipped) def test_skip_classname_and_specific_collect(self): testdata = [ @@ -587,7 +587,7 @@ ("foo", ["FooTC"], 0), ] for runpattern, skipped, expected_count in testdata: - yield self.assertRunCount, runpattern, self.module, expected_count, skipped + self.assertRunCount(runpattern, self.module, expected_count, skipped) def test_nonregr_dotted_path(self): self.assertRunCount("FooTC.test_foo", self.module, 2) @@ -615,7 +615,7 @@ ("odd", 0), ] for pattern, expected_count in data: - yield self.assertRunCount, pattern, MyMod, expected_count + self.assertRunCount(pattern, MyMod, expected_count) def test_nonregr_class_skipped_option(self): class MyMod: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logilab-common-1.8.3/test/test_textutils.py new/logilab-common-1.9.7/test/test_textutils.py --- old/logilab-common-1.8.3/test/test_textutils.py 2022-01-04 15:21:54.000000000 +0100 +++ new/logilab-common-1.9.7/test/test_textutils.py 2022-06-07 16:22:38.000000000 +0200 @@ -318,7 +318,7 @@ ("Bordeaux\u2013M??rignac", "Bordeaux-Merignac"), ] for input, output in data: - yield self.assertEqual, tu.unormalize(input), output + self.assertEqual(tu.unormalize(input), output) def test_unormalize_substitute(self): self.assertEqual(tu.unormalize("ab \u8000 cd", substitute="_"), "ab _ cd") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logilab-common-1.8.3/tox.ini new/logilab-common-1.9.7/tox.ini --- old/logilab-common-1.8.3/tox.ini 2022-01-04 16:16:04.000000000 +0100 +++ new/logilab-common-1.9.7/tox.ini 2022-06-07 16:22:38.000000000 +0200 @@ -4,7 +4,7 @@ [testenv] deps = pytz - pytest == 5.4.1 + pytest git+https://github.com/psycojoker/pytest-capture-deprecatedwarnings commands= {envpython} -m pytest test {posargs}