mirror of
https://github.com/hwchase17/langchain.git
synced 2025-09-08 06:23:20 +00:00
Do not issue beta or deprecation warnings on internal calls (#15641)
This commit is contained in:
@@ -15,6 +15,8 @@ import inspect
|
||||
import warnings
|
||||
from typing import Any, Callable, Generator, Type, TypeVar
|
||||
|
||||
from langchain_core._api.internal import is_caller_internal
|
||||
|
||||
|
||||
class LangChainBetaWarning(DeprecationWarning):
|
||||
"""A class for issuing beta warnings for LangChain users."""
|
||||
@@ -78,6 +80,34 @@ def beta(
|
||||
_addendum: str = addendum,
|
||||
) -> T:
|
||||
"""Implementation of the decorator returned by `beta`."""
|
||||
|
||||
def emit_warning() -> None:
|
||||
"""Emit the warning."""
|
||||
warn_beta(
|
||||
message=_message,
|
||||
name=_name,
|
||||
obj_type=_obj_type,
|
||||
addendum=_addendum,
|
||||
)
|
||||
|
||||
warned = False
|
||||
|
||||
def warning_emitting_wrapper(*args: Any, **kwargs: Any) -> Any:
|
||||
"""Wrapper for the original wrapped callable that emits a warning.
|
||||
|
||||
Args:
|
||||
*args: The positional arguments to the function.
|
||||
**kwargs: The keyword arguments to the function.
|
||||
|
||||
Returns:
|
||||
The return value of the function being wrapped.
|
||||
"""
|
||||
nonlocal warned
|
||||
if not warned and not is_caller_internal():
|
||||
warned = True
|
||||
emit_warning()
|
||||
return wrapped(*args, **kwargs)
|
||||
|
||||
if isinstance(obj, type):
|
||||
if not _obj_type:
|
||||
_obj_type = "class"
|
||||
@@ -85,14 +115,25 @@ def beta(
|
||||
_name = _name or obj.__name__
|
||||
old_doc = obj.__doc__
|
||||
|
||||
def finalize(wrapper: Callable[..., Any], new_doc: str) -> T:
|
||||
def finalize(_: Any, new_doc: str) -> T:
|
||||
"""Finalize the annotation of a class."""
|
||||
try:
|
||||
obj.__doc__ = new_doc
|
||||
except AttributeError: # Can't set on some extension objects.
|
||||
pass
|
||||
|
||||
def warn_if_direct_instance(
|
||||
self: Any, *args: Any, **kwargs: Any
|
||||
) -> Any:
|
||||
"""Warn that the class is in beta."""
|
||||
nonlocal warned
|
||||
if not warned and type(self) is obj and not is_caller_internal():
|
||||
warned = True
|
||||
emit_warning()
|
||||
return wrapped(self, *args, **kwargs)
|
||||
|
||||
obj.__init__ = functools.wraps(obj.__init__)( # type: ignore[misc]
|
||||
wrapper
|
||||
warn_if_direct_instance
|
||||
)
|
||||
return obj
|
||||
|
||||
@@ -155,28 +196,6 @@ def beta(
|
||||
wrapper.__doc__ = new_doc
|
||||
return wrapper
|
||||
|
||||
def emit_warning() -> None:
|
||||
"""Emit the warning."""
|
||||
warn_beta(
|
||||
message=_message,
|
||||
name=_name,
|
||||
obj_type=_obj_type,
|
||||
addendum=_addendum,
|
||||
)
|
||||
|
||||
def warning_emitting_wrapper(*args: Any, **kwargs: Any) -> Any:
|
||||
"""Wrapper for the original wrapped callable that emits a warning.
|
||||
|
||||
Args:
|
||||
*args: The positional arguments to the function.
|
||||
**kwargs: The keyword arguments to the function.
|
||||
|
||||
Returns:
|
||||
The return value of the function being wrapped.
|
||||
"""
|
||||
emit_warning()
|
||||
return wrapped(*args, **kwargs)
|
||||
|
||||
old_doc = inspect.cleandoc(old_doc or "").strip("\n")
|
||||
|
||||
if not old_doc:
|
||||
|
@@ -16,6 +16,8 @@ import inspect
|
||||
import warnings
|
||||
from typing import Any, Callable, Generator, Type, TypeVar
|
||||
|
||||
from langchain_core._api.internal import is_caller_internal
|
||||
|
||||
|
||||
class LangChainDeprecationWarning(DeprecationWarning):
|
||||
"""A class for issuing deprecation warnings for LangChain users."""
|
||||
@@ -107,6 +109,38 @@ def deprecated(
|
||||
_addendum: str = addendum,
|
||||
) -> T:
|
||||
"""Implementation of the decorator returned by `deprecated`."""
|
||||
|
||||
def emit_warning() -> None:
|
||||
"""Emit the warning."""
|
||||
warn_deprecated(
|
||||
since,
|
||||
message=_message,
|
||||
name=_name,
|
||||
alternative=_alternative,
|
||||
pending=_pending,
|
||||
obj_type=_obj_type,
|
||||
addendum=_addendum,
|
||||
removal=removal,
|
||||
)
|
||||
|
||||
warned = False
|
||||
|
||||
def warning_emitting_wrapper(*args: Any, **kwargs: Any) -> Any:
|
||||
"""Wrapper for the original wrapped callable that emits a warning.
|
||||
|
||||
Args:
|
||||
*args: The positional arguments to the function.
|
||||
**kwargs: The keyword arguments to the function.
|
||||
|
||||
Returns:
|
||||
The return value of the function being wrapped.
|
||||
"""
|
||||
nonlocal warned
|
||||
if not warned and not is_caller_internal():
|
||||
warned = True
|
||||
emit_warning()
|
||||
return wrapped(*args, **kwargs)
|
||||
|
||||
if isinstance(obj, type):
|
||||
if not _obj_type:
|
||||
_obj_type = "class"
|
||||
@@ -114,14 +148,25 @@ def deprecated(
|
||||
_name = _name or obj.__name__
|
||||
old_doc = obj.__doc__
|
||||
|
||||
def finalize(wrapper: Callable[..., Any], new_doc: str) -> T:
|
||||
def finalize(_: Any, new_doc: str) -> T:
|
||||
"""Finalize the deprecation of a class."""
|
||||
try:
|
||||
obj.__doc__ = new_doc
|
||||
except AttributeError: # Can't set on some extension objects.
|
||||
pass
|
||||
|
||||
def warn_if_direct_instance(
|
||||
self: Any, *args: Any, **kwargs: Any
|
||||
) -> Any:
|
||||
"""Warn that the class is in beta."""
|
||||
nonlocal warned
|
||||
if not warned and type(self) is obj and not is_caller_internal():
|
||||
warned = True
|
||||
emit_warning()
|
||||
return wrapped(self, *args, **kwargs)
|
||||
|
||||
obj.__init__ = functools.wraps(obj.__init__)( # type: ignore[misc]
|
||||
wrapper
|
||||
warn_if_direct_instance
|
||||
)
|
||||
return obj
|
||||
|
||||
@@ -184,32 +229,6 @@ def deprecated(
|
||||
wrapper.__doc__ = new_doc
|
||||
return wrapper
|
||||
|
||||
def emit_warning() -> None:
|
||||
"""Emit the warning."""
|
||||
warn_deprecated(
|
||||
since,
|
||||
message=_message,
|
||||
name=_name,
|
||||
alternative=_alternative,
|
||||
pending=_pending,
|
||||
obj_type=_obj_type,
|
||||
addendum=_addendum,
|
||||
removal=removal,
|
||||
)
|
||||
|
||||
def warning_emitting_wrapper(*args: Any, **kwargs: Any) -> Any:
|
||||
"""Wrapper for the original wrapped callable that emits a warning.
|
||||
|
||||
Args:
|
||||
*args: The positional arguments to the function.
|
||||
**kwargs: The keyword arguments to the function.
|
||||
|
||||
Returns:
|
||||
The return value of the function being wrapped.
|
||||
"""
|
||||
emit_warning()
|
||||
return wrapped(*args, **kwargs)
|
||||
|
||||
old_doc = inspect.cleandoc(old_doc or "").strip("\n")
|
||||
|
||||
if not old_doc:
|
||||
|
23
libs/core/langchain_core/_api/internal.py
Normal file
23
libs/core/langchain_core/_api/internal.py
Normal file
@@ -0,0 +1,23 @@
|
||||
import inspect
|
||||
|
||||
|
||||
def is_caller_internal(depth: int = 2) -> bool:
|
||||
"""Return whether the caller at `depth` of this function is internal."""
|
||||
try:
|
||||
frame = inspect.currentframe()
|
||||
except AttributeError:
|
||||
return False
|
||||
if frame is None:
|
||||
return False
|
||||
try:
|
||||
for _ in range(depth):
|
||||
frame = frame.f_back
|
||||
if frame is None:
|
||||
return False
|
||||
caller_module = inspect.getmodule(frame)
|
||||
if caller_module is None:
|
||||
return False
|
||||
caller_module_name = caller_module.__name__
|
||||
return caller_module_name.startswith("langchain")
|
||||
finally:
|
||||
del frame
|
@@ -3,7 +3,7 @@ import json
|
||||
import os
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from langchain_core._api import beta, suppress_langchain_beta_warning
|
||||
from langchain_core._api import beta
|
||||
from langchain_core.load.mapping import (
|
||||
OLD_PROMPT_TEMPLATE_FORMATS,
|
||||
SERIALIZABLE_MAPPING,
|
||||
@@ -125,16 +125,6 @@ def loads(
|
||||
return json.loads(text, object_hook=Reviver(secrets_map, valid_namespaces))
|
||||
|
||||
|
||||
def _loads_suppress_warning(
|
||||
text: str,
|
||||
*,
|
||||
secrets_map: Optional[Dict[str, str]] = None,
|
||||
valid_namespaces: Optional[List[str]] = None,
|
||||
) -> Any:
|
||||
with suppress_langchain_beta_warning():
|
||||
return loads(text, secrets_map=secrets_map, valid_namespaces=valid_namespaces)
|
||||
|
||||
|
||||
@beta()
|
||||
def load(
|
||||
obj: Any,
|
||||
@@ -166,13 +156,3 @@ def load(
|
||||
return obj
|
||||
|
||||
return _load(obj)
|
||||
|
||||
|
||||
def _load_suppress_warning(
|
||||
obj: Any,
|
||||
*,
|
||||
secrets_map: Optional[Dict[str, str]] = None,
|
||||
valid_namespaces: Optional[List[str]] = None,
|
||||
) -> Any:
|
||||
with suppress_langchain_beta_warning():
|
||||
return load(obj, secrets_map=secrets_map, valid_namespaces=valid_namespaces)
|
||||
|
@@ -14,7 +14,7 @@ from typing import (
|
||||
)
|
||||
|
||||
from langchain_core.chat_history import BaseChatMessageHistory
|
||||
from langchain_core.load.load import _load_suppress_warning
|
||||
from langchain_core.load.load import load
|
||||
from langchain_core.pydantic_v1 import BaseModel, create_model
|
||||
from langchain_core.runnables.base import Runnable, RunnableBindingBase, RunnableLambda
|
||||
from langchain_core.runnables.config import run_in_executor
|
||||
@@ -337,7 +337,7 @@ class RunnableWithMessageHistory(RunnableBindingBase):
|
||||
hist = config["configurable"]["message_history"]
|
||||
|
||||
# Get the input messages
|
||||
inputs = _load_suppress_warning(run.inputs)
|
||||
inputs = load(run.inputs)
|
||||
input_val = inputs[self.input_messages_key or "input"]
|
||||
input_messages = self._get_input_messages(input_val)
|
||||
|
||||
@@ -348,7 +348,7 @@ class RunnableWithMessageHistory(RunnableBindingBase):
|
||||
input_messages = input_messages[len(historic_messages) :]
|
||||
|
||||
# Get the output messages
|
||||
output_val = _load_suppress_warning(run.outputs)
|
||||
output_val = load(run.outputs)
|
||||
output_messages = self._get_output_messages(output_val)
|
||||
|
||||
for m in input_messages + output_messages:
|
||||
|
@@ -20,7 +20,7 @@ from uuid import UUID
|
||||
import jsonpatch # type: ignore[import]
|
||||
from anyio import create_memory_object_stream
|
||||
|
||||
from langchain_core.load.load import _load_suppress_warning
|
||||
from langchain_core.load.load import load
|
||||
from langchain_core.outputs import ChatGenerationChunk, GenerationChunk
|
||||
from langchain_core.tracers.base import BaseTracer
|
||||
from langchain_core.tracers.schemas import Run
|
||||
@@ -293,7 +293,7 @@ class LogStreamCallbackHandler(BaseTracer):
|
||||
"op": "add",
|
||||
"path": f"/logs/{index}/final_output",
|
||||
# to undo the dumpd done by some runnables / tracer / etc
|
||||
"value": _load_suppress_warning(run.outputs),
|
||||
"value": load(run.outputs),
|
||||
},
|
||||
{
|
||||
"op": "add",
|
||||
|
Reference in New Issue
Block a user