From 97ac1d34d092464ca211605ac93217033169067c Mon Sep 17 00:00:00 2001 From: "open-swe[bot]" <215916821+open-swe[bot]@users.noreply.github.com> Date: Tue, 28 Apr 2026 20:59:00 -0400 Subject: [PATCH] fix(anthropic): guard httpx finalizers (#37064) --- .../langchain_anthropic/_client_utils.py | 10 ++++------ .../tests/unit_tests/test_client_utils.py | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/libs/partners/anthropic/langchain_anthropic/_client_utils.py b/libs/partners/anthropic/langchain_anthropic/_client_utils.py index 55f194f4dbe..8f895ee6832 100644 --- a/libs/partners/anthropic/langchain_anthropic/_client_utils.py +++ b/libs/partners/anthropic/langchain_anthropic/_client_utils.py @@ -22,10 +22,9 @@ class _SyncHttpxClientWrapper(anthropic.DefaultHttpxClient): """Borrowed from anthropic._base_client.""" def __del__(self) -> None: - if self.is_closed: - return - try: + if self.is_closed: + return self.close() except Exception: # noqa: S110 pass @@ -35,10 +34,9 @@ class _AsyncHttpxClientWrapper(anthropic.DefaultAsyncHttpxClient): """Borrowed from anthropic._base_client.""" def __del__(self) -> None: - if self.is_closed: - return - try: + if self.is_closed: + return # TODO(someday): support non asyncio runtimes here asyncio.get_running_loop().create_task(self.aclose()) except Exception: # noqa: S110 diff --git a/libs/partners/anthropic/tests/unit_tests/test_client_utils.py b/libs/partners/anthropic/tests/unit_tests/test_client_utils.py index 50b50ba147d..ce8ec47d891 100644 --- a/libs/partners/anthropic/tests/unit_tests/test_client_utils.py +++ b/libs/partners/anthropic/tests/unit_tests/test_client_utils.py @@ -3,8 +3,10 @@ from __future__ import annotations from langchain_anthropic._client_utils import ( + _AsyncHttpxClientWrapper, _get_default_async_httpx_client, _get_default_httpx_client, + _SyncHttpxClientWrapper, ) @@ -60,3 +62,17 @@ def test_client_proxy_none_value() -> None: # Both should be created successfully with None proxy assert sync_client is not None assert async_client is not None + + +def test_sync_client_wrapper_del_handles_uninitialized_client() -> None: + """Test sync wrapper finalizer handles clients without initialized state.""" + client = _SyncHttpxClientWrapper.__new__(_SyncHttpxClientWrapper) + + client.__del__() + + +async def test_async_client_wrapper_del_handles_uninitialized_client() -> None: + """Test async wrapper finalizer handles clients without initialized state.""" + client = _AsyncHttpxClientWrapper.__new__(_AsyncHttpxClientWrapper) + + client.__del__()