summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Rittau <srittau@rittau.biz>2024-07-23 09:59:28 (GMT)
committerGitHub <noreply@github.com>2024-07-23 09:59:28 (GMT)
commit375c9f6dfb78345dd0966d6f3b281f15107b0561 (patch)
tree57c42dcd869a38d15d775e17b2f1ad104db46e49
parent2a5d1eb7073179a13159bce937afdbe240432e7d (diff)
downloadcpython-375c9f6dfb78345dd0966d6f3b281f15107b0561.zip
cpython-375c9f6dfb78345dd0966d6f3b281f15107b0561.tar.gz
cpython-375c9f6dfb78345dd0966d6f3b281f15107b0561.tar.bz2
gh-122088: Copy the coroutine status of the underlying callable in `@warnings.deprecated` (#122086)
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
-rw-r--r--Lib/test/test_warnings/__init__.py24
-rw-r--r--Lib/warnings.py4
-rw-r--r--Misc/NEWS.d/next/Library/2024-07-21-18-03-30.gh-issue-122088.vi2bP-.rst3
3 files changed, 31 insertions, 0 deletions
diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py
index f9b2b07..7d04371 100644
--- a/Lib/test/test_warnings/__init__.py
+++ b/Lib/test/test_warnings/__init__.py
@@ -1,6 +1,7 @@
from contextlib import contextmanager
import linecache
import os
+import inspect
from io import StringIO
import re
import sys
@@ -1684,6 +1685,29 @@ class DeprecatedTests(unittest.TestCase):
isinstance(cell.cell_contents, deprecated) for cell in d.__closure__
))
+ def test_inspect(self):
+ @deprecated("depr")
+ def sync():
+ pass
+
+ @deprecated("depr")
+ async def coro():
+ pass
+
+ class Cls:
+ @deprecated("depr")
+ def sync(self):
+ pass
+
+ @deprecated("depr")
+ async def coro(self):
+ pass
+
+ self.assertFalse(inspect.iscoroutinefunction(sync))
+ self.assertTrue(inspect.iscoroutinefunction(coro))
+ self.assertFalse(inspect.iscoroutinefunction(Cls.sync))
+ self.assertTrue(inspect.iscoroutinefunction(Cls.coro))
+
def setUpModule():
py_warnings.onceregistry.clear()
c_warnings.onceregistry.clear()
diff --git a/Lib/warnings.py b/Lib/warnings.py
index d344cea..e83cde3 100644
--- a/Lib/warnings.py
+++ b/Lib/warnings.py
@@ -628,12 +628,16 @@ class deprecated:
return arg
elif callable(arg):
import functools
+ import inspect
@functools.wraps(arg)
def wrapper(*args, **kwargs):
warn(msg, category=category, stacklevel=stacklevel + 1)
return arg(*args, **kwargs)
+ if inspect.iscoroutinefunction(arg):
+ wrapper = inspect.markcoroutinefunction(wrapper)
+
arg.__deprecated__ = wrapper.__deprecated__ = msg
return wrapper
else:
diff --git a/Misc/NEWS.d/next/Library/2024-07-21-18-03-30.gh-issue-122088.vi2bP-.rst b/Misc/NEWS.d/next/Library/2024-07-21-18-03-30.gh-issue-122088.vi2bP-.rst
new file mode 100644
index 0000000..9c173d8
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-07-21-18-03-30.gh-issue-122088.vi2bP-.rst
@@ -0,0 +1,3 @@
+:func:`@warnings.deprecated <warnings.deprecated>` now copies the
+coroutine status of functions and methods so that
+:func:`inspect.iscoroutinefunction` returns the correct result.