Skip to content

Commit 673e5ce

Browse files
Add @typing_extensions.deprecated (#105)
See PEP 702, python/peps#2942.
1 parent 27646ec commit 673e5ce

File tree

4 files changed

+77
-1
lines changed

4 files changed

+77
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Unreleased
22

3+
- Runtime support for PEP 702, adding `typing_extensions.deprecated`. Patch
4+
by Jelle Zijlstra.
35
- Add better default value for TypeVar `default` parameter, PEP 696. Enables
46
runtime check if `None` was passed as default. Patch by Marc Mueller (@cdce8p).
57
- The `@typing_extensions.override` decorator now sets the `.__override__`

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ This module currently contains the following:
3838
- `override` (see [PEP 698](https://peps.python.org/pep-0698/))
3939
- The `default=` argument to `TypeVar`, `ParamSpec`, and `TypeVarTuple` (see [PEP 696](https://peps.python.org/pep-0696/))
4040
- The `infer_variance=` argument to `TypeVar` (see [PEP 695](https://peps.python.org/pep-0695/))
41+
- The `@deprecated` decorator (see [PEP 702](https://peps.python.org/pep-0698/))
4142

4243
- In `typing` since Python 3.11
4344

src/test_typing_extensions.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from typing_extensions import assert_type, get_type_hints, get_origin, get_args
3030
from typing_extensions import clear_overloads, get_overloads, overload
3131
from typing_extensions import NamedTuple
32-
from typing_extensions import override
32+
from typing_extensions import override, deprecated
3333
from _typed_dict_test_helper import Foo, FooGeneric
3434

3535
# Flags used to mark tests that only apply after a specific
@@ -202,6 +202,35 @@ def static_method_bad_order():
202202
self.assertIs(False, hasattr(Derived.static_method_bad_order, "__override__"))
203203

204204

205+
class DeprecatedTests(BaseTestCase):
206+
def test_deprecated(self):
207+
@deprecated("A will go away soon")
208+
class A:
209+
pass
210+
211+
self.assertEqual(A.__deprecated__, "A will go away soon")
212+
self.assertIsInstance(A, type)
213+
214+
@deprecated("b will go away soon")
215+
def b():
216+
pass
217+
218+
self.assertEqual(b.__deprecated__, "b will go away soon")
219+
self.assertIsInstance(b, types.FunctionType)
220+
221+
@overload
222+
@deprecated("no more ints")
223+
def h(x: int) -> int: ...
224+
@overload
225+
def h(x: str) -> str: ...
226+
def h(x):
227+
return x
228+
229+
overloads = get_overloads(h)
230+
self.assertEqual(len(overloads), 2)
231+
self.assertEqual(overloads[0].__deprecated__, "no more ints")
232+
233+
205234
class AnyTests(BaseTestCase):
206235
def test_can_subclass(self):
207236
class Mock(Any): pass

src/typing_extensions.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
'assert_type',
5353
'clear_overloads',
5454
'dataclass_transform',
55+
'deprecated',
5556
'get_overloads',
5657
'final',
5758
'get_args',
@@ -2129,6 +2130,49 @@ def method(self) -> None:
21292130
return __arg
21302131

21312132

2133+
if hasattr(typing, "deprecated"):
2134+
deprecated = typing.deprecated
2135+
else:
2136+
_T = typing.TypeVar("_T")
2137+
2138+
def deprecated(__msg: str) -> typing.Callable[[_T], _T]:
2139+
"""Indicate that a class, function or overload is deprecated.
2140+
2141+
Usage:
2142+
2143+
@deprecated("Use B instead")
2144+
class A:
2145+
pass
2146+
2147+
@deprecated("Use g instead")
2148+
def f():
2149+
pass
2150+
2151+
@overload
2152+
@deprecated("int support is deprecated")
2153+
def g(x: int) -> int: ...
2154+
@overload
2155+
def g(x: str) -> int: ...
2156+
2157+
When this decorator is applied to an object, the type checker
2158+
will generate a diagnostic on usage of the deprecated object.
2159+
2160+
No runtime warning is issued. The decorator sets the ``__deprecated__``
2161+
attribute on the decorated object to the deprecation message
2162+
passed to the decorator. If applied to an overload, the decorator
2163+
must be after the ``@overload`` decorator for the attribute to
2164+
exist on the overload as returned by ``get_overloads()``.
2165+
2166+
See PEP 702 for details.
2167+
2168+
"""
2169+
def decorator(__arg: _T) -> _T:
2170+
__arg.__deprecated__ = __msg
2171+
return __arg
2172+
2173+
return decorator
2174+
2175+
21322176
# We have to do some monkey patching to deal with the dual nature of
21332177
# Unpack/TypeVarTuple:
21342178
# - We want Unpack to be a kind of TypeVar so it gets accepted in

0 commit comments

Comments
 (0)
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