feat(core): add ruff rules D to tests except D1 (#32000)

Docs are not required for tests but when there are docstrings, they
shall be correctly formatted.
See https://docs.astral.sh/ruff/rules/#pydocstyle-d
This commit is contained in:
Christophe Bornet 2025-07-14 16:42:03 +02:00 committed by GitHub
parent 58d4261875
commit d57216c295
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 61 additions and 34 deletions

View File

@ -124,5 +124,5 @@ asyncio_default_fixture_loop_scope = "function"
[tool.ruff.lint.per-file-ignores] [tool.ruff.lint.per-file-ignores]
"langchain_core/utils/mustache.py" = [ "PLW0603",] "langchain_core/utils/mustache.py" = [ "PLW0603",]
"tests/unit_tests/test_tools.py" = [ "ARG",] "tests/unit_tests/test_tools.py" = [ "ARG",]
"tests/**" = [ "D", "S", "SLF",] "tests/**" = [ "D1", "S", "SLF",]
"scripts/**" = [ "INP", "S",] "scripts/**" = [ "INP", "S",]

View File

@ -2,7 +2,9 @@ from langchain_core.embeddings import DeterministicFakeEmbedding
def test_deterministic_fake_embeddings() -> None: def test_deterministic_fake_embeddings() -> None:
"""Test that the deterministic fake embeddings return the same """Test that DeterministicFakeEmbedding is deterministic.
Test that the deterministic fake embeddings return the same
embedding vector for the same text. embedding vector for the same text.
""" """
fake = DeterministicFakeEmbedding(size=10) fake = DeterministicFakeEmbedding(size=10)

View File

@ -905,7 +905,7 @@ async def test_ascoped_full_fails_with_bad_source_ids(
def test_index_empty_doc_scoped_full( def test_index_empty_doc_scoped_full(
record_manager: InMemoryRecordManager, vector_store: InMemoryVectorStore record_manager: InMemoryRecordManager, vector_store: InMemoryVectorStore
) -> None: ) -> None:
"""Test Indexing with scoped_full strategy""" """Test Indexing with scoped_full strategy."""
loader = ToyLoader( loader = ToyLoader(
documents=[ documents=[
Document( Document(
@ -1927,7 +1927,6 @@ def test_incremental_cleanup_with_different_batchsize(
record_manager: InMemoryRecordManager, vector_store: VectorStore record_manager: InMemoryRecordManager, vector_store: VectorStore
) -> None: ) -> None:
"""Check that we can clean up with different batch size.""" """Check that we can clean up with different batch size."""
docs = [ docs = [
Document( Document(
page_content="This is a test document.", page_content="This is a test document.",

View File

@ -99,7 +99,7 @@ async def test_async_batch_size() -> None:
async def test_error_callback() -> None: async def test_error_callback() -> None:
class FailingLLMError(Exception): class FailingLLMError(Exception):
"""FailingLLMError""" """FailingLLMError."""
class FailingLLM(LLM): class FailingLLM(LLM):
@property @property

View File

@ -28,7 +28,9 @@ def test_single_item() -> None:
def test_multiple_items_with_spaces() -> None: def test_multiple_items_with_spaces() -> None:
"""Test that a string with multiple comma-separated items """Test multiple items with spaces.
Test that a string with multiple comma-separated items
with spaces is parsed to a list. with spaces is parsed to a list.
""" """
parser = CommaSeparatedListOutputParser() parser = CommaSeparatedListOutputParser()
@ -66,7 +68,9 @@ def test_multiple_items() -> None:
def test_multiple_items_with_comma() -> None: def test_multiple_items_with_comma() -> None:
"""Test that a string with multiple comma-separated items with 1 item containing a """Test multiple items with a comma.
Test that a string with multiple comma-separated items with 1 item containing a
comma is parsed to a list. comma is parsed to a list.
""" """
parser = CommaSeparatedListOutputParser() parser = CommaSeparatedListOutputParser()

View File

@ -361,8 +361,9 @@ def test_prompt_from_file() -> None:
def test_prompt_from_file_with_partial_variables() -> None: def test_prompt_from_file_with_partial_variables() -> None:
"""Test prompt can be successfully constructed from a file """Test prompt from file with partial variables.
with partial variables.
Test prompt can be successfully constructed from a file with partial variables.
""" """
# given # given
template = "This is a {foo} test {bar}." template = "This is a {foo} test {bar}."

View File

@ -102,6 +102,7 @@ PYDANTIC_VERSION_AT_LEAST_210 = version.parse("2.10") <= PYDANTIC_VERSION
class FakeTracer(BaseTracer): class FakeTracer(BaseTracer):
"""Fake tracer that records LangChain execution. """Fake tracer that records LangChain execution.
It replaces run ids with deterministic UUIDs for snapshotting. It replaces run ids with deterministic UUIDs for snapshotting.
""" """
@ -4867,7 +4868,9 @@ async def test_runnable_gen_async() -> None:
def test_runnable_gen_context_config() -> None: def test_runnable_gen_context_config() -> None:
"""Test that a generator can call other runnables with config """Test generator runnable config propagation.
Test that a generator can call other runnables with config
propagated from the context. propagated from the context.
""" """
fake = RunnableLambda(len) fake = RunnableLambda(len)
@ -4942,9 +4945,11 @@ def test_runnable_gen_context_config() -> None:
"async tasks in a specific context", "async tasks in a specific context",
) )
async def test_runnable_gen_context_config_async() -> None: async def test_runnable_gen_context_config_async() -> None:
"""Test that a generator can call other runnables with config """Test generator runnable config propagation.
propagated from the context."""
Test that a generator can call other runnables with config
propagated from the context.
"""
fake = RunnableLambda(len) fake = RunnableLambda(len)
async def agen(_: AsyncIterator[Any]) -> AsyncIterator[int]: async def agen(_: AsyncIterator[Any]) -> AsyncIterator[int]:
@ -5010,7 +5015,9 @@ async def test_runnable_gen_context_config_async() -> None:
def test_runnable_iter_context_config() -> None: def test_runnable_iter_context_config() -> None:
"""Test that a generator can call other runnables with config """Test generator runnable config propagation.
Test that a generator can call other runnables with config
propagated from the context. propagated from the context.
""" """
fake = RunnableLambda(len) fake = RunnableLambda(len)
@ -5069,9 +5076,11 @@ def test_runnable_iter_context_config() -> None:
"async tasks in a specific context", "async tasks in a specific context",
) )
async def test_runnable_iter_context_config_async() -> None: async def test_runnable_iter_context_config_async() -> None:
"""Test that a generator can call other runnables with config """Test generator runnable config propagation.
propagated from the context."""
Test that a generator can call other runnables with config
propagated from the context.
"""
fake = RunnableLambda(len) fake = RunnableLambda(len)
@chain @chain
@ -5135,7 +5144,9 @@ async def test_runnable_iter_context_config_async() -> None:
def test_runnable_lambda_context_config() -> None: def test_runnable_lambda_context_config() -> None:
"""Test that a function can call other runnables with config """Test function runnable config propagation.
Test that a function can call other runnables with config
propagated from the context. propagated from the context.
""" """
fake = RunnableLambda(len) fake = RunnableLambda(len)
@ -5192,9 +5203,11 @@ def test_runnable_lambda_context_config() -> None:
"async tasks in a specific context", "async tasks in a specific context",
) )
async def test_runnable_lambda_context_config_async() -> None: async def test_runnable_lambda_context_config_async() -> None:
"""Test that a function can call other runnables with config """Test function runnable config propagation.
propagated from the context."""
Test that a function can call other runnables with config
propagated from the context.
"""
fake = RunnableLambda(len) fake = RunnableLambda(len)
@chain @chain
@ -5295,7 +5308,9 @@ def test_with_config_callbacks() -> None:
async def test_ainvoke_on_returned_runnable() -> None: async def test_ainvoke_on_returned_runnable() -> None:
"""Verify that a runnable returned by a sync runnable in the async path will """Test ainvoke on a returned runnable.
Verify that a runnable returned by a sync runnable in the async path will
be runthroughaasync path (issue #13407). be runthroughaasync path (issue #13407).
""" """
@ -5637,7 +5652,9 @@ def test_pydantic_protected_namespaces() -> None:
def test_schema_for_prompt_and_chat_model() -> None: def test_schema_for_prompt_and_chat_model() -> None:
"""Testing that schema is generated properly when using variable names """Test schema generation for prompt and chat model.
Testing that schema is generated properly when using variable names
that collide with pydantic attributes. that collide with pydantic attributes.
""" """
prompt = ChatPromptTemplate([("system", "{model_json_schema}, {_private}, {json}")]) prompt = ChatPromptTemplate([("system", "{model_json_schema}, {_private}, {json}")])

View File

@ -2797,6 +2797,5 @@ async def test_custom_event_root_dispatch_with_in_tool() -> None:
def test_default_is_v2() -> None: def test_default_is_v2() -> None:
"""Test that we default to version="v2".""" """Test that we default to version="v2"."""
signature = inspect.signature(Runnable.astream_events) signature = inspect.signature(Runnable.astream_events)
assert signature.parameters["version"].default == "v2" assert signature.parameters["version"].default == "v2"

View File

@ -940,7 +940,7 @@ def test_tool_message_serdes() -> None:
class BadObject: class BadObject:
"""""" pass
def test_tool_message_ser_non_serializable() -> None: def test_tool_message_ser_non_serializable() -> None:

View File

@ -1,4 +1,6 @@
"""A set of tests that verifies that Union discrimination works correctly with """Test pydantic SerDe.
A set of tests that verifies that Union discrimination works correctly with
the various pydantic base models. the various pydantic base models.
These tests can uncover issues that will also arise during regular instantiation These tests can uncover issues that will also arise during regular instantiation

View File

@ -544,8 +544,9 @@ def test_empty_args_decorator() -> None:
def test_tool_from_function_with_run_manager() -> None: def test_tool_from_function_with_run_manager() -> None:
"""Test run of tool when using run_manager.""" """Test run of tool when using run_manager."""
def foo(bar: str, callbacks: Optional[CallbackManagerForToolRun] = None) -> str: def foo(bar: str, callbacks: Optional[CallbackManagerForToolRun] = None) -> str: # noqa: D417
"""Docstring """Docstring.
Args: Args:
bar: str. bar: str.
""" """
@ -562,7 +563,7 @@ def test_tool_from_function_with_run_manager() -> None:
def test_structured_tool_from_function_with_run_manager() -> None: def test_structured_tool_from_function_with_run_manager() -> None:
"""Test args and schema of structured tool when using callbacks.""" """Test args and schema of structured tool when using callbacks."""
def foo( def foo( # noqa: D417
bar: int, baz: str, callbacks: Optional[CallbackManagerForToolRun] = None bar: int, baz: str, callbacks: Optional[CallbackManagerForToolRun] = None
) -> str: ) -> str:
"""Docstring. """Docstring.
@ -1193,7 +1194,7 @@ def test_tool_arg_descriptions() -> None:
assert args_schema == expected assert args_schema == expected
# Test parsing with run_manager does not raise error # Test parsing with run_manager does not raise error
def foo3( def foo3( # noqa: D417
bar: str, baz: int, run_manager: Optional[CallbackManagerForToolRun] = None bar: str, baz: int, run_manager: Optional[CallbackManagerForToolRun] = None
) -> str: ) -> str:
"""The foo. """The foo.
@ -1310,7 +1311,7 @@ def test_docstring_parsing() -> None:
def test_tool_invalid_docstrings() -> None: def test_tool_invalid_docstrings() -> None:
"""Test invalid docstrings""" """Test invalid docstrings."""
def foo3(bar: str, baz: int) -> str: def foo3(bar: str, baz: int) -> str:
"""The foo.""" """The foo."""
@ -1321,14 +1322,14 @@ def test_tool_invalid_docstrings() -> None:
Args: Args:
bar: The bar. bar: The bar.
baz: The baz. baz: The baz.
""" """ # noqa: D205,D411
return bar return bar
for func in {foo3, foo4}: for func in {foo3, foo4}:
with pytest.raises(ValueError, match="Found invalid Google-Style docstring."): with pytest.raises(ValueError, match="Found invalid Google-Style docstring."):
_ = tool(func, parse_docstring=True) _ = tool(func, parse_docstring=True)
def foo5(bar: str, baz: int) -> str: def foo5(bar: str, baz: int) -> str: # noqa: D417
"""The foo. """The foo.
Args: Args:

View File

@ -121,7 +121,9 @@ class CustomAddDocumentsVectorstore(VectorStore):
"vs_class", [CustomAddTextsVectorstore, CustomAddDocumentsVectorstore] "vs_class", [CustomAddTextsVectorstore, CustomAddDocumentsVectorstore]
) )
def test_default_add_documents(vs_class: type[VectorStore]) -> None: def test_default_add_documents(vs_class: type[VectorStore]) -> None:
"""Test that we can implement the upsert method of the CustomVectorStore """Test default implementation of add_documents.
Test that we can implement the upsert method of the CustomVectorStore
class without violating the Liskov Substitution Principle. class without violating the Liskov Substitution Principle.
""" """
store = vs_class() store = vs_class()

View File

@ -1008,7 +1008,7 @@ dev = [
{ name = "jupyter", specifier = ">=1.0.0,<2.0.0" }, { name = "jupyter", specifier = ">=1.0.0,<2.0.0" },
{ name = "setuptools", specifier = ">=67.6.1,<68.0.0" }, { name = "setuptools", specifier = ">=67.6.1,<68.0.0" },
] ]
lint = [{ name = "ruff", specifier = ">=0.12.2,<0.13.0" }] lint = [{ name = "ruff", specifier = ">=0.12.2,<0.13" }]
test = [ test = [
{ name = "blockbuster", specifier = "~=1.5.18" }, { name = "blockbuster", specifier = "~=1.5.18" },
{ name = "freezegun", specifier = ">=1.2.2,<2.0.0" }, { name = "freezegun", specifier = ">=1.2.2,<2.0.0" },
@ -1072,7 +1072,7 @@ requires-dist = [
[package.metadata.requires-dev] [package.metadata.requires-dev]
codespell = [{ name = "codespell", specifier = ">=2.2.0,<3.0.0" }] codespell = [{ name = "codespell", specifier = ">=2.2.0,<3.0.0" }]
lint = [{ name = "ruff", specifier = ">=0.9.2,<1.0.0" }] lint = [{ name = "ruff", specifier = ">=0.12.2,<0.13" }]
test = [{ name = "langchain-core", editable = "." }] test = [{ name = "langchain-core", editable = "." }]
test-integration = [] test-integration = []
typing = [ typing = [
@ -1098,7 +1098,7 @@ dev = [
] ]
lint = [ lint = [
{ name = "langchain-core", editable = "." }, { name = "langchain-core", editable = "." },
{ name = "ruff", specifier = ">=0.9.2,<1.0.0" }, { name = "ruff", specifier = ">=0.12.2,<0.13" },
] ]
test = [ test = [
{ name = "freezegun", specifier = ">=1.2.2,<2.0.0" }, { name = "freezegun", specifier = ">=1.2.2,<2.0.0" },