mirror of
https://github.com/hwchase17/langchain
synced 2024-11-04 06:00:26 +00:00
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:
parent
52f4ad8216
commit
1703fe2361
@ -108,6 +108,14 @@ def beta(
|
||||
emit_warning()
|
||||
return wrapped(*args, **kwargs)
|
||||
|
||||
async def awarning_emitting_wrapper(*args: Any, **kwargs: Any) -> Any:
|
||||
"""Same as warning_emitting_wrapper, but for async functions."""
|
||||
nonlocal warned
|
||||
if not warned and not is_caller_internal():
|
||||
warned = True
|
||||
emit_warning()
|
||||
return await wrapped(*args, **kwargs)
|
||||
|
||||
if isinstance(obj, type):
|
||||
if not _obj_type:
|
||||
_obj_type = "class"
|
||||
@ -217,7 +225,10 @@ def beta(
|
||||
f" {details}"
|
||||
)
|
||||
|
||||
return finalize(warning_emitting_wrapper, new_doc)
|
||||
if inspect.iscoroutinefunction(obj):
|
||||
return finalize(awarning_emitting_wrapper, new_doc)
|
||||
else:
|
||||
return finalize(warning_emitting_wrapper, new_doc)
|
||||
|
||||
return beta
|
||||
|
||||
|
@ -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."""
|
||||
|
Loading…
Reference in New Issue
Block a user