From 026de908ebd48b235175be45f55a93b363638c15 Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Mon, 31 Mar 2025 16:05:23 +0200 Subject: [PATCH] core: Add ruff rules G, FA, INP, AIR and ISC (#29334) Fixes mostly for rules G. See https://docs.astral.sh/ruff/rules/#flake8-logging-format-g --- libs/core/langchain_core/callbacks/manager.py | 30 ++++++++++++------- libs/core/langchain_core/tracers/core.py | 5 ++-- .../core/langchain_core/tracers/evaluation.py | 12 ++++---- libs/core/langchain_core/utils/html.py | 4 ++- libs/core/langchain_core/utils/mustache.py | 2 +- libs/core/langchain_core/vectorstores/base.py | 14 +++++---- libs/core/pyproject.toml | 6 ++-- libs/core/tests/unit_tests/caches/__init__.py | 0 .../unit_tests/runnables/test_history.py | 4 +-- .../unit_tests/utils/test_function_calling.py | 2 +- 10 files changed, 47 insertions(+), 32 deletions(-) create mode 100644 libs/core/tests/unit_tests/caches/__init__.py diff --git a/libs/core/langchain_core/callbacks/manager.py b/libs/core/langchain_core/callbacks/manager.py index 62aa8f73d37..d1c534d27c6 100644 --- a/libs/core/langchain_core/callbacks/manager.py +++ b/libs/core/langchain_core/callbacks/manager.py @@ -282,13 +282,17 @@ def handle_event( else: handler_name = handler.__class__.__name__ logger.warning( - f"NotImplementedError in {handler_name}.{event_name}" - f" callback: {repr(e)}" + "NotImplementedError in %s.%s callback: %s", + handler_name, + event_name, + repr(e), ) except Exception as e: logger.warning( - f"Error in {handler.__class__.__name__}.{event_name} callback:" - f" {repr(e)}" + "Error in %s.%s callback: %s", + handler.__class__.__name__, + event_name, + repr(e), ) if handler.raise_error: raise @@ -328,7 +332,7 @@ def _run_coros(coros: list[Coroutine[Any, Any, Any]]) -> None: try: runner.run(coro) except Exception as e: - logger.warning(f"Error in callback coroutine: {repr(e)}") + logger.warning("Error in callback coroutine: %s", repr(e)) # Run pending tasks scheduled by coros until they are all done while pending := asyncio.all_tasks(runner.get_loop()): @@ -340,7 +344,7 @@ def _run_coros(coros: list[Coroutine[Any, Any, Any]]) -> None: try: asyncio.run(coro) except Exception as e: - logger.warning(f"Error in callback coroutine: {repr(e)}") + logger.warning("Error in callback coroutine: %s", repr(e)) async def _ahandle_event_for_handler( @@ -382,12 +386,17 @@ async def _ahandle_event_for_handler( ) else: logger.warning( - f"NotImplementedError in {handler.__class__.__name__}.{event_name}" - f" callback: {repr(e)}" + "NotImplementedError in %s.%s callback: %s", + handler.__class__.__name__, + event_name, + repr(e), ) except Exception as e: logger.warning( - f"Error in {handler.__class__.__name__}.{event_name} callback: {repr(e)}" + "Error in %s.%s callback: %s", + handler.__class__.__name__, + event_name, + repr(e), ) if handler.raise_error: raise @@ -2386,7 +2395,8 @@ def _configure( "Unable to load requested LangChainTracer." " To disable this warning," " unset the LANGCHAIN_TRACING_V2 environment variables.\n" - f"{repr(e)}", + "%s", + repr(e), ) if run_tree is not None: for handler in callback_manager.handlers: diff --git a/libs/core/langchain_core/tracers/core.py b/libs/core/langchain_core/tracers/core.py index 1f6e05dbc61..4e716a89244 100644 --- a/libs/core/langchain_core/tracers/core.py +++ b/libs/core/langchain_core/tracers/core.py @@ -119,8 +119,9 @@ class _TracerCore(ABC): else: if self.log_missing_parent: logger.debug( - f"Parent run {run.parent_run_id} not found for run {run.id}." - " Treating as a root run." + "Parent run %s not found for run %s. Treating as a root run.", + run.parent_run_id, + run.id, ) run.parent_run_id = None run.trace_id = run.id diff --git a/libs/core/langchain_core/tracers/evaluation.py b/libs/core/langchain_core/tracers/evaluation.py index a1e9dac63c6..7771b5b3f23 100644 --- a/libs/core/langchain_core/tracers/evaluation.py +++ b/libs/core/langchain_core/tracers/evaluation.py @@ -134,11 +134,11 @@ class EvaluatorCallbackHandler(BaseTracer): run, source_run_id=cb.latest_run.id if cb.latest_run else None, ) - except Exception as e: - logger.error( - f"Error evaluating run {run.id} with " - f"{evaluator.__class__.__name__}: {repr(e)}", - exc_info=True, + except Exception: + logger.exception( + "Error evaluating run %s with %s", + run.id, + evaluator.__class__.__name__, ) raise example_id = str(run.reference_example_id) @@ -202,7 +202,7 @@ class EvaluatorCallbackHandler(BaseTracer): """ if self.skip_unfinished and not run.outputs: - logger.debug(f"Skipping unfinished run {run.id}") + logger.debug("Skipping unfinished run %s", run.id) return run_ = run.copy() run_.reference_example_id = self.example_id diff --git a/libs/core/langchain_core/utils/html.py b/libs/core/langchain_core/utils/html.py index f54e52024cc..3b7a3b18964 100644 --- a/libs/core/langchain_core/utils/html.py +++ b/libs/core/langchain_core/utils/html.py @@ -95,7 +95,9 @@ def extract_sub_links( absolute_paths.add(absolute_path) except Exception as e: if continue_on_failure: - logger.warning(f"Unable to load link {link}. Raised exception:\n\n{e}") + logger.warning( + "Unable to load link %s. Raised exception:\n\n%s", link, e + ) continue raise diff --git a/libs/core/langchain_core/utils/mustache.py b/libs/core/langchain_core/utils/mustache.py index 6e12964f7b5..2cc2a4a3363 100644 --- a/libs/core/langchain_core/utils/mustache.py +++ b/libs/core/langchain_core/utils/mustache.py @@ -385,7 +385,7 @@ def _get_key( # We couldn't find the key in any of the scopes if warn: - logger.warn(f"Could not find key '{key}'") + logger.warning("Could not find key '%s'", key) if keep: return f"{def_ldel} {key} {def_rdel}" diff --git a/libs/core/langchain_core/vectorstores/base.py b/libs/core/langchain_core/vectorstores/base.py index 1cf1fd529fb..41e14dbed40 100644 --- a/libs/core/langchain_core/vectorstores/base.py +++ b/libs/core/langchain_core/vectorstores/base.py @@ -117,8 +117,8 @@ class VectorStore(ABC): def embeddings(self) -> Optional[Embeddings]: """Access the query embedding object if available.""" logger.debug( - f"The embeddings property has not been " - f"implemented for {self.__class__.__name__}" + "The embeddings property has not been implemented for %s", + self.__class__.__name__, ) return None @@ -573,8 +573,9 @@ class VectorStore(ABC): ] if len(docs_and_similarities) == 0: logger.warning( - "No relevant docs were retrieved using the relevance score" - f" threshold {score_threshold}" + "No relevant docs were retrieved using the " + "relevance score threshold %s", + score_threshold, ) return docs_and_similarities @@ -621,8 +622,9 @@ class VectorStore(ABC): ] if len(docs_and_similarities) == 0: logger.warning( - "No relevant docs were retrieved using the relevance score" - f" threshold {score_threshold}" + "No relevant docs were retrieved using the " + "relevance score threshold %s", + score_threshold, ) return docs_and_similarities diff --git a/libs/core/pyproject.toml b/libs/core/pyproject.toml index 05005e681af..53d9adaf71f 100644 --- a/libs/core/pyproject.toml +++ b/libs/core/pyproject.toml @@ -77,8 +77,8 @@ target-version = "py39" [tool.ruff.lint] -select = [ "ANN", "ASYNC", "B", "C4", "COM", "DJ", "E", "EM", "EXE", "F", "FLY", "FURB", "I", "ICN", "INT", "LOG", "N", "NPY", "PD", "PIE", "PLW", "PTH", "Q", "RSE", "S", "SIM", "SLOT", "T10", "T201", "TC", "TID", "TRY", "UP", "W", "YTT",] -ignore = [ "ANN401", "COM812", "UP007", "S110", "S112", "TC001", "TC002", "TC003"] +select = [ "AIR", "ANN", "ASYNC", "B", "C4", "COM", "DJ", "E", "EM", "EXE", "F", "FA", "FAST", "FLY", "FURB", "G", "I", "ICN", "INP","INT", "ISC", "LOG", "N", "NPY", "PD", "PIE", "PLW", "PTH", "Q", "RSE", "S", "SIM", "SLOT", "T10", "T20", "TC", "TID", "TRY", "UP", "W", "YTT",] +ignore = [ "ANN401", "COM812", "FA100", "ISC001", "S110", "S112", "TC001", "TC002", "TC003", "UP007",] flake8-type-checking.runtime-evaluated-base-classes = ["pydantic.BaseModel","langchain_core.load.serializable.Serializable","langchain_core.runnables.base.RunnableSerializable"] flake8-annotations.allow-star-arg-any = true flake8-annotations.mypy-init-return = true @@ -102,4 +102,4 @@ classmethod-decorators = [ "classmethod", "langchain_core.utils.pydantic.pre_ini "tests/unit_tests/runnables/test_runnable.py" = [ "E501",] "tests/unit_tests/runnables/test_graph.py" = [ "E501",] "tests/**" = [ "S",] -"scripts/**" = [ "S",] +"scripts/**" = [ "INP", "S",] diff --git a/libs/core/tests/unit_tests/caches/__init__.py b/libs/core/tests/unit_tests/caches/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/libs/core/tests/unit_tests/runnables/test_history.py b/libs/core/tests/unit_tests/runnables/test_history.py index 06c63203f89..de709a42a7c 100644 --- a/libs/core/tests/unit_tests/runnables/test_history.py +++ b/libs/core/tests/unit_tests/runnables/test_history.py @@ -862,7 +862,7 @@ def test_get_output_messages_with_value_error() -> None: with_history.bound.invoke([HumanMessage(content="hello")], config) excepted = ( "Expected str, BaseMessage, List[BaseMessage], or Tuple[BaseMessage]." - + (f" Got {illegal_bool_message}.") + f" Got {illegal_bool_message}." ) assert excepted in str(excinfo.value) @@ -874,6 +874,6 @@ def test_get_output_messages_with_value_error() -> None: with_history.bound.invoke([HumanMessage(content="hello")], config) excepted = ( "Expected str, BaseMessage, List[BaseMessage], or Tuple[BaseMessage]." - + (f" Got {illegal_int_message}.") + f" Got {illegal_int_message}." ) assert excepted in str(excinfo.value) diff --git a/libs/core/tests/unit_tests/utils/test_function_calling.py b/libs/core/tests/unit_tests/utils/test_function_calling.py index 03e0625c69a..1c9e952f527 100644 --- a/libs/core/tests/unit_tests/utils/test_function_calling.py +++ b/libs/core/tests/unit_tests/utils/test_function_calling.py @@ -994,7 +994,7 @@ def test__convert_typed_dict_to_openai_function_fail(typed_dict: type) -> None: ) def test_convert_union_type_py_39() -> None: @tool - def magic_function(input: int | float) -> str: + def magic_function(input: int | float) -> str: # noqa: FA102 """Compute a magic function.""" result = convert_to_openai_function(magic_function)