Skip to content

Commit d9509f9

Browse files
srittauAlexWaygood
andauthored
Copy the coroutine status in deprecated (python#438)
Co-authored-by: Alex Waygood <[email protected]>
1 parent 70cec91 commit d9509f9

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
- Add `typing_extensions.get_annotations`, a backport of
66
`inspect.get_annotations` that adds features specified
77
by PEP 649. Patches by Jelle Zijlstra and Alex Waygood.
8+
- Copy the coroutine status of functions and methods wrapped
9+
with `@typing_extensions.deprecated`. Patch by Sebastian Rittau.
810

911
# Release 4.12.2 (June 7, 2024)
1012

src/test_typing_extensions.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import abc
2+
import asyncio
23
import collections
34
import collections.abc
45
import contextlib
@@ -115,9 +116,15 @@
115116
# and adds PEP 695 to CPython's grammar
116117
TYPING_3_12_0 = sys.version_info[:3] >= (3, 12, 0)
117118

119+
# @deprecated works differently in Python 3.12
120+
TYPING_3_12_ONLY = (3, 12) <= sys.version_info < (3, 13)
121+
118122
# 3.13 drops support for the keyword argument syntax of TypedDict
119123
TYPING_3_13_0 = sys.version_info[:3] >= (3, 13, 0)
120124

125+
# 3.13.0.rc1 fixes a problem with @deprecated
126+
TYPING_3_13_0_RC = sys.version_info[:4] >= (3, 13, 0, "candidate")
127+
121128
# https://github.com/python/cpython/pull/27017 was backported into some 3.9 and 3.10
122129
# versions, but not all
123130
HAS_FORWARD_MODULE = "module" in inspect.signature(typing._type_check).parameters
@@ -850,6 +857,37 @@ def d(): pass
850857
isinstance(cell.cell_contents, deprecated) for cell in d.__closure__
851858
))
852859

860+
@deprecated("depr")
861+
def func():
862+
pass
863+
864+
@deprecated("depr")
865+
async def coro():
866+
pass
867+
868+
class Cls:
869+
@deprecated("depr")
870+
def func(self):
871+
pass
872+
873+
@deprecated("depr")
874+
async def coro(self):
875+
pass
876+
877+
class DeprecatedCoroTests(BaseTestCase):
878+
def test_asyncio_iscoroutinefunction(self):
879+
self.assertFalse(asyncio.coroutines.iscoroutinefunction(func))
880+
self.assertFalse(asyncio.coroutines.iscoroutinefunction(Cls.func))
881+
self.assertTrue(asyncio.coroutines.iscoroutinefunction(coro))
882+
self.assertTrue(asyncio.coroutines.iscoroutinefunction(Cls.coro))
883+
884+
@skipUnless(TYPING_3_12_ONLY or TYPING_3_13_0_RC, "inspect.iscoroutinefunction works differently on Python < 3.12")
885+
def test_inspect_iscoroutinefunction(self):
886+
self.assertFalse(inspect.iscoroutinefunction(func))
887+
self.assertFalse(inspect.iscoroutinefunction(Cls.func))
888+
self.assertTrue(inspect.iscoroutinefunction(coro))
889+
self.assertTrue(inspect.iscoroutinefunction(Cls.coro))
890+
853891

854892
class AnyTests(BaseTestCase):
855893
def test_can_subclass(self):

src/typing_extensions.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2898,13 +2898,21 @@ def __init_subclass__(*args, **kwargs):
28982898
__init_subclass__.__deprecated__ = msg
28992899
return arg
29002900
elif callable(arg):
2901+
import asyncio.coroutines
29012902
import functools
2903+
import inspect
29022904

29032905
@functools.wraps(arg)
29042906
def wrapper(*args, **kwargs):
29052907
warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
29062908
return arg(*args, **kwargs)
29072909

2910+
if asyncio.coroutines.iscoroutinefunction(arg):
2911+
if sys.version_info >= (3, 12):
2912+
wrapper = inspect.markcoroutinefunction(wrapper)
2913+
else:
2914+
wrapper._is_coroutine = asyncio.coroutines._is_coroutine
2915+
29082916
arg.__deprecated__ = wrapper.__deprecated__ = msg
29092917
return wrapper
29102918
else:

0 commit comments

Comments
 (0)