mirror of
https://github.com/hwchase17/langchain.git
synced 2025-07-10 15:06:18 +00:00
standard-tests: Ruff autofixes (#31862)
Auto-fixes from ruff with rule ALL
This commit is contained in:
parent
2df3fdf40d
commit
9368b92b2c
@ -1,5 +1,4 @@
|
|||||||
"""
|
"""Base Test classes for standard testing.
|
||||||
Base Test classes for standard testing.
|
|
||||||
|
|
||||||
To learn how to use these classes, see the
|
To learn how to use these classes, see the
|
||||||
`Integration standard testing <https://python.langchain.com/docs/contributing/how_to/integrations/standard_tests/>`_
|
`Integration standard testing <https://python.langchain.com/docs/contributing/how_to/integrations/standard_tests/>`_
|
||||||
|
@ -2,13 +2,10 @@ from abc import ABC
|
|||||||
|
|
||||||
|
|
||||||
class BaseStandardTests(ABC):
|
class BaseStandardTests(ABC):
|
||||||
"""
|
""":private:"""
|
||||||
:private:
|
|
||||||
"""
|
|
||||||
|
|
||||||
def test_no_overrides_DO_NOT_OVERRIDE(self) -> None:
|
def test_no_overrides_DO_NOT_OVERRIDE(self) -> None:
|
||||||
"""
|
"""Test that no standard tests are overridden.
|
||||||
Test that no standard tests are overridden.
|
|
||||||
|
|
||||||
:private:
|
:private:
|
||||||
"""
|
"""
|
||||||
@ -22,10 +19,11 @@ class BaseStandardTests(ABC):
|
|||||||
if comparison_class is None:
|
if comparison_class is None:
|
||||||
comparison_class = base
|
comparison_class = base
|
||||||
else:
|
else:
|
||||||
raise ValueError(
|
msg = (
|
||||||
"Multiple standard test base classes found: "
|
"Multiple standard test base classes found: "
|
||||||
f"{comparison_class}, {base}"
|
f"{comparison_class}, {base}"
|
||||||
)
|
)
|
||||||
|
raise ValueError(msg)
|
||||||
else:
|
else:
|
||||||
explore_bases(base)
|
explore_bases(base)
|
||||||
|
|
||||||
@ -34,12 +32,10 @@ class BaseStandardTests(ABC):
|
|||||||
|
|
||||||
print(f"Comparing {self.__class__} to {comparison_class}") # noqa: T201
|
print(f"Comparing {self.__class__} to {comparison_class}") # noqa: T201
|
||||||
|
|
||||||
running_tests = set(
|
running_tests = {method for method in dir(self) if method.startswith("test_")}
|
||||||
[method for method in dir(self) if method.startswith("test_")]
|
base_tests = {
|
||||||
)
|
method for method in dir(comparison_class) if method.startswith("test_")
|
||||||
base_tests = set(
|
}
|
||||||
[method for method in dir(comparison_class) if method.startswith("test_")]
|
|
||||||
)
|
|
||||||
deleted_tests = base_tests - running_tests
|
deleted_tests = base_tests - running_tests
|
||||||
assert not deleted_tests, f"Standard tests deleted: {deleted_tests}"
|
assert not deleted_tests, f"Standard tests deleted: {deleted_tests}"
|
||||||
|
|
||||||
|
@ -52,9 +52,8 @@ class CustomPersister:
|
|||||||
# If cassette path is already Path this is a no-op
|
# If cassette path is already Path this is a no-op
|
||||||
cassette_path = Path(cassette_path)
|
cassette_path = Path(cassette_path)
|
||||||
if not cassette_path.is_file():
|
if not cassette_path.is_file():
|
||||||
raise CassetteNotFoundError(
|
msg = f"Cassette file {cassette_path} does not exist."
|
||||||
f"Cassette file {cassette_path} does not exist."
|
raise CassetteNotFoundError(msg)
|
||||||
)
|
|
||||||
with cassette_path.open(mode="rb") as f:
|
with cassette_path.open(mode="rb") as f:
|
||||||
data = f.read()
|
data = f.read()
|
||||||
deser = serializer.deserialize(data)
|
deser = serializer.deserialize(data)
|
||||||
|
@ -26,13 +26,13 @@ from .tools import ToolsIntegrationTests
|
|||||||
from .vectorstores import VectorStoreIntegrationTests
|
from .vectorstores import VectorStoreIntegrationTests
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"ChatModelIntegrationTests",
|
"AsyncCacheTestSuite",
|
||||||
"EmbeddingsIntegrationTests",
|
|
||||||
"ToolsIntegrationTests",
|
|
||||||
"BaseStoreAsyncTests",
|
"BaseStoreAsyncTests",
|
||||||
"BaseStoreSyncTests",
|
"BaseStoreSyncTests",
|
||||||
"AsyncCacheTestSuite",
|
"ChatModelIntegrationTests",
|
||||||
"SyncCacheTestSuite",
|
"EmbeddingsIntegrationTests",
|
||||||
"VectorStoreIntegrationTests",
|
|
||||||
"RetrieversIntegrationTests",
|
"RetrieversIntegrationTests",
|
||||||
|
"SyncCacheTestSuite",
|
||||||
|
"ToolsIntegrationTests",
|
||||||
|
"VectorStoreIntegrationTests",
|
||||||
]
|
]
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
"""
|
"""Standard tests for the BaseStore abstraction.
|
||||||
Standard tests for the BaseStore abstraction
|
|
||||||
|
|
||||||
We don't recommend implementing externally managed BaseStore abstractions at this time.
|
We don't recommend implementing externally managed BaseStore abstractions at this time.
|
||||||
|
|
||||||
@ -38,10 +37,9 @@ class BaseStoreSyncTests(BaseStandardTests, Generic[V]):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@pytest.fixture()
|
@pytest.fixture
|
||||||
def three_values(self) -> tuple[V, V, V]:
|
def three_values(self) -> tuple[V, V, V]:
|
||||||
"""Three example values that will be used in the tests."""
|
"""Three example values that will be used in the tests."""
|
||||||
pass
|
|
||||||
|
|
||||||
def test_three_values(self, three_values: tuple[V, V, V]) -> None:
|
def test_three_values(self, three_values: tuple[V, V, V]) -> None:
|
||||||
"""Test that the fixture provides three values."""
|
"""Test that the fixture provides three values."""
|
||||||
@ -169,10 +167,9 @@ class BaseStoreAsyncTests(BaseStandardTests, Generic[V]):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@pytest.fixture()
|
@pytest.fixture
|
||||||
def three_values(self) -> tuple[V, V, V]:
|
def three_values(self) -> tuple[V, V, V]:
|
||||||
"""Three example values that will be used in the tests."""
|
"""Three example values that will be used in the tests."""
|
||||||
pass
|
|
||||||
|
|
||||||
async def test_three_values(self, three_values: tuple[V, V, V]) -> None:
|
async def test_three_values(self, three_values: tuple[V, V, V]) -> None:
|
||||||
"""Test that the fixture provides three values."""
|
"""Test that the fixture provides three values."""
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
"""
|
"""Standard tests for the BaseCache abstraction.
|
||||||
Standard tests for the BaseCache abstraction
|
|
||||||
|
|
||||||
We don't recommend implementing externally managed BaseCache abstractions at this time.
|
We don't recommend implementing externally managed BaseCache abstractions at this time.
|
||||||
|
|
||||||
|
@ -41,9 +41,7 @@ from langchain_tests.utils.pydantic import PYDANTIC_MAJOR_VERSION
|
|||||||
def _get_joke_class(
|
def _get_joke_class(
|
||||||
schema_type: Literal["pydantic", "typeddict", "json_schema"],
|
schema_type: Literal["pydantic", "typeddict", "json_schema"],
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""
|
""":private:"""
|
||||||
:private:
|
|
||||||
"""
|
|
||||||
|
|
||||||
class Joke(BaseModel):
|
class Joke(BaseModel):
|
||||||
"""Joke to tell user."""
|
"""Joke to tell user."""
|
||||||
@ -61,18 +59,18 @@ def _get_joke_class(
|
|||||||
punchline: Annotated[str, ..., "answer to resolve the joke"]
|
punchline: Annotated[str, ..., "answer to resolve the joke"]
|
||||||
|
|
||||||
def validate_joke_dict(result: Any) -> bool:
|
def validate_joke_dict(result: Any) -> bool:
|
||||||
return all(key in ["setup", "punchline"] for key in result.keys())
|
return all(key in ["setup", "punchline"] for key in result)
|
||||||
|
|
||||||
if schema_type == "pydantic":
|
if schema_type == "pydantic":
|
||||||
return Joke, validate_joke
|
return Joke, validate_joke
|
||||||
|
|
||||||
elif schema_type == "typeddict":
|
if schema_type == "typeddict":
|
||||||
return JokeDict, validate_joke_dict
|
return JokeDict, validate_joke_dict
|
||||||
|
|
||||||
elif schema_type == "json_schema":
|
if schema_type == "json_schema":
|
||||||
return Joke.model_json_schema(), validate_joke_dict
|
return Joke.model_json_schema(), validate_joke_dict
|
||||||
else:
|
msg = "Invalid schema type"
|
||||||
raise ValueError("Invalid schema type")
|
raise ValueError(msg)
|
||||||
|
|
||||||
|
|
||||||
class _TestCallbackHandler(BaseCallbackHandler):
|
class _TestCallbackHandler(BaseCallbackHandler):
|
||||||
@ -879,8 +877,7 @@ class ChatModelIntegrationTests(ChatModelTests):
|
|||||||
assert len(result.content) > 0
|
assert len(result.content) > 0
|
||||||
|
|
||||||
def test_double_messages_conversation(self, model: BaseChatModel) -> None:
|
def test_double_messages_conversation(self, model: BaseChatModel) -> None:
|
||||||
"""
|
"""Test to verify that the model can handle double-message conversations.
|
||||||
Test to verify that the model can handle double-message conversations.
|
|
||||||
|
|
||||||
This should pass for all integrations. Tests the model's ability to process
|
This should pass for all integrations. Tests the model's ability to process
|
||||||
a sequence of double-system, double-human, and double-ai messages as context
|
a sequence of double-system, double-human, and double-ai messages as context
|
||||||
@ -1083,7 +1080,8 @@ class ChatModelIntegrationTests(ChatModelTests):
|
|||||||
assert usage_metadata.get("input_tokens", 0) >= total_detailed_tokens
|
assert usage_metadata.get("input_tokens", 0) >= total_detailed_tokens
|
||||||
|
|
||||||
def test_usage_metadata_streaming(self, model: BaseChatModel) -> None:
|
def test_usage_metadata_streaming(self, model: BaseChatModel) -> None:
|
||||||
"""
|
"""Test usage metadata in streaming mode.
|
||||||
|
|
||||||
Test to verify that the model returns correct usage metadata in streaming mode.
|
Test to verify that the model returns correct usage metadata in streaming mode.
|
||||||
|
|
||||||
.. versionchanged:: 0.3.17
|
.. versionchanged:: 0.3.17
|
||||||
@ -1193,7 +1191,7 @@ class ChatModelIntegrationTests(ChatModelTests):
|
|||||||
"Only one chunk should set input_tokens,"
|
"Only one chunk should set input_tokens,"
|
||||||
" the rest should be 0 or None"
|
" the rest should be 0 or None"
|
||||||
)
|
)
|
||||||
full = chunk if full is None else cast(AIMessageChunk, full + chunk)
|
full = chunk if full is None else cast("AIMessageChunk", full + chunk)
|
||||||
|
|
||||||
assert isinstance(full, AIMessageChunk)
|
assert isinstance(full, AIMessageChunk)
|
||||||
assert full.usage_metadata is not None
|
assert full.usage_metadata is not None
|
||||||
@ -1261,7 +1259,7 @@ class ChatModelIntegrationTests(ChatModelTests):
|
|||||||
run_manager: Optional[CallbackManagerForLLMRun] = None,
|
run_manager: Optional[CallbackManagerForLLMRun] = None,
|
||||||
**kwargs: Any,
|
**kwargs: Any,
|
||||||
) -> ChatResult:
|
) -> ChatResult:
|
||||||
""" # noqa: E501
|
"""
|
||||||
result = model.invoke("hi", stop=["you"])
|
result = model.invoke("hi", stop=["you"])
|
||||||
assert isinstance(result, AIMessage)
|
assert isinstance(result, AIMessage)
|
||||||
|
|
||||||
@ -1315,10 +1313,7 @@ class ChatModelIntegrationTests(ChatModelTests):
|
|||||||
"""
|
"""
|
||||||
if not self.has_tool_calling:
|
if not self.has_tool_calling:
|
||||||
pytest.skip("Test requires tool calling.")
|
pytest.skip("Test requires tool calling.")
|
||||||
if not self.has_tool_choice:
|
tool_choice_value = None if not self.has_tool_choice else "any"
|
||||||
tool_choice_value = None
|
|
||||||
else:
|
|
||||||
tool_choice_value = "any"
|
|
||||||
# Emit warning if tool_choice_value property is overridden
|
# Emit warning if tool_choice_value property is overridden
|
||||||
if inspect.getattr_static(
|
if inspect.getattr_static(
|
||||||
self, "tool_choice_value"
|
self, "tool_choice_value"
|
||||||
@ -1391,10 +1386,7 @@ class ChatModelIntegrationTests(ChatModelTests):
|
|||||||
"""
|
"""
|
||||||
if not self.has_tool_calling:
|
if not self.has_tool_calling:
|
||||||
pytest.skip("Test requires tool calling.")
|
pytest.skip("Test requires tool calling.")
|
||||||
if not self.has_tool_choice:
|
tool_choice_value = None if not self.has_tool_choice else "any"
|
||||||
tool_choice_value = None
|
|
||||||
else:
|
|
||||||
tool_choice_value = "any"
|
|
||||||
model_with_tools = model.bind_tools(
|
model_with_tools = model.bind_tools(
|
||||||
[magic_function], tool_choice=tool_choice_value
|
[magic_function], tool_choice=tool_choice_value
|
||||||
)
|
)
|
||||||
@ -1730,10 +1722,7 @@ class ChatModelIntegrationTests(ChatModelTests):
|
|||||||
""" # noqa: E501
|
""" # noqa: E501
|
||||||
if not self.has_tool_calling:
|
if not self.has_tool_calling:
|
||||||
pytest.skip("Test requires tool calling.")
|
pytest.skip("Test requires tool calling.")
|
||||||
if not self.has_tool_choice:
|
tool_choice_value = None if not self.has_tool_choice else "any"
|
||||||
tool_choice_value = None
|
|
||||||
else:
|
|
||||||
tool_choice_value = "any"
|
|
||||||
model_with_tools = model.bind_tools(
|
model_with_tools = model.bind_tools(
|
||||||
[magic_function_no_args], tool_choice=tool_choice_value
|
[magic_function_no_args], tool_choice=tool_choice_value
|
||||||
)
|
)
|
||||||
@ -1856,14 +1845,15 @@ class ChatModelIntegrationTests(ChatModelTests):
|
|||||||
@pytest.mark.xfail(reason=("Not implemented."))
|
@pytest.mark.xfail(reason=("Not implemented."))
|
||||||
def test_structured_few_shot_examples(self, *args: Any) -> None:
|
def test_structured_few_shot_examples(self, *args: Any) -> None:
|
||||||
super().test_structured_few_shot_examples(*args)
|
super().test_structured_few_shot_examples(*args)
|
||||||
""" # noqa: E501
|
"""
|
||||||
if not self.has_tool_calling:
|
if not self.has_tool_calling:
|
||||||
pytest.skip("Test requires tool calling.")
|
pytest.skip("Test requires tool calling.")
|
||||||
model_with_tools = model.bind_tools([my_adder_tool], tool_choice="any")
|
model_with_tools = model.bind_tools([my_adder_tool], tool_choice="any")
|
||||||
function_result = json.dumps({"result": 3})
|
function_result = json.dumps({"result": 3})
|
||||||
|
|
||||||
tool_schema = my_adder_tool.args_schema
|
tool_schema = my_adder_tool.args_schema
|
||||||
assert isinstance(tool_schema, type) and issubclass(tool_schema, BaseModel)
|
assert isinstance(tool_schema, type)
|
||||||
|
assert issubclass(tool_schema, BaseModel)
|
||||||
few_shot_messages = tool_example_to_messages(
|
few_shot_messages = tool_example_to_messages(
|
||||||
"What is 1 + 2",
|
"What is 1 + 2",
|
||||||
[tool_schema(a=1, b=2)],
|
[tool_schema(a=1, b=2)],
|
||||||
@ -1871,7 +1861,7 @@ class ChatModelIntegrationTests(ChatModelTests):
|
|||||||
ai_response=function_result,
|
ai_response=function_result,
|
||||||
)
|
)
|
||||||
|
|
||||||
messages = few_shot_messages + [HumanMessage("What is 3 + 4")]
|
messages = [*few_shot_messages, HumanMessage("What is 3 + 4")]
|
||||||
result = model_with_tools.invoke(messages)
|
result = model_with_tools.invoke(messages)
|
||||||
assert isinstance(result, AIMessage)
|
assert isinstance(result, AIMessage)
|
||||||
|
|
||||||
@ -1905,7 +1895,7 @@ class ChatModelIntegrationTests(ChatModelTests):
|
|||||||
most formats: https://python.langchain.com/api_reference/core/utils/langchain_core.utils.function_calling.convert_to_openai_tool.html
|
most formats: https://python.langchain.com/api_reference/core/utils/langchain_core.utils.function_calling.convert_to_openai_tool.html
|
||||||
|
|
||||||
See example implementation of ``with_structured_output`` here: https://python.langchain.com/api_reference/_modules/langchain_openai/chat_models/base.html#BaseChatOpenAI.with_structured_output
|
See example implementation of ``with_structured_output`` here: https://python.langchain.com/api_reference/_modules/langchain_openai/chat_models/base.html#BaseChatOpenAI.with_structured_output
|
||||||
""" # noqa: E501
|
"""
|
||||||
if not self.has_structured_output:
|
if not self.has_structured_output:
|
||||||
pytest.skip("Test requires structured output.")
|
pytest.skip("Test requires structured output.")
|
||||||
|
|
||||||
@ -1983,7 +1973,7 @@ class ChatModelIntegrationTests(ChatModelTests):
|
|||||||
most formats: https://python.langchain.com/api_reference/core/utils/langchain_core.utils.function_calling.convert_to_openai_tool.html
|
most formats: https://python.langchain.com/api_reference/core/utils/langchain_core.utils.function_calling.convert_to_openai_tool.html
|
||||||
|
|
||||||
See example implementation of ``with_structured_output`` here: https://python.langchain.com/api_reference/_modules/langchain_openai/chat_models/base.html#BaseChatOpenAI.with_structured_output
|
See example implementation of ``with_structured_output`` here: https://python.langchain.com/api_reference/_modules/langchain_openai/chat_models/base.html#BaseChatOpenAI.with_structured_output
|
||||||
""" # noqa: E501
|
"""
|
||||||
if not self.has_structured_output:
|
if not self.has_structured_output:
|
||||||
pytest.skip("Test requires structured output.")
|
pytest.skip("Test requires structured output.")
|
||||||
|
|
||||||
@ -2163,7 +2153,7 @@ class ChatModelIntegrationTests(ChatModelTests):
|
|||||||
assert isinstance(result, dict)
|
assert isinstance(result, dict)
|
||||||
|
|
||||||
def test_json_mode(self, model: BaseChatModel) -> None:
|
def test_json_mode(self, model: BaseChatModel) -> None:
|
||||||
"""Test structured output via `JSON mode. <https://python.langchain.com/docs/concepts/structured_outputs/#json-mode>`_
|
"""Test structured output via `JSON mode. <https://python.langchain.com/docs/concepts/structured_outputs/#json-mode>`_.
|
||||||
|
|
||||||
This test is optional and should be skipped if the model does not support
|
This test is optional and should be skipped if the model does not support
|
||||||
the JSON mode feature (see Configuration below).
|
the JSON mode feature (see Configuration below).
|
||||||
@ -2183,7 +2173,7 @@ class ChatModelIntegrationTests(ChatModelTests):
|
|||||||
.. dropdown:: Troubleshooting
|
.. dropdown:: Troubleshooting
|
||||||
|
|
||||||
See example implementation of ``with_structured_output`` here: https://python.langchain.com/api_reference/_modules/langchain_openai/chat_models/base.html#BaseChatOpenAI.with_structured_output
|
See example implementation of ``with_structured_output`` here: https://python.langchain.com/api_reference/_modules/langchain_openai/chat_models/base.html#BaseChatOpenAI.with_structured_output
|
||||||
""" # noqa: E501
|
"""
|
||||||
if not self.supports_json_mode:
|
if not self.supports_json_mode:
|
||||||
pytest.skip("Test requires json mode support.")
|
pytest.skip("Test requires json mode support.")
|
||||||
|
|
||||||
@ -2893,20 +2883,20 @@ class ChatModelIntegrationTests(ChatModelTests):
|
|||||||
|
|
||||||
def invoke_with_audio_input(self, *, stream: bool = False) -> AIMessage:
|
def invoke_with_audio_input(self, *, stream: bool = False) -> AIMessage:
|
||||||
""":private:"""
|
""":private:"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError
|
||||||
|
|
||||||
def invoke_with_audio_output(self, *, stream: bool = False) -> AIMessage:
|
def invoke_with_audio_output(self, *, stream: bool = False) -> AIMessage:
|
||||||
""":private:"""
|
""":private:"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError
|
||||||
|
|
||||||
def invoke_with_reasoning_output(self, *, stream: bool = False) -> AIMessage:
|
def invoke_with_reasoning_output(self, *, stream: bool = False) -> AIMessage:
|
||||||
""":private:"""
|
""":private:"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError
|
||||||
|
|
||||||
def invoke_with_cache_read_input(self, *, stream: bool = False) -> AIMessage:
|
def invoke_with_cache_read_input(self, *, stream: bool = False) -> AIMessage:
|
||||||
""":private:"""
|
""":private:"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError
|
||||||
|
|
||||||
def invoke_with_cache_creation_input(self, *, stream: bool = False) -> AIMessage:
|
def invoke_with_cache_creation_input(self, *, stream: bool = False) -> AIMessage:
|
||||||
""":private:"""
|
""":private:"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError
|
||||||
|
@ -31,7 +31,7 @@ class DocumentIndexerTestSuite(ABC):
|
|||||||
"""Get the index."""
|
"""Get the index."""
|
||||||
|
|
||||||
def test_upsert_documents_has_no_ids(self, index: DocumentIndex) -> None:
|
def test_upsert_documents_has_no_ids(self, index: DocumentIndex) -> None:
|
||||||
"""Verify that there is not parameter called ids in upsert"""
|
"""Verify that there is not parameter called ids in upsert."""
|
||||||
signature = inspect.signature(index.upsert)
|
signature = inspect.signature(index.upsert)
|
||||||
assert "ids" not in signature.parameters
|
assert "ids" not in signature.parameters
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ class DocumentIndexerTestSuite(ABC):
|
|||||||
]
|
]
|
||||||
response = index.upsert(documents)
|
response = index.upsert(documents)
|
||||||
ids = response["succeeded"]
|
ids = response["succeeded"]
|
||||||
other_id = list(set(ids) - {foo_uuid})[0]
|
other_id = next(iter(set(ids) - {foo_uuid}))
|
||||||
assert response["failed"] == []
|
assert response["failed"] == []
|
||||||
assert foo_uuid in ids
|
assert foo_uuid in ids
|
||||||
# Ordering is not guaranteed, so we use a set.
|
# Ordering is not guaranteed, so we use a set.
|
||||||
@ -221,7 +221,7 @@ class AsyncDocumentIndexTestSuite(ABC):
|
|||||||
"""Get the index."""
|
"""Get the index."""
|
||||||
|
|
||||||
async def test_upsert_documents_has_no_ids(self, index: DocumentIndex) -> None:
|
async def test_upsert_documents_has_no_ids(self, index: DocumentIndex) -> None:
|
||||||
"""Verify that there is not parameter called ids in upsert"""
|
"""Verify that there is not parameter called ids in upsert."""
|
||||||
signature = inspect.signature(index.upsert)
|
signature = inspect.signature(index.upsert)
|
||||||
assert "ids" not in signature.parameters
|
assert "ids" not in signature.parameters
|
||||||
|
|
||||||
@ -265,7 +265,7 @@ class AsyncDocumentIndexTestSuite(ABC):
|
|||||||
]
|
]
|
||||||
response = await index.aupsert(documents)
|
response = await index.aupsert(documents)
|
||||||
ids = response["succeeded"]
|
ids = response["succeeded"]
|
||||||
other_id = list(set(ids) - {foo_uuid})[0]
|
other_id = next(iter(set(ids) - {foo_uuid}))
|
||||||
assert response["failed"] == []
|
assert response["failed"] == []
|
||||||
assert foo_uuid in ids
|
assert foo_uuid in ids
|
||||||
# Ordering is not guaranteed, so we use a set.
|
# Ordering is not guaranteed, so we use a set.
|
||||||
|
@ -8,43 +8,32 @@ from langchain_tests.base import BaseStandardTests
|
|||||||
|
|
||||||
|
|
||||||
class RetrieversIntegrationTests(BaseStandardTests):
|
class RetrieversIntegrationTests(BaseStandardTests):
|
||||||
"""
|
"""Base class for retrievers integration tests."""
|
||||||
Base class for retrievers integration tests.
|
|
||||||
"""
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def retriever_constructor(self) -> type[BaseRetriever]:
|
def retriever_constructor(self) -> type[BaseRetriever]:
|
||||||
"""
|
"""A BaseRetriever subclass to be tested."""
|
||||||
A BaseRetriever subclass to be tested.
|
|
||||||
"""
|
|
||||||
...
|
...
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def retriever_constructor_params(self) -> dict:
|
def retriever_constructor_params(self) -> dict:
|
||||||
"""
|
"""Returns a dictionary of parameters to pass to the retriever constructor."""
|
||||||
Returns a dictionary of parameters to pass to the retriever constructor.
|
|
||||||
"""
|
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def retriever_query_example(self) -> str:
|
def retriever_query_example(self) -> str:
|
||||||
"""
|
"""Returns a str representing the "query" of an example retriever call."""
|
||||||
Returns a str representing the "query" of an example retriever call.
|
|
||||||
"""
|
|
||||||
...
|
...
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def retriever(self) -> BaseRetriever:
|
def retriever(self) -> BaseRetriever:
|
||||||
"""
|
""":private:"""
|
||||||
:private:
|
|
||||||
"""
|
|
||||||
return self.retriever_constructor(**self.retriever_constructor_params)
|
return self.retriever_constructor(**self.retriever_constructor_params)
|
||||||
|
|
||||||
def test_k_constructor_param(self) -> None:
|
def test_k_constructor_param(self) -> None:
|
||||||
"""
|
"""Test that the retriever constructor accepts a k parameter, representing
|
||||||
Test that the retriever constructor accepts a k parameter, representing
|
|
||||||
the number of documents to return.
|
the number of documents to return.
|
||||||
|
|
||||||
.. dropdown:: Troubleshooting
|
.. dropdown:: Troubleshooting
|
||||||
@ -77,8 +66,7 @@ class RetrieversIntegrationTests(BaseStandardTests):
|
|||||||
assert all(isinstance(doc, Document) for doc in result_1)
|
assert all(isinstance(doc, Document) for doc in result_1)
|
||||||
|
|
||||||
def test_invoke_with_k_kwarg(self, retriever: BaseRetriever) -> None:
|
def test_invoke_with_k_kwarg(self, retriever: BaseRetriever) -> None:
|
||||||
"""
|
"""Test that the invoke method accepts a k parameter, representing the number of
|
||||||
Test that the invoke method accepts a k parameter, representing the number of
|
|
||||||
documents to return.
|
documents to return.
|
||||||
|
|
||||||
.. dropdown:: Troubleshooting
|
.. dropdown:: Troubleshooting
|
||||||
@ -104,8 +92,7 @@ class RetrieversIntegrationTests(BaseStandardTests):
|
|||||||
assert all(isinstance(doc, Document) for doc in result_3)
|
assert all(isinstance(doc, Document) for doc in result_3)
|
||||||
|
|
||||||
def test_invoke_returns_documents(self, retriever: BaseRetriever) -> None:
|
def test_invoke_returns_documents(self, retriever: BaseRetriever) -> None:
|
||||||
"""
|
"""If invoked with the example params, the retriever should return a list of
|
||||||
If invoked with the example params, the retriever should return a list of
|
|
||||||
Documents.
|
Documents.
|
||||||
|
|
||||||
.. dropdown:: Troubleshooting
|
.. dropdown:: Troubleshooting
|
||||||
@ -120,8 +107,7 @@ class RetrieversIntegrationTests(BaseStandardTests):
|
|||||||
assert all(isinstance(doc, Document) for doc in result)
|
assert all(isinstance(doc, Document) for doc in result)
|
||||||
|
|
||||||
async def test_ainvoke_returns_documents(self, retriever: BaseRetriever) -> None:
|
async def test_ainvoke_returns_documents(self, retriever: BaseRetriever) -> None:
|
||||||
"""
|
"""If ainvoked with the example params, the retriever should return a list of
|
||||||
If ainvoked with the example params, the retriever should return a list of
|
|
||||||
Documents.
|
Documents.
|
||||||
|
|
||||||
See :meth:`test_invoke_returns_documents` for more information on
|
See :meth:`test_invoke_returns_documents` for more information on
|
||||||
|
@ -5,12 +5,11 @@ from langchain_tests.unit_tests.tools import ToolsTests
|
|||||||
|
|
||||||
|
|
||||||
class ToolsIntegrationTests(ToolsTests):
|
class ToolsIntegrationTests(ToolsTests):
|
||||||
"""
|
"""Base class for tools integration tests."""
|
||||||
Base class for tools integration tests.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def test_invoke_matches_output_schema(self, tool: BaseTool) -> None:
|
def test_invoke_matches_output_schema(self, tool: BaseTool) -> None:
|
||||||
"""
|
"""Test invoke matches output schema.
|
||||||
|
|
||||||
If invoked with a ToolCall, the tool should return a valid ToolMessage content.
|
If invoked with a ToolCall, the tool should return a valid ToolMessage content.
|
||||||
|
|
||||||
If you have followed the `custom tool guide <https://python.langchain.com/docs/how_to/custom_tools/>`_,
|
If you have followed the `custom tool guide <https://python.langchain.com/docs/how_to/custom_tools/>`_,
|
||||||
@ -41,7 +40,8 @@ class ToolsIntegrationTests(ToolsTests):
|
|||||||
assert all(isinstance(c, (str, dict)) for c in tool_message.content)
|
assert all(isinstance(c, (str, dict)) for c in tool_message.content)
|
||||||
|
|
||||||
async def test_async_invoke_matches_output_schema(self, tool: BaseTool) -> None:
|
async def test_async_invoke_matches_output_schema(self, tool: BaseTool) -> None:
|
||||||
"""
|
"""Test async invoke matches output schema.
|
||||||
|
|
||||||
If ainvoked with a ToolCall, the tool should return a valid ToolMessage content.
|
If ainvoked with a ToolCall, the tool should return a valid ToolMessage content.
|
||||||
|
|
||||||
For debugging tips, see :meth:`test_invoke_matches_output_schema`.
|
For debugging tips, see :meth:`test_invoke_matches_output_schema`.
|
||||||
@ -66,9 +66,8 @@ class ToolsIntegrationTests(ToolsTests):
|
|||||||
assert all(isinstance(c, (str, dict)) for c in tool_message.content)
|
assert all(isinstance(c, (str, dict)) for c in tool_message.content)
|
||||||
|
|
||||||
def test_invoke_no_tool_call(self, tool: BaseTool) -> None:
|
def test_invoke_no_tool_call(self, tool: BaseTool) -> None:
|
||||||
"""
|
"""If invoked without a ToolCall, the tool can return anything
|
||||||
If invoked without a ToolCall, the tool can return anything
|
but it shouldn't throw an error.
|
||||||
but it shouldn't throw an error
|
|
||||||
|
|
||||||
If this test fails, your tool may not be handling the input you defined
|
If this test fails, your tool may not be handling the input you defined
|
||||||
in `tool_invoke_params_example` correctly, and it's throwing an error.
|
in `tool_invoke_params_example` correctly, and it's throwing an error.
|
||||||
@ -79,9 +78,8 @@ class ToolsIntegrationTests(ToolsTests):
|
|||||||
tool.invoke(self.tool_invoke_params_example)
|
tool.invoke(self.tool_invoke_params_example)
|
||||||
|
|
||||||
async def test_async_invoke_no_tool_call(self, tool: BaseTool) -> None:
|
async def test_async_invoke_no_tool_call(self, tool: BaseTool) -> None:
|
||||||
"""
|
"""If ainvoked without a ToolCall, the tool can return anything
|
||||||
If ainvoked without a ToolCall, the tool can return anything
|
but it shouldn't throw an error.
|
||||||
but it shouldn't throw an error
|
|
||||||
|
|
||||||
For debugging tips, see :meth:`test_invoke_no_tool_call`.
|
For debugging tips, see :meth:`test_invoke_no_tool_call`.
|
||||||
"""
|
"""
|
||||||
|
@ -105,16 +105,12 @@ class VectorStoreIntegrationTests(BaseStandardTests):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def has_sync(self) -> bool:
|
def has_sync(self) -> bool:
|
||||||
"""
|
"""Configurable property to enable or disable sync tests."""
|
||||||
Configurable property to enable or disable sync tests.
|
|
||||||
"""
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def has_async(self) -> bool:
|
def has_async(self) -> bool:
|
||||||
"""
|
"""Configurable property to enable or disable async tests."""
|
||||||
Configurable property to enable or disable async tests.
|
|
||||||
"""
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -368,7 +364,7 @@ class VectorStoreIntegrationTests(BaseStandardTests):
|
|||||||
@pytest.mark.xfail(reason=("get_by_ids not implemented."))
|
@pytest.mark.xfail(reason=("get_by_ids not implemented."))
|
||||||
def test_get_by_ids_missing(self, vectorstore: VectorStore) -> None:
|
def test_get_by_ids_missing(self, vectorstore: VectorStore) -> None:
|
||||||
super().test_get_by_ids_missing(vectorstore)
|
super().test_get_by_ids_missing(vectorstore)
|
||||||
""" # noqa: E501
|
"""
|
||||||
if not self.has_sync:
|
if not self.has_sync:
|
||||||
pytest.skip("Sync tests not supported.")
|
pytest.skip("Sync tests not supported.")
|
||||||
|
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
"""
|
""":autodoc-options: autoproperty."""
|
||||||
:autodoc-options: autoproperty
|
|
||||||
"""
|
|
||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
import os
|
import os
|
||||||
@ -31,13 +29,13 @@ from langchain_tests.utils.pydantic import PYDANTIC_MAJOR_VERSION
|
|||||||
|
|
||||||
|
|
||||||
def generate_schema_pydantic_v1_from_2() -> Any:
|
def generate_schema_pydantic_v1_from_2() -> Any:
|
||||||
"""
|
"""Use to generate a schema from v1 namespace in pydantic 2.
|
||||||
Use to generate a schema from v1 namespace in pydantic 2.
|
|
||||||
|
|
||||||
:private:
|
:private:
|
||||||
"""
|
"""
|
||||||
if PYDANTIC_MAJOR_VERSION != 2:
|
if PYDANTIC_MAJOR_VERSION != 2:
|
||||||
raise AssertionError("This function is only compatible with Pydantic v2.")
|
msg = "This function is only compatible with Pydantic v2."
|
||||||
|
raise AssertionError(msg)
|
||||||
|
|
||||||
class PersonB(BaseModelV1):
|
class PersonB(BaseModelV1):
|
||||||
"""Record attributes of a person."""
|
"""Record attributes of a person."""
|
||||||
@ -49,8 +47,7 @@ def generate_schema_pydantic_v1_from_2() -> Any:
|
|||||||
|
|
||||||
|
|
||||||
def generate_schema_pydantic() -> Any:
|
def generate_schema_pydantic() -> Any:
|
||||||
"""
|
"""Works with either pydantic 1 or 2.
|
||||||
Works with either pydantic 1 or 2
|
|
||||||
|
|
||||||
:private:
|
:private:
|
||||||
"""
|
"""
|
||||||
@ -74,7 +71,7 @@ class ChatModelTests(BaseStandardTests):
|
|||||||
"""Base class for chat model tests.
|
"""Base class for chat model tests.
|
||||||
|
|
||||||
:private:
|
:private:
|
||||||
""" # noqa: E501
|
"""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@ -158,13 +155,15 @@ class ChatModelTests(BaseStandardTests):
|
|||||||
@property
|
@property
|
||||||
def supports_image_inputs(self) -> bool:
|
def supports_image_inputs(self) -> bool:
|
||||||
"""(bool) whether the chat model supports image inputs, defaults to
|
"""(bool) whether the chat model supports image inputs, defaults to
|
||||||
``False``."""
|
``False``.
|
||||||
|
"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def supports_image_urls(self) -> bool:
|
def supports_image_urls(self) -> bool:
|
||||||
"""(bool) whether the chat model supports image inputs from URLs, defaults to
|
"""(bool) whether the chat model supports image inputs from URLs, defaults to
|
||||||
``False``."""
|
``False``.
|
||||||
|
"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -175,19 +174,22 @@ class ChatModelTests(BaseStandardTests):
|
|||||||
@property
|
@property
|
||||||
def supports_audio_inputs(self) -> bool:
|
def supports_audio_inputs(self) -> bool:
|
||||||
"""(bool) whether the chat model supports audio inputs, defaults to
|
"""(bool) whether the chat model supports audio inputs, defaults to
|
||||||
``False``."""
|
``False``.
|
||||||
|
"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def supports_video_inputs(self) -> bool:
|
def supports_video_inputs(self) -> bool:
|
||||||
"""(bool) whether the chat model supports video inputs, defaults to ``False``.
|
"""(bool) whether the chat model supports video inputs, defaults to ``False``.
|
||||||
No current tests are written for this feature."""
|
No current tests are written for this feature.
|
||||||
|
"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def returns_usage_metadata(self) -> bool:
|
def returns_usage_metadata(self) -> bool:
|
||||||
"""(bool) whether the chat model returns usage metadata on invoke and streaming
|
"""(bool) whether the chat model returns usage metadata on invoke and streaming
|
||||||
responses."""
|
responses.
|
||||||
|
"""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -198,7 +200,8 @@ class ChatModelTests(BaseStandardTests):
|
|||||||
@property
|
@property
|
||||||
def supports_image_tool_message(self) -> bool:
|
def supports_image_tool_message(self) -> bool:
|
||||||
"""(bool) whether the chat model supports ToolMessages that include image
|
"""(bool) whether the chat model supports ToolMessages that include image
|
||||||
content."""
|
content.
|
||||||
|
"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -227,7 +230,8 @@ class ChatModelTests(BaseStandardTests):
|
|||||||
],
|
],
|
||||||
]:
|
]:
|
||||||
"""(dict) what usage metadata details are emitted in invoke and stream. Only
|
"""(dict) what usage metadata details are emitted in invoke and stream. Only
|
||||||
needs to be overridden if these details are returned by the model."""
|
needs to be overridden if these details are returned by the model.
|
||||||
|
"""
|
||||||
return {"invoke": [], "stream": []}
|
return {"invoke": [], "stream": []}
|
||||||
|
|
||||||
|
|
||||||
@ -806,7 +810,8 @@ class ChatModelUnitTests(ChatModelTests):
|
|||||||
@property
|
@property
|
||||||
def init_from_env_params(self) -> tuple[dict, dict, dict]:
|
def init_from_env_params(self) -> tuple[dict, dict, dict]:
|
||||||
"""(tuple) environment variables, additional initialization args, and expected
|
"""(tuple) environment variables, additional initialization args, and expected
|
||||||
instance attributes for testing initialization from environment variables."""
|
instance attributes for testing initialization from environment variables.
|
||||||
|
"""
|
||||||
return {}, {}, {}
|
return {}, {}, {}
|
||||||
|
|
||||||
def test_init(self) -> None:
|
def test_init(self) -> None:
|
||||||
@ -887,7 +892,7 @@ class ChatModelUnitTests(ChatModelTests):
|
|||||||
a utility function that will accommodate most formats: https://python.langchain.com/api_reference/core/utils/langchain_core.utils.function_calling.convert_to_openai_tool.html
|
a utility function that will accommodate most formats: https://python.langchain.com/api_reference/core/utils/langchain_core.utils.function_calling.convert_to_openai_tool.html
|
||||||
|
|
||||||
See example implementation of ``bind_tools`` here: https://python.langchain.com/api_reference/_modules/langchain_openai/chat_models/base.html#BaseChatOpenAI.bind_tools
|
See example implementation of ``bind_tools`` here: https://python.langchain.com/api_reference/_modules/langchain_openai/chat_models/base.html#BaseChatOpenAI.bind_tools
|
||||||
""" # noqa: E501
|
"""
|
||||||
if not self.has_tool_calling:
|
if not self.has_tool_calling:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -927,7 +932,7 @@ class ChatModelUnitTests(ChatModelTests):
|
|||||||
a utility function that will accommodate most formats: https://python.langchain.com/api_reference/core/utils/langchain_core.utils.function_calling.convert_to_openai_tool.html
|
a utility function that will accommodate most formats: https://python.langchain.com/api_reference/core/utils/langchain_core.utils.function_calling.convert_to_openai_tool.html
|
||||||
|
|
||||||
See example implementation of ``with_structured_output`` here: https://python.langchain.com/api_reference/_modules/langchain_openai/chat_models/base.html#BaseChatOpenAI.with_structured_output
|
See example implementation of ``with_structured_output`` here: https://python.langchain.com/api_reference/_modules/langchain_openai/chat_models/base.html#BaseChatOpenAI.with_structured_output
|
||||||
""" # noqa: E501
|
"""
|
||||||
if not self.has_structured_output:
|
if not self.has_structured_output:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -10,9 +10,7 @@ from langchain_tests.base import BaseStandardTests
|
|||||||
|
|
||||||
|
|
||||||
class EmbeddingsTests(BaseStandardTests):
|
class EmbeddingsTests(BaseStandardTests):
|
||||||
"""
|
""":private:"""
|
||||||
:private:
|
|
||||||
"""
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@ -88,7 +86,7 @@ class EmbeddingsUnitTests(EmbeddingsTests):
|
|||||||
"my_api_key": "api_key",
|
"my_api_key": "api_key",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
""" # noqa: E501
|
"""
|
||||||
|
|
||||||
def test_init(self) -> None:
|
def test_init(self) -> None:
|
||||||
"""Test model initialization.
|
"""Test model initialization.
|
||||||
@ -106,7 +104,8 @@ class EmbeddingsUnitTests(EmbeddingsTests):
|
|||||||
"""This property is used in unit tests to test initialization from environment
|
"""This property is used in unit tests to test initialization from environment
|
||||||
variables. It should return a tuple of three dictionaries that specify the
|
variables. It should return a tuple of three dictionaries that specify the
|
||||||
environment variables, additional initialization args, and expected instance
|
environment variables, additional initialization args, and expected instance
|
||||||
attributes to check."""
|
attributes to check.
|
||||||
|
"""
|
||||||
return {}, {}, {}
|
return {}, {}, {}
|
||||||
|
|
||||||
def test_init_from_env(self) -> None:
|
def test_init_from_env(self) -> None:
|
||||||
|
@ -11,8 +11,7 @@ from langchain_tests.base import BaseStandardTests
|
|||||||
|
|
||||||
|
|
||||||
class ToolsTests(BaseStandardTests):
|
class ToolsTests(BaseStandardTests):
|
||||||
"""
|
""":private:
|
||||||
:private:
|
|
||||||
Base class for testing tools. This won't show in the documentation, but
|
Base class for testing tools. This won't show in the documentation, but
|
||||||
the docstrings will be inherited by subclasses.
|
the docstrings will be inherited by subclasses.
|
||||||
"""
|
"""
|
||||||
@ -20,22 +19,17 @@ class ToolsTests(BaseStandardTests):
|
|||||||
@property
|
@property
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def tool_constructor(self) -> Union[type[BaseTool], BaseTool]:
|
def tool_constructor(self) -> Union[type[BaseTool], BaseTool]:
|
||||||
"""
|
"""Returns a class or instance of a tool to be tested."""
|
||||||
Returns a class or instance of a tool to be tested.
|
|
||||||
"""
|
|
||||||
...
|
...
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tool_constructor_params(self) -> dict:
|
def tool_constructor_params(self) -> dict:
|
||||||
"""
|
"""Returns a dictionary of parameters to pass to the tool constructor."""
|
||||||
Returns a dictionary of parameters to pass to the tool constructor.
|
|
||||||
"""
|
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tool_invoke_params_example(self) -> dict:
|
def tool_invoke_params_example(self) -> dict:
|
||||||
"""
|
"""Returns a dictionary representing the "args" of an example tool call.
|
||||||
Returns a dictionary representing the "args" of an example tool call.
|
|
||||||
|
|
||||||
This should NOT be a ToolCall dict - it should not
|
This should NOT be a ToolCall dict - it should not
|
||||||
have {"name", "id", "args"} keys.
|
have {"name", "id", "args"} keys.
|
||||||
@ -44,9 +38,7 @@ class ToolsTests(BaseStandardTests):
|
|||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def tool(self) -> BaseTool:
|
def tool(self) -> BaseTool:
|
||||||
"""
|
""":private:"""
|
||||||
:private:
|
|
||||||
"""
|
|
||||||
if isinstance(self.tool_constructor, BaseTool):
|
if isinstance(self.tool_constructor, BaseTool):
|
||||||
if self.tool_constructor_params != {}:
|
if self.tool_constructor_params != {}:
|
||||||
msg = (
|
msg = (
|
||||||
@ -59,19 +51,17 @@ class ToolsTests(BaseStandardTests):
|
|||||||
|
|
||||||
|
|
||||||
class ToolsUnitTests(ToolsTests):
|
class ToolsUnitTests(ToolsTests):
|
||||||
"""
|
"""Base class for tools unit tests."""
|
||||||
Base class for tools unit tests.
|
|
||||||
"""
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def init_from_env_params(self) -> tuple[dict, dict, dict]:
|
def init_from_env_params(self) -> tuple[dict, dict, dict]:
|
||||||
"""Return env vars, init args, and expected instance attrs for initializing
|
"""Return env vars, init args, and expected instance attrs for initializing
|
||||||
from env vars."""
|
from env vars.
|
||||||
|
"""
|
||||||
return {}, {}, {}
|
return {}, {}, {}
|
||||||
|
|
||||||
def test_init(self) -> None:
|
def test_init(self) -> None:
|
||||||
"""
|
"""Test that the tool can be initialized with :attr:`tool_constructor` and
|
||||||
Test that the tool can be initialized with :attr:`tool_constructor` and
|
|
||||||
:attr:`tool_constructor_params`. If this fails, check that the
|
:attr:`tool_constructor_params`. If this fails, check that the
|
||||||
keyword args defined in :attr:`tool_constructor_params` are valid.
|
keyword args defined in :attr:`tool_constructor_params` are valid.
|
||||||
"""
|
"""
|
||||||
@ -94,16 +84,14 @@ class ToolsUnitTests(ToolsTests):
|
|||||||
assert actual == expected
|
assert actual == expected
|
||||||
|
|
||||||
def test_has_name(self, tool: BaseTool) -> None:
|
def test_has_name(self, tool: BaseTool) -> None:
|
||||||
"""
|
"""Tests that the tool has a name attribute to pass to chat models.
|
||||||
Tests that the tool has a name attribute to pass to chat models.
|
|
||||||
|
|
||||||
If this fails, add a `name` parameter to your tool.
|
If this fails, add a `name` parameter to your tool.
|
||||||
"""
|
"""
|
||||||
assert tool.name
|
assert tool.name
|
||||||
|
|
||||||
def test_has_input_schema(self, tool: BaseTool) -> None:
|
def test_has_input_schema(self, tool: BaseTool) -> None:
|
||||||
"""
|
"""Tests that the tool has an input schema.
|
||||||
Tests that the tool has an input schema.
|
|
||||||
|
|
||||||
If this fails, add an `args_schema` to your tool.
|
If this fails, add an `args_schema` to your tool.
|
||||||
|
|
||||||
@ -115,8 +103,7 @@ class ToolsUnitTests(ToolsTests):
|
|||||||
assert tool.get_input_schema()
|
assert tool.get_input_schema()
|
||||||
|
|
||||||
def test_input_schema_matches_invoke_params(self, tool: BaseTool) -> None:
|
def test_input_schema_matches_invoke_params(self, tool: BaseTool) -> None:
|
||||||
"""
|
"""Tests that the provided example params match the declared input schema.
|
||||||
Tests that the provided example params match the declared input schema.
|
|
||||||
|
|
||||||
If this fails, update the `tool_invoke_params_example` attribute to match
|
If this fails, update the `tool_invoke_params_example` attribute to match
|
||||||
the input schema (`args_schema`) of the tool.
|
the input schema (`args_schema`) of the tool.
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
"""
|
"""Utilities for working with pydantic models.
|
||||||
Utilities for working with pydantic models.
|
|
||||||
|
|
||||||
:private:
|
:private:
|
||||||
"""
|
"""
|
||||||
|
@ -4,4 +4,3 @@ import pytest
|
|||||||
@pytest.mark.compile
|
@pytest.mark.compile
|
||||||
def test_placeholder() -> None:
|
def test_placeholder() -> None:
|
||||||
"""Used for compiling integration tests without running any real tests."""
|
"""Used for compiling integration tests without running any real tests."""
|
||||||
pass
|
|
||||||
|
@ -41,8 +41,7 @@ class TestParrotMultiplyToolUnit(ToolsUnitTests):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def tool_invoke_params_example(self) -> dict:
|
def tool_invoke_params_example(self) -> dict:
|
||||||
"""
|
"""Returns a dictionary representing the "args" of an example tool call.
|
||||||
Returns a dictionary representing the "args" of an example tool call.
|
|
||||||
|
|
||||||
This should NOT be a ToolCall dict - i.e. it should not
|
This should NOT be a ToolCall dict - i.e. it should not
|
||||||
have {"name", "id", "args"} keys.
|
have {"name", "id", "args"} keys.
|
||||||
@ -64,8 +63,7 @@ class TestParrotMultiplyToolIntegration(ToolsIntegrationTests):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def tool_invoke_params_example(self) -> dict:
|
def tool_invoke_params_example(self) -> dict:
|
||||||
"""
|
"""Returns a dictionary representing the "args" of an example tool call.
|
||||||
Returns a dictionary representing the "args" of an example tool call.
|
|
||||||
|
|
||||||
This should NOT be a ToolCall dict - i.e. it should not
|
This should NOT be a ToolCall dict - i.e. it should not
|
||||||
have {"name", "id", "args"} keys.
|
have {"name", "id", "args"} keys.
|
||||||
@ -87,8 +85,7 @@ class TestParrotMultiplyArtifactToolIntegration(ToolsIntegrationTests):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def tool_invoke_params_example(self) -> dict:
|
def tool_invoke_params_example(self) -> dict:
|
||||||
"""
|
"""Returns a dictionary representing the "args" of an example tool call.
|
||||||
Returns a dictionary representing the "args" of an example tool call.
|
|
||||||
|
|
||||||
This should NOT be a ToolCall dict - i.e. it should not
|
This should NOT be a ToolCall dict - i.e. it should not
|
||||||
have {"name", "id", "args"} keys.
|
have {"name", "id", "args"} keys.
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
"""
|
"""Test the standard tests on the custom chat model in the docs."""
|
||||||
Test the standard tests on the custom chat model in the docs
|
|
||||||
"""
|
|
||||||
|
|
||||||
from langchain_tests.integration_tests import ChatModelIntegrationTests
|
from langchain_tests.integration_tests import ChatModelIntegrationTests
|
||||||
from langchain_tests.unit_tests import ChatModelUnitTests
|
from langchain_tests.unit_tests import ChatModelUnitTests
|
||||||
|
@ -17,8 +17,7 @@ class TestParrotMultiplyToolUnit(ToolsUnitTests):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def tool_invoke_params_example(self) -> dict:
|
def tool_invoke_params_example(self) -> dict:
|
||||||
"""
|
"""Returns a dictionary representing the "args" of an example tool call.
|
||||||
Returns a dictionary representing the "args" of an example tool call.
|
|
||||||
|
|
||||||
This should NOT be a ToolCall dict - i.e. it should not
|
This should NOT be a ToolCall dict - i.e. it should not
|
||||||
have {"name", "id", "args"} keys.
|
have {"name", "id", "args"} keys.
|
||||||
@ -33,8 +32,7 @@ class TestParrotMultiplyToolIntegration(ToolsIntegrationTests):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def tool_invoke_params_example(self) -> dict:
|
def tool_invoke_params_example(self) -> dict:
|
||||||
"""
|
"""Returns a dictionary representing the "args" of an example tool call.
|
||||||
Returns a dictionary representing the "args" of an example tool call.
|
|
||||||
|
|
||||||
This should NOT be a ToolCall dict - i.e. it should not
|
This should NOT be a ToolCall dict - i.e. it should not
|
||||||
have {"name", "id", "args"} keys.
|
have {"name", "id", "args"} keys.
|
||||||
|
Loading…
Reference in New Issue
Block a user