[3.13] gh-122088: Copy the coroutine status of the underlying callable in `@warnings.deprecated` (GH-122086) (#122156)

Co-authored-by: Sebastian Rittau <srittau@rittau.biz>
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
This commit is contained in:
Miss Islington (bot) 2024-07-23 12:24:07 +02:00 committed by GitHub
parent 48154e7053
commit 7767534df9
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 from contextlib import contextmanager
import linecache import linecache
import os import os
import inspect
from io import StringIO from io import StringIO
import re import re
import sys import sys
@ -1682,6 +1683,29 @@ class DeprecatedTests(unittest.TestCase):
isinstance(cell.cell_contents, deprecated) for cell in d.__closure__ 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(): def setUpModule():
py_warnings.onceregistry.clear() py_warnings.onceregistry.clear()
c_warnings.onceregistry.clear() c_warnings.onceregistry.clear()

View File

@ -629,12 +629,16 @@ class deprecated:
return arg return arg
elif callable(arg): elif callable(arg):
import functools import functools
import inspect
@functools.wraps(arg) @functools.wraps(arg)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
warn(msg, category=category, stacklevel=stacklevel + 1) warn(msg, category=category, stacklevel=stacklevel + 1)
return arg(*args, **kwargs) return arg(*args, **kwargs)
if inspect.iscoroutinefunction(arg):
wrapper = inspect.markcoroutinefunction(wrapper)
arg.__deprecated__ = wrapper.__deprecated__ = msg arg.__deprecated__ = wrapper.__deprecated__ = msg
return wrapper return wrapper
else: 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.