@@ -1554,6 +1554,18 @@ def wrap(fn: F) -> F:
15541554
15551555 return cast(F, wrapper)
15561556
1557+ C = Callable[..., Any]
1558+
1559+ def get_decorator() -> C:
1560+ def decorator(endpoint: C) -> C:
1561+ @wraps(endpoint)
1562+ async def inner(self: Any, val: int, *args: Any) -> Any:
1563+ return await endpoint(self, val, *args)
1564+
1565+ return cast(C, inner)
1566+
1567+ return cast(C, decorator)
1568+
15571569@wrap
15581570def wrapped(val: int) -> int:
15591571 return val
@@ -1571,34 +1583,57 @@ async def wrapped2_async(val: int) -> int:
15711583 return val * 2
15721584
15731585class T:
1574- def returns_one(self) -> int:
1586+ def returns_one(self, val: int ) -> int:
15751587 return 1
15761588
1577- async def returns_one_async(self) -> int:
1589+ async def returns_one_async(self, val: int ) -> int:
15781590 return 1
15791591
15801592 @wrap
1581- def returns_two(self) -> int:
1593+ def returns_two(self, val: int ) -> int:
15821594 return 1
15831595
15841596 @wrap
1585- async def returns_two_async(self) -> int:
1597+ async def returns_two_async(self, val: int ) -> int:
15861598 return 1
15871599
15881600 @staticmethod
1589- def static() -> int:
1601+ def static(val: int) -> int:
1602+ return 2
1603+
1604+ @staticmethod
1605+ async def static_async(val: int) -> int:
1606+ return 2
1607+
1608+ @staticmethod
1609+ @wrap
1610+ def wrapped_static(val: int) -> int:
15901611 return 2
15911612
15921613 @staticmethod
1593- async def static_async() -> int:
1614+ @wrap
1615+ async def wrapped_static_async(val: int) -> int:
15941616 return 2
15951617
15961618 @classmethod
1597- def class_method(cls) -> int:
1619+ def class_method(cls, val: int ) -> int:
15981620 return 3
15991621
16001622 @classmethod
1601- async def class_method_async(cls) -> int:
1623+ async def class_method_async(cls, val: int) -> int:
1624+ assert cls is T
1625+ return 3
1626+
1627+ @classmethod
1628+ @wrap
1629+ def wrapped_class_method(cls, val: int) -> int:
1630+ assert cls is T
1631+ return 3
1632+
1633+ @classmethod
1634+ @get_decorator()
1635+ async def wrapped_class_method_async(cls, val: int) -> int:
1636+ assert cls is T
16021637 return 3
16031638
16041639def is_coroutine(fn):
@@ -1653,38 +1688,50 @@ def test_method() -> None:
16531688 t = T()
16541689 # Call through variable to make sure the call is through vectorcall and not optimized to a native call.
16551690 f: Any = t.returns_one_async
1656- assert asyncio.run(f()) == 1
1691+ assert asyncio.run(f(1 )) == 1
16571692
16581693 assert not is_coroutine(T.returns_two)
16591694 assert is_coroutine(T.returns_two_async)
1660- assert asyncio.run(t.returns_two_async()) == 2
1695+ assert asyncio.run(t.returns_two_async(2 )) == 2
16611696
16621697 assert not is_coroutine(T.static)
16631698 assert is_coroutine(T.static_async)
1664- assert asyncio.run(T.static_async()) == 2
1699+ assert asyncio.run(T.static_async(3)) == 2
1700+ assert not is_coroutine(T.wrapped_static)
1701+ assert is_coroutine(T.wrapped_static_async)
1702+ assert T.wrapped_static(3) == 4
1703+ assert t.wrapped_static(3) == 4
1704+ assert asyncio.run(T.wrapped_static_async(3)) == 4
1705+ assert asyncio.run(t.wrapped_static_async(3)) == 4
16651706
16661707 assert not is_coroutine(T.class_method)
16671708 assert is_coroutine(T.class_method_async)
1668- assert asyncio.run(T.class_method_async()) == 3
1709+ assert asyncio.run(T.class_method_async(4)) == 3
1710+ assert not is_coroutine(T.wrapped_class_method)
1711+ assert is_coroutine(T.wrapped_class_method_async)
1712+ assert T.wrapped_class_method(4) == 6
1713+ assert t.wrapped_class_method(4) == 6
1714+ assert asyncio.run(T.wrapped_class_method_async(4)) == 3
1715+ assert asyncio.run(t.wrapped_class_method_async(4)) == 3
16691716
16701717def test_nested() -> None:
1671- def nested() -> int:
1718+ def nested(val: int ) -> int:
16721719 return 1
16731720
1674- async def nested_async() -> int:
1721+ async def nested_async(val: int ) -> int:
16751722 return 1
16761723
16771724 @wrap
1678- def nested_wrapped() -> int:
1725+ def nested_wrapped(val: int ) -> int:
16791726 return 2
16801727
16811728 @wrap
1682- async def nested_wrapped_async() -> int:
1729+ async def nested_wrapped_async(val: int ) -> int:
16831730 return 2
16841731
16851732 assert not is_coroutine(nested)
16861733 assert is_coroutine(nested_async)
1687- assert asyncio.run(nested_async()) == 1
1734+ assert asyncio.run(nested_async(1 )) == 1
16881735
16891736 assert getattr(nested_async, "__name__") == "nested_async", getattr(nested_async, "__name__")
16901737 setattr(nested_async, "__name__", "some custom name")
@@ -1696,7 +1743,7 @@ def test_nested() -> None:
16961743
16971744 assert not is_coroutine(nested_wrapped)
16981745 assert is_coroutine(nested_wrapped_async)
1699- assert asyncio.run(nested_wrapped_async()) == 4
1746+ assert asyncio.run(nested_wrapped_async(2 )) == 4
17001747
17011748def test_async_function_wrapper_code_refcount() -> None:
17021749 if is_gil_disabled():
@@ -1729,6 +1776,102 @@ def test_nested_async_function_wrapper_code_refcount() -> None:
17291776 assert before == after + 1, (before, after)
17301777 assert after == 1, after
17311778
1779+ [file driver.py]
1780+ import asyncio
1781+ import sys
1782+ import weakref
1783+
1784+ import native
1785+
1786+ def test_function() -> None:
1787+ native.identity_async.__name__ = "identity_async"
1788+ native.wrapped_async.__name__ = "wrapped_async"
1789+
1790+ assert not native.is_coroutine(native.identity)
1791+ assert native.is_coroutine(native.identity_async)
1792+ assert str(native.identity_async).startswith("<function identity_async"), str(native.identity_async)
1793+ assert asyncio.run(native.identity_async(42)) == 42
1794+
1795+ wr = weakref.ref(native.identity_async)
1796+ f = wr()
1797+ assert f
1798+ assert asyncio.run(f(43)) == 43
1799+
1800+ assert getattr(native.identity_async, "__name__") == "identity_async"
1801+ assert getattr(native.identity_async, "__code__") is not None
1802+ assert getattr(native.identity_async, "__defaults__") is None
1803+ assert getattr(native.identity_async, "__kwdefaults__") is None
1804+ assert getattr(native.identity_async, "__annotations__") is None
1805+
1806+ assert not native.is_coroutine(native.wrapped)
1807+ assert native.is_coroutine(native.wrapped_async)
1808+ assert asyncio.run(native.wrapped_async(22)) == 44
1809+
1810+ assert getattr(native.wrapped, "__name__") == "wrapped"
1811+ assert getattr(native.wrapped2, "__name__") == "wrapped2"
1812+ assert getattr(native.wrapped_async, "__name__") == "wrapped_async"
1813+ assert getattr(native.wrapped2_async, "__name__") == "wrapped2_async"
1814+
1815+ def test_method() -> None:
1816+ assert not native.is_coroutine(native.T.returns_one)
1817+ assert native.is_coroutine(native.T.returns_one_async)
1818+ assert str(native.T.returns_one_async).startswith("<function T.returns_one_async")
1819+
1820+ t = native.T()
1821+ f = t.returns_one_async
1822+ assert asyncio.run(f(1)) == 1
1823+
1824+ assert not native.is_coroutine(native.T.returns_two)
1825+ assert native.is_coroutine(native.T.returns_two_async)
1826+ assert asyncio.run(t.returns_two_async(2)) == 2
1827+
1828+ assert not native.is_coroutine(native.T.static)
1829+ assert native.is_coroutine(native.T.static_async)
1830+ assert asyncio.run(native.T.static_async(3)) == 2
1831+ assert asyncio.run(t.static_async(3)) == 2
1832+ assert not native.is_coroutine(native.T.wrapped_static)
1833+ assert native.is_coroutine(native.T.wrapped_static_async)
1834+ assert native.T.wrapped_static(3) == 4
1835+ assert t.wrapped_static(3) == 4
1836+ assert asyncio.run(native.T.wrapped_static_async(3)) == 4
1837+ assert asyncio.run(t.wrapped_static_async(3)) == 4
1838+
1839+ assert not native.is_coroutine(native.T.class_method)
1840+ assert native.is_coroutine(native.T.class_method_async)
1841+ assert asyncio.run(native.T.class_method_async(4)) == 3
1842+ assert asyncio.run(t.class_method_async(4)) == 3
1843+ assert not native.is_coroutine(native.T.wrapped_class_method)
1844+ assert native.is_coroutine(native.T.wrapped_class_method_async)
1845+ assert native.T.wrapped_class_method(4) == 6
1846+ assert t.wrapped_class_method(4) == 6
1847+ assert asyncio.run(native.T.wrapped_class_method_async(4)) == 3
1848+ assert asyncio.run(t.wrapped_class_method_async(4)) == 3
1849+
1850+ def test_nested() -> None:
1851+ def nested(val: int) -> int:
1852+ return 1
1853+
1854+ async def nested_async(val: int) -> int:
1855+ return 1
1856+
1857+ nested_wrapped = native.wrap(nested)
1858+ nested_wrapped_async = native.wrap(nested_async)
1859+
1860+ assert not native.is_coroutine(nested_wrapped)
1861+ assert native.is_coroutine(nested_wrapped_async)
1862+ assert nested_wrapped(1) == 2
1863+ assert asyncio.run(nested_wrapped_async(2)) == 2
1864+
1865+ native.test_function()
1866+ native.test_method()
1867+ native.test_nested()
1868+ native.test_async_function_wrapper_code_refcount()
1869+ native.test_nested_async_function_wrapper_code_refcount()
1870+
1871+ test_function()
1872+ test_nested()
1873+ test_method()
1874+
17321875[file asyncio/__init__.pyi]
17331876def run(x: object) -> object: ...
17341877
0 commit comments