Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add @typing_extensions.deprecated #105

Merged
merged 5 commits into from Jan 3, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,7 @@
# 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).
- The `@typing_extensions.override` decorator now sets the `.__override__`
Expand Down
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -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

Expand Down
31 changes: 30 additions & 1 deletion src/test_typing_extensions.py
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
42 changes: 42 additions & 0 deletions src/typing_extensions.py
Expand Up @@ -52,6 +52,7 @@
'assert_type',
'clear_overloads',
'dataclass_transform',
'deprecated',
'get_overloads',
'final',
'get_args',
Expand Down Expand Up @@ -2129,6 +2130,47 @@ def method(self) -> None:
return __arg


if hasattr(typing, "deprecated"):
deprecated = 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
JelleZijlstra marked this conversation as resolved.
Show resolved Hide resolved
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.
hauntsaninja marked this conversation as resolved.
Show resolved Hide resolved

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
Expand Down