From d09177d218bf913143283cfa65d777d44f6c2bcc Mon Sep 17 00:00:00 2001 From: Erik Wrede Date: Sun, 29 Sep 2024 12:51:35 +0200 Subject: [PATCH] refactor: replace @deprecated decorator with upcoming native support (via typing-extensions) --- graphene/utils/deprecated.py | 68 ++----------------------- graphene/utils/resolve_only_args.py | 3 +- graphene/utils/tests/test_deprecated.py | 64 ----------------------- setup.py | 1 + tox.ini | 2 +- 5 files changed, 6 insertions(+), 132 deletions(-) diff --git a/graphene/utils/deprecated.py b/graphene/utils/deprecated.py index 42c358fb..7138bf56 100644 --- a/graphene/utils/deprecated.py +++ b/graphene/utils/deprecated.py @@ -1,67 +1,5 @@ -import functools -import inspect -import warnings - -string_types = (type(b""), type("")) +from warnings import warn -def warn_deprecation(text): - warnings.warn(text, category=DeprecationWarning, stacklevel=2) - - -def deprecated(reason): - """ - This is a decorator which can be used to mark functions - as deprecated. It will result in a warning being emitted - when the function is used. - """ - - if isinstance(reason, string_types): - # The @deprecated is used with a 'reason'. - # - # .. code-block:: python - # - # @deprecated("please, use another function") - # def old_function(x, y): - # pass - - def decorator(func1): - if inspect.isclass(func1): - fmt1 = f"Call to deprecated class {func1.__name__} ({reason})." - else: - fmt1 = f"Call to deprecated function {func1.__name__} ({reason})." - - @functools.wraps(func1) - def new_func1(*args, **kwargs): - warn_deprecation(fmt1) - return func1(*args, **kwargs) - - return new_func1 - - return decorator - - elif inspect.isclass(reason) or inspect.isfunction(reason): - # The @deprecated is used without any 'reason'. - # - # .. code-block:: python - # - # @deprecated - # def old_function(x, y): - # pass - - func2 = reason - - if inspect.isclass(func2): - fmt2 = f"Call to deprecated class {func2.__name__}." - else: - fmt2 = f"Call to deprecated function {func2.__name__}." - - @functools.wraps(func2) - def new_func2(*args, **kwargs): - warn_deprecation(fmt2) - return func2(*args, **kwargs) - - return new_func2 - - else: - raise TypeError(repr(type(reason))) +def warn_deprecation(text: str): + warn(text, category=DeprecationWarning, stacklevel=2) diff --git a/graphene/utils/resolve_only_args.py b/graphene/utils/resolve_only_args.py index 5efff2ed..088e62ca 100644 --- a/graphene/utils/resolve_only_args.py +++ b/graphene/utils/resolve_only_args.py @@ -1,6 +1,5 @@ from functools import wraps - -from .deprecated import deprecated +from typing_extensions import deprecated @deprecated("This function is deprecated") diff --git a/graphene/utils/tests/test_deprecated.py b/graphene/utils/tests/test_deprecated.py index 8a14434b..b09512f3 100644 --- a/graphene/utils/tests/test_deprecated.py +++ b/graphene/utils/tests/test_deprecated.py @@ -1,7 +1,4 @@ -from pytest import raises - from .. import deprecated -from ..deprecated import deprecated as deprecated_decorator from ..deprecated import warn_deprecation @@ -12,64 +9,3 @@ def test_warn_deprecation(mocker): deprecated.warnings.warn.assert_called_with( "OH!", stacklevel=2, category=DeprecationWarning ) - - -def test_deprecated_decorator(mocker): - mocker.patch.object(deprecated, "warn_deprecation") - - @deprecated_decorator - def my_func(): - return True - - result = my_func() - assert result - deprecated.warn_deprecation.assert_called_with( - "Call to deprecated function my_func." - ) - - -def test_deprecated_class(mocker): - mocker.patch.object(deprecated, "warn_deprecation") - - @deprecated_decorator - class X: - pass - - result = X() - assert result - deprecated.warn_deprecation.assert_called_with("Call to deprecated class X.") - - -def test_deprecated_decorator_text(mocker): - mocker.patch.object(deprecated, "warn_deprecation") - - @deprecated_decorator("Deprecation text") - def my_func(): - return True - - result = my_func() - assert result - deprecated.warn_deprecation.assert_called_with( - "Call to deprecated function my_func (Deprecation text)." - ) - - -def test_deprecated_class_text(mocker): - mocker.patch.object(deprecated, "warn_deprecation") - - @deprecated_decorator("Deprecation text") - class X: - pass - - result = X() - assert result - deprecated.warn_deprecation.assert_called_with( - "Call to deprecated class X (Deprecation text)." - ) - - -def test_deprecated_other_object(mocker): - mocker.patch.object(deprecated, "warn_deprecation") - - with raises(TypeError): - deprecated_decorator({}) diff --git a/setup.py b/setup.py index c41a368a..33ceba50 100644 --- a/setup.py +++ b/setup.py @@ -83,6 +83,7 @@ setup( install_requires=[ "graphql-core>=3.1,<3.3", "graphql-relay>=3.1,<3.3", + "typing-extensions>=4.7.1,<5", ], tests_require=tests_require, extras_require={"test": tests_require, "dev": dev_requires}, diff --git a/tox.ini b/tox.ini index 00c10174..dc42a653 100644 --- a/tox.ini +++ b/tox.ini @@ -20,7 +20,7 @@ commands = [testenv:mypy] basepython = python3.10 deps = - mypy>=0.950,<1 + mypy>=1.10,<2 commands = mypy graphene