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>
This commit is contained in:
Sebastian Rittau 2024-07-23 11:59:28 +02:00 committed by GitHub
parent 2a5d1eb707
commit 375c9f6dfb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 31 additions and 0 deletions

View File

@ -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()

View File

@ -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:

View File

@ -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.