From 1ae287bd97b46e19b2f9c411be24dd26949cb307 Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Mon, 2 Dec 2024 11:05:41 +0100 Subject: [PATCH] Remove `deprecate_function` and `deprecate_arguments` decorators (deprecated in 0.24) (#13448) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * remove deprecated_function and deprecated_argument decorators * reno * Update releasenotes/notes/deprecate_arguments_and_deprecate_function-5e19f6f049fa489c.yaml Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com> --------- Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com> --- qiskit/utils/__init__.py | 6 - qiskit/utils/deprecation.py | 108 ------------------ ...d_deprecate_function-5e19f6f049fa489c.yaml | 7 ++ test/python/utils/test_deprecation.py | 94 --------------- 4 files changed, 7 insertions(+), 208 deletions(-) create mode 100644 releasenotes/notes/deprecate_arguments_and_deprecate_function-5e19f6f049fa489c.yaml diff --git a/qiskit/utils/__init__.py b/qiskit/utils/__init__.py index 30935437ebf2..c6b73e09ff28 100644 --- a/qiskit/utils/__init__.py +++ b/qiskit/utils/__init__.py @@ -23,9 +23,7 @@ .. autofunction:: add_deprecation_to_docstring .. autofunction:: deprecate_arg -.. autofunction:: deprecate_arguments .. autofunction:: deprecate_func -.. autofunction:: deprecate_function SI unit conversion ================== @@ -58,9 +56,7 @@ from .deprecation import ( add_deprecation_to_docstring, deprecate_arg, - deprecate_arguments, deprecate_func, - deprecate_function, ) from .multiprocessing import local_hardware_info from .multiprocessing import is_main_process @@ -78,9 +74,7 @@ "LazySubprocessTester", "add_deprecation_to_docstring", "deprecate_arg", - "deprecate_arguments", "deprecate_func", - "deprecate_function", "local_hardware_info", "is_main_process", "apply_prefix", diff --git a/qiskit/utils/deprecation.py b/qiskit/utils/deprecation.py index aebea233282e..2a1e4adbc1b8 100644 --- a/qiskit/utils/deprecation.py +++ b/qiskit/utils/deprecation.py @@ -205,114 +205,6 @@ def wrapper(*args, **kwargs): return decorator -def deprecate_arguments( - kwarg_map: dict[str, str | None], - category: Type[Warning] = DeprecationWarning, - *, - since: str | None = None, -): - """Deprecated. Instead, use `@deprecate_arg`. - - Args: - kwarg_map: A dictionary of the old argument name to the new name. - category: Usually either DeprecationWarning or PendingDeprecationWarning. - since: The version the deprecation started at. Only Optional for backwards - compatibility - this should always be set. If the deprecation is pending, set - the version to when that started; but later, when switching from pending to - deprecated, update `since` to the new version. - - Returns: - Callable: The decorated callable. - """ - - def decorator(func): - func_name = func.__qualname__ - old_kwarg_to_msg = {} - for old_arg, new_arg in kwarg_map.items(): - msg_suffix = ( - "will in the future be removed." if new_arg is None else f"replaced with {new_arg}." - ) - old_kwarg_to_msg[old_arg] = ( - f"{func_name} keyword argument {old_arg} is deprecated and {msg_suffix}" - ) - - @functools.wraps(func) - def wrapper(*args, **kwargs): - for old, new in kwarg_map.items(): - _maybe_warn_and_rename_kwarg( - args, - kwargs, - func_name=func_name, - original_func_co_varnames=wrapper.__original_func_co_varnames, - old_arg_name=old, - new_alias=new, - warning_msg=old_kwarg_to_msg[old], - category=category, - predicate=None, - ) - return func(*args, **kwargs) - - # When decorators get called repeatedly, `func` refers to the result of the prior - # decorator, not the original underlying function. This trick allows us to record the - # original function's variable names regardless of how many decorators are used. - # - # If it's the very first decorator call, we also check that *args and **kwargs are not used. - if hasattr(func, "__original_func_co_varnames"): - wrapper.__original_func_co_varnames = func.__original_func_co_varnames - else: - wrapper.__original_func_co_varnames = func.__code__.co_varnames - param_kinds = {param.kind for param in inspect.signature(func).parameters.values()} - if inspect.Parameter.VAR_POSITIONAL in param_kinds: - raise ValueError( - "@deprecate_arg cannot be used with functions that take variable *args. Use " - "warnings.warn() directly instead." - ) - - for msg in old_kwarg_to_msg.values(): - add_deprecation_to_docstring( - wrapper, msg, since=since, pending=issubclass(category, PendingDeprecationWarning) - ) - return wrapper - - return decorator - - -def deprecate_function( - msg: str, - stacklevel: int = 2, - category: Type[Warning] = DeprecationWarning, - *, - since: str | None = None, -): - """Deprecated. Instead, use `@deprecate_func`. - - Args: - msg: Warning message to emit. - stacklevel: The warning stacklevel to use, defaults to 2. - category: Usually either DeprecationWarning or PendingDeprecationWarning. - since: The version the deprecation started at. Only Optional for backwards - compatibility - this should always be set. If the deprecation is pending, set - the version to when that started; but later, when switching from pending to - deprecated, update `since` to the new version. - - Returns: - Callable: The decorated, deprecated callable. - """ - - def decorator(func): - @functools.wraps(func) - def wrapper(*args, **kwargs): - warnings.warn(msg, category=category, stacklevel=stacklevel) - return func(*args, **kwargs) - - add_deprecation_to_docstring( - wrapper, msg, since=since, pending=issubclass(category, PendingDeprecationWarning) - ) - return wrapper - - return decorator - - def _maybe_warn_and_rename_kwarg( args: tuple[Any, ...], kwargs: dict[str, Any], diff --git a/releasenotes/notes/deprecate_arguments_and_deprecate_function-5e19f6f049fa489c.yaml b/releasenotes/notes/deprecate_arguments_and_deprecate_function-5e19f6f049fa489c.yaml new file mode 100644 index 000000000000..7dfb70703cff --- /dev/null +++ b/releasenotes/notes/deprecate_arguments_and_deprecate_function-5e19f6f049fa489c.yaml @@ -0,0 +1,7 @@ +--- +upgrade_misc: + - | + The ``deprecate_function`` and ``deprecate_arguments`` decorators had been deprecated since 0.24, released + on May 2023, and have been removed in 2.0. + Current :func:`deprecate_func`` replaces ``@deprecate_function`` and current + :func:`deprecate_arg` replaces ``@deprecate_arguments``. diff --git a/test/python/utils/test_deprecation.py b/test/python/utils/test_deprecation.py index 08872b9e7a41..1e2f98b17263 100644 --- a/test/python/utils/test_deprecation.py +++ b/test/python/utils/test_deprecation.py @@ -20,9 +20,7 @@ from qiskit.utils.deprecation import ( add_deprecation_to_docstring, deprecate_arg, - deprecate_arguments, deprecate_func, - deprecate_function, ) from test import QiskitTestCase # pylint: disable=wrong-import-order @@ -164,51 +162,6 @@ def my_func() -> None: ), ) - def test_deprecate_arguments_docstring(self) -> None: - """Test that `@deprecate_arguments` adds the correct message to the docstring.""" - - @deprecate_arguments( - {"old_arg1": "new_arg1", "old_arg2": None}, - category=PendingDeprecationWarning, - since="9.99", - ) - def my_func() -> None: - pass - - self.assertEqual( - my_func.__doc__, - dedent( - f"""\ - - .. deprecated:: 9.99_pending - {my_func.__qualname__} keyword argument old_arg1 is deprecated and replaced with \ -new_arg1. - - .. deprecated:: 9.99_pending - {my_func.__qualname__} keyword argument old_arg2 is deprecated and will in the \ -future be removed. - """ - ), - ) - - def test_deprecate_function_docstring(self) -> None: - """Test that `@deprecate_function` adds the correct message to the docstring.""" - - @deprecate_function("Stop using my_func!", since="9.99") - def my_func() -> None: - pass - - self.assertEqual( - my_func.__doc__, - dedent( - """\ - - .. deprecated:: 9.99 - Stop using my_func! - """ - ), - ) - def test_deprecate_func_runtime_warning(self) -> None: """Test that `@deprecate_func` warns whenever the function is used.""" @@ -313,53 +266,6 @@ def my_func2(my_kwarg: int | None = None, **kwargs) -> None: with self.assertWarnsRegex(DeprecationWarning, "my_kwarg"): my_func2(my_kwarg=5, another_arg=0, yet_another=0) - def test_deprecate_arguments_runtime_warning(self) -> None: - """Test that `@deprecate_arguments` warns whenever the arguments are used. - - Also check that old arguments are passed in as their new alias. - """ - - @deprecate_arguments({"arg1": "new_arg1", "arg2": None}, since="9.99") - def my_func(arg1: str = "a", arg2: str = "a", new_arg1: str | None = None) -> None: - del arg2 - # If the old arg was set, we should set its `new_alias` to that value. - if arg1 != "a": - self.assertEqual(new_arg1, "z") - if new_arg1 is not None: - self.assertEqual(new_arg1, "z") - - # No warnings if no deprecated args used. - my_func() - my_func(new_arg1="z") - - # Warn if argument is specified, regardless of positional vs kwarg. - with self.assertWarnsRegex(DeprecationWarning, "arg1"): - my_func("z") - with self.assertWarnsRegex(DeprecationWarning, "arg1"): - my_func(arg1="z") - with self.assertWarnsRegex(DeprecationWarning, "arg2"): - my_func("z", "z") - with self.assertWarnsRegex(DeprecationWarning, "arg2"): - my_func(arg2="z") - - # Error if new_alias specified at the same time as old argument name. - with self.assertRaises(TypeError): - my_func("a", new_arg1="z") - with self.assertRaises(TypeError): - my_func(arg1="a", new_arg1="z") - with self.assertRaises(TypeError): - my_func("a", "a", "z") - - def test_deprecate_function_runtime_warning(self) -> None: - """Test that `@deprecate_function` warns whenever the function is used.""" - - @deprecate_function("Stop using my_func!", since="9.99") - def my_func() -> None: - pass - - with self.assertWarnsRegex(DeprecationWarning, "Stop using my_func!"): - my_func() - class AddDeprecationDocstringTest(QiskitTestCase): """Test that we correctly insert the deprecation directive at the right location.