core[patch]: preserve inspect.iscoroutinefunction with @beta decorator (#16440)

Adjusted deprecate decorator to make sure decorated async functions are
still recognized as "coroutinefunction" by inspect

Addresses #16402

<!-- Thank you for contributing to LangChain!

Please title your PR "<package>: <description>", where <package> is
whichever of langchain, community, core, experimental, etc. is being
modified.

Replace this entire comment with:
  - **Description:** a description of the change, 
  - **Issue:** the issue # it fixes if applicable,
  - **Dependencies:** any dependencies required for this change,
- **Twitter handle:** we announce bigger features on Twitter. If your PR
gets announced, and you'd like a mention, we'll gladly shout you out!

Please make sure your PR is passing linting and testing before
submitting. Run `make format`, `make lint` and `make test` from the root
of the package you've modified to check this locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc: https://python.langchain.com/docs/contributing/

If you're adding a new integration, please include:
1. a test for the integration, preferably unit tests that do not rely on
network access,
2. an example notebook showing its use. It lives in
`docs/docs/integrations` directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
This commit is contained in:
Yudhajit Sinha
2024-01-30 09:31:11 +05:30
committed by GitHub
parent 52f4ad8216
commit 1703fe2361
2 changed files with 69 additions and 1 deletions

View File

@@ -1,3 +1,4 @@
import inspect
import warnings
from typing import Any, Dict
@@ -57,6 +58,12 @@ def beta_function() -> str:
return "This is a beta function."
@beta()
async def beta_async_function() -> str:
"""original doc"""
return "This is a beta async function."
class ClassWithBetaMethods:
def __init__(self) -> None:
"""original doc"""
@@ -67,6 +74,11 @@ class ClassWithBetaMethods:
"""original doc"""
return "This is a beta method."
@beta()
async def beta_async_method(self) -> str:
"""original doc"""
return "This is a beta async method."
@classmethod
@beta()
def beta_classmethod(cls) -> str:
@@ -102,6 +114,28 @@ def test_beta_function() -> None:
assert isinstance(doc, str)
assert doc.startswith("[*Beta*] original doc")
assert not inspect.iscoroutinefunction(beta_function)
@pytest.mark.asyncio
async def test_beta_async_function() -> None:
"""Test beta async function."""
with warnings.catch_warnings(record=True) as warning_list:
warnings.simplefilter("always")
assert await beta_async_function() == "This is a beta async function."
assert len(warning_list) == 1
warning = warning_list[0].message
assert str(warning) == (
"The function `beta_async_function` is in beta. "
"It is actively being worked on, so the API may change."
)
doc = beta_function.__doc__
assert isinstance(doc, str)
assert doc.startswith("[*Beta*] original doc")
assert inspect.iscoroutinefunction(beta_async_function)
def test_beta_method() -> None:
"""Test beta method."""
@@ -120,6 +154,29 @@ def test_beta_method() -> None:
assert isinstance(doc, str)
assert doc.startswith("[*Beta*] original doc")
assert not inspect.iscoroutinefunction(obj.beta_method)
@pytest.mark.asyncio
async def test_beta_async_method() -> None:
"""Test beta method."""
with warnings.catch_warnings(record=True) as warning_list:
warnings.simplefilter("always")
obj = ClassWithBetaMethods()
assert await obj.beta_async_method() == "This is a beta async method."
assert len(warning_list) == 1
warning = warning_list[0].message
assert str(warning) == (
"The function `beta_async_method` is in beta. "
"It is actively being worked on, so the API may change."
)
doc = obj.beta_method.__doc__
assert isinstance(doc, str)
assert doc.startswith("[*Beta*] original doc")
assert inspect.iscoroutinefunction(obj.beta_async_method)
def test_beta_classmethod() -> None:
"""Test beta classmethod."""