From a410aac5e865561ba3b39c89b60dd1f77dd6eac9 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 31 Dec 2022 11:29:33 -0800 Subject: [PATCH 1/4] Add @typing_extensions.deprecated See PEP 702, python/peps#2942. This should not be merged until the PEP is merged into the repo. --- README.md | 1 + src/test_typing_extensions.py | 31 +++++++++++++++++++++++++- src/typing_extensions.py | 42 +++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 55314d46..15200c35 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ This module currently contains the following: - `override` (see [PEP 698](https://peps.python.org/pep-0698/)) - The `default=` argument to `TypeVar`, `ParamSpec`, and `TypeVarTuple` (see [PEP 696](https://peps.python.org/pep-0696/)) - The `infer_variance=` argument to `TypeVar` (see [PEP 695](https://peps.python.org/pep-0695/)) + - The `@deprecated` decorator (see [PEP 702](https://peps.python.org/pep-0698/)) - In `typing` since Python 3.11 diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index d5982b9b..9013aeb9 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -29,7 +29,7 @@ from typing_extensions import assert_type, get_type_hints, get_origin, get_args from typing_extensions import clear_overloads, get_overloads, overload from typing_extensions import NamedTuple -from typing_extensions import override +from typing_extensions import override, deprecated from _typed_dict_test_helper import Foo, FooGeneric # Flags used to mark tests that only apply after a specific @@ -202,6 +202,35 @@ def static_method_bad_order(): self.assertIs(False, hasattr(Derived.static_method_bad_order, "__override__")) +class DeprecatedTests(BaseTestCase): + def test_deprecated(self): + @deprecated("A will go away soon") + class A: + pass + + self.assertEqual(A.__deprecated__, "A will go away soon") + self.assertIsInstance(A, type) + + @deprecated("b will go away soon") + def b(): + pass + + self.assertEqual(b.__deprecated__, "b will go away soon") + self.assertIsInstance(b, types.FunctionType) + + @overload + @deprecated("no more ints") + def h(x: int) -> int: ... + @overload + def h(x: str) -> str: ... + def h(x): + return x + + overloads = get_overloads(h) + self.assertEqual(len(overloads), 2) + self.assertEqual(overloads[0].__deprecated__, "no more ints") + + class AnyTests(BaseTestCase): def test_can_subclass(self): class Mock(Any): pass diff --git a/src/typing_extensions.py b/src/typing_extensions.py index 03fe268e..479692f5 100644 --- a/src/typing_extensions.py +++ b/src/typing_extensions.py @@ -52,6 +52,7 @@ 'assert_type', 'clear_overloads', 'dataclass_transform', + 'deprecated', 'get_overloads', 'final', 'get_args', @@ -2128,6 +2129,47 @@ def method(self) -> None: return __arg +if hasattr(typing, "deprecated"): + override = typing.deprecated +else: + _T = typing.TypeVar("_T") + + def deprecated(__msg: str) -> typing.Callable[[_T], _T]: + """Indicate that a class, function or overload is deprecated. + + Usage: + + @deprecated("Use B instead") + class A: + pass + + @deprecated("Use g instead") + def f(): + pass + + @deprecated("int support is deprecated") + @overload + def g(x: int) -> int: ... + @overload + def g(x: str) -> int: ... + + When this decorator is applied to an object, the type checker + will generate a diagnostic on usage of the deprecated object. + + No runtime warning is issued. The decorator sets the ``__deprecated__`` + attribute on the decorated object to the deprecation message + passed to the decorator. + + See PEP 702 for details. + + """ + def decorator(__arg: _T) -> _T: + __arg.__deprecated__ = __msg + return __arg + + return decorator + + # We have to do some monkey patching to deal with the dual nature of # Unpack/TypeVarTuple: # - We want Unpack to be a kind of TypeVar so it gets accepted in From 0f08b6348fb739c8bcffff28e5d13544275e26da Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 31 Dec 2022 11:38:49 -0800 Subject: [PATCH 2/4] fix --- CHANGELOG.md | 4 +++- src/typing_extensions.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3cd4630..6fe6f920 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ -# Release 4.4.1 (?) +# Unreleased +- Runtime support for PEP 702, adding `typing_extensions.deprecated`. Patch + by Jelle Zijlstra. - Add better default value for TypeVar `default` parameter, PEP 696. Enables runtime check if `None` was passed as default. Patch by Marc Mueller (@cdce8p). diff --git a/src/typing_extensions.py b/src/typing_extensions.py index 479692f5..ba8021b4 100644 --- a/src/typing_extensions.py +++ b/src/typing_extensions.py @@ -2130,7 +2130,7 @@ def method(self) -> None: if hasattr(typing, "deprecated"): - override = typing.deprecated + deprecated = typing.deprecated else: _T = typing.TypeVar("_T") From 31be31684237c158f8217443453b555f8a45a183 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sun, 1 Jan 2023 16:25:06 -0800 Subject: [PATCH 3/4] Update src/typing_extensions.py --- src/typing_extensions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/typing_extensions.py b/src/typing_extensions.py index cb460f5a..15a139d2 100644 --- a/src/typing_extensions.py +++ b/src/typing_extensions.py @@ -2148,8 +2148,8 @@ class A: def f(): pass - @deprecated("int support is deprecated") @overload + @deprecated("int support is deprecated") def g(x: int) -> int: ... @overload def g(x: str) -> int: ... From f3bf9977d57f65453587119df04a8aa3c29849f5 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sun, 1 Jan 2023 19:38:58 -0800 Subject: [PATCH 4/4] discuss overloads --- src/typing_extensions.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/typing_extensions.py b/src/typing_extensions.py index 15a139d2..c32c63d1 100644 --- a/src/typing_extensions.py +++ b/src/typing_extensions.py @@ -2159,7 +2159,9 @@ def g(x: str) -> int: ... No runtime warning is issued. The decorator sets the ``__deprecated__`` attribute on the decorated object to the deprecation message - passed to the decorator. + passed to the decorator. If applied to an overload, the decorator + must be after the ``@overload`` decorator for the attribute to + exist on the overload as returned by ``get_overloads()``. See PEP 702 for details. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy