Compare commits

...

4 Commits

Author SHA1 Message Date
Eugene Yurtsev
910d4d00a7 x 2023-09-27 16:18:12 -04:00
Eugene Yurtsev
4cef01adf7 x 2023-09-27 16:11:00 -04:00
Eugene Yurtsev
6b945c3091 x 2023-09-27 16:10:22 -04:00
Eugene Yurtsev
17a383d31f x 2023-09-27 15:55:48 -04:00
6 changed files with 127 additions and 85 deletions

View File

@@ -4,6 +4,8 @@ import warnings
from importlib import metadata
from typing import TYPE_CHECKING, Any, Optional
from langchain._api.deprecation import surface_langchain_deprecation_warnings
if TYPE_CHECKING:
from langchain.schema import BaseCache
@@ -26,6 +28,10 @@ def _warn_on_import(name: str) -> None:
)
# Surfaces Deprecation and Pending Deprecation warnings from langchain.
surface_langchain_deprecation_warnings()
def __getattr__(name: str) -> Any:
if name == "MRKLChain":
from langchain.agents import MRKLChain

View File

@@ -13,10 +13,14 @@ from .deprecation import (
LangChainDeprecationWarning,
deprecated,
suppress_langchain_deprecation_warning,
surface_langchain_deprecation_warnings,
warn_deprecated,
)
__all__ = [
"deprecated",
"LangChainDeprecationWarning",
"suppress_langchain_deprecation_warning",
"surface_langchain_deprecation_warnings",
"warn_deprecated",
]

View File

@@ -21,84 +21,8 @@ class LangChainDeprecationWarning(DeprecationWarning):
"""A class for issuing deprecation warnings for LangChain users."""
def _warn_deprecated(
since: str,
*,
message: str = "",
name: str = "",
alternative: str = "",
pending: bool = False,
obj_type: str = "",
addendum: str = "",
removal: str = "",
) -> None:
"""Display a standardized deprecation.
Arguments:
since : str
The release at which this API became deprecated.
message : str, optional
Override the default deprecation message. The %(since)s,
%(name)s, %(alternative)s, %(obj_type)s, %(addendum)s,
and %(removal)s format specifiers will be replaced by the
values of the respective arguments passed to this function.
name : str, optional
The name of the deprecated object.
alternative : str, optional
An alternative API that the user may use in place of the
deprecated API. The deprecation warning will tell the user
about this alternative if provided.
pending : bool, optional
If True, uses a PendingDeprecationWarning instead of a
DeprecationWarning. Cannot be used together with removal.
obj_type : str, optional
The object type being deprecated.
addendum : str, optional
Additional text appended directly to the final message.
removal : str, optional
The expected removal version. With the default (an empty
string), a removal version is automatically computed from
since. Set to other Falsy values to not schedule a removal
date. Cannot be used together with pending.
"""
if pending and removal:
raise ValueError("A pending deprecation cannot have a scheduled removal")
if not pending:
if not removal:
removal = f"in {removal}" if removal else "within ?? minor releases"
raise NotImplementedError(
f"Need to determine which default deprecation schedule to use. "
f"{removal}"
)
else:
removal = f"in {removal}"
if not message:
message = ""
if obj_type:
message += f"The {obj_type} `{name}`"
else:
message += f"`{name}`"
if pending:
message += " will be deprecated in a future version"
else:
message += f" was deprecated in LangChain {since}"
if removal:
message += f" and will be removed {removal}"
if alternative:
message += f". Use {alternative} instead."
if addendum:
message += f" {addendum}"
warning_cls = PendingDeprecationWarning if pending else LangChainDeprecationWarning
warning = warning_cls(message)
warnings.warn(warning, category=LangChainDeprecationWarning, stacklevel=2)
class LangChainPendingDeprecationWarning(PendingDeprecationWarning):
"""A class for issuing deprecation warnings for LangChain users."""
# PUBLIC API
@@ -262,7 +186,7 @@ def deprecated(
def emit_warning() -> None:
"""Emit the warning."""
_warn_deprecated(
warn_deprecated(
since,
message=_message,
name=_name,
@@ -318,4 +242,100 @@ def suppress_langchain_deprecation_warning() -> Generator[None, None, None]:
"""Context manager to suppress LangChainDeprecationWarning."""
with warnings.catch_warnings():
warnings.simplefilter("ignore", LangChainDeprecationWarning)
warnings.simplefilter("ignore", LangChainPendingDeprecationWarning)
yield
def warn_deprecated(
since: str,
*,
message: str = "",
name: str = "",
alternative: str = "",
pending: bool = False,
obj_type: str = "",
addendum: str = "",
removal: str = "",
) -> None:
"""Display a standardized deprecation.
Arguments:
since : str
The release at which this API became deprecated.
message : str, optional
Override the default deprecation message. The %(since)s,
%(name)s, %(alternative)s, %(obj_type)s, %(addendum)s,
and %(removal)s format specifiers will be replaced by the
values of the respective arguments passed to this function.
name : str, optional
The name of the deprecated object.
alternative : str, optional
An alternative API that the user may use in place of the
deprecated API. The deprecation warning will tell the user
about this alternative if provided.
pending : bool, optional
If True, uses a PendingDeprecationWarning instead of a
DeprecationWarning. Cannot be used together with removal.
obj_type : str, optional
The object type being deprecated.
addendum : str, optional
Additional text appended directly to the final message.
removal : str, optional
The expected removal version. With the default (an empty
string), a removal version is automatically computed from
since. Set to other Falsy values to not schedule a removal
date. Cannot be used together with pending.
"""
if pending and removal:
raise ValueError("A pending deprecation cannot have a scheduled removal")
if not pending:
if not removal:
removal = f"in {removal}" if removal else "within ?? minor releases"
raise NotImplementedError(
f"Need to determine which default deprecation schedule to use. "
f"{removal}"
)
else:
removal = f"in {removal}"
if not message:
message = ""
if obj_type:
message += f"The {obj_type} `{name}`"
else:
message += f"`{name}`"
if pending:
message += " will be deprecated in a future version"
else:
message += f" was deprecated in LangChain {since}"
if removal:
message += f" and will be removed {removal}"
if alternative:
message += f". Use {alternative} instead."
if addendum:
message += f" {addendum}"
warning_cls = (
LangChainPendingDeprecationWarning if pending else LangChainDeprecationWarning
)
warning = warning_cls(message)
warnings.warn(warning, category=LangChainDeprecationWarning, stacklevel=2)
def surface_langchain_deprecation_warnings() -> None:
"""Unmute LangChain deprecation warnings."""
warnings.filterwarnings(
"default",
category=LangChainPendingDeprecationWarning,
)
warnings.filterwarnings(
"default",
category=LangChainDeprecationWarning,
)

View File

@@ -2,3 +2,13 @@
Heavily borrowed from llm_math, wrapper for SymPy
"""
from langchain._api import warn_deprecated
warn_deprecated(
since="0.0.304",
message=(
"On 2023-10-06 this module will be moved to langchain-experimental as "
"it relies on sympify https://github.com/sympy/sympy/issues/10805"
),
pending=True,
)

View File

@@ -74,12 +74,14 @@ class WebBaseLoader(BaseLoader):
"Received web_path and web_paths. Only one can be specified. "
"web_path is deprecated, web_paths should be used."
)
if web_paths:
self.web_paths = list(web_paths)
if isinstance(web_path, str):
self.web_paths = [web_path]
elif isinstance(web_path, Sequence):
self.web_paths = list(web_path)
else:
self.web_paths = [web_path]
raise TypeError(
f"web_path must be str or Sequence[str], not {type(web_path)}"
)
self.requests_per_second = requests_per_second
self.default_parser = default_parser
self.requests_kwargs = requests_kwargs or {}

View File

@@ -3,7 +3,7 @@ from typing import Any, Dict
import pytest
from langchain._api.deprecation import _warn_deprecated, deprecated
from langchain._api.deprecation import deprecated, warn_deprecated
from langchain.pydantic_v1 import BaseModel
@@ -55,7 +55,7 @@ def test_warn_deprecated(kwargs: Dict[str, Any], expected_message: str) -> None:
with warnings.catch_warnings(record=True) as warning_list:
warnings.simplefilter("always")
_warn_deprecated(**kwargs)
warn_deprecated(**kwargs)
assert len(warning_list) == 1
warning = warning_list[0].message
@@ -65,7 +65,7 @@ def test_warn_deprecated(kwargs: Dict[str, Any], expected_message: str) -> None:
def test_undefined_deprecation_schedule() -> None:
"""This test is expected to fail until we defined a deprecation schedule."""
with pytest.raises(NotImplementedError):
_warn_deprecated("1.0.0", pending=False)
warn_deprecated("1.0.0", pending=False)
@deprecated(since="2.0.0", removal="3.0.0", pending=False)