1+ import builtins
2+ import importlib
13import sys
4+ from typing import Any
25from unittest .mock import MagicMock , patch
36
47import pytest
58from langchain_core .tools .structured import StructuredTool
69from llama_index .core .tools import FunctionTool
710
811from cleanlab_codex .codex_tool import CodexTool
12+ from cleanlab_codex .utils .errors import MissingDependencyError
13+
14+
15+ def patch_import_with_import_error (missing_module : str ) -> None :
16+ def custom_import (name : str , * args : Any , ** kwargs : Any ) -> Any :
17+ if name .startswith (missing_module ):
18+ raise ImportError ("test" , name = missing_module )
19+ return importlib .__import__ (name , * args , ** kwargs )
20+
21+ builtins .__import__ = custom_import
922
1023
1124def test_to_openai_tool (mock_client_from_access_key : MagicMock ) -> None :
@@ -32,6 +45,20 @@ def test_to_llamaindex_tool(mock_client_from_access_key: MagicMock) -> None:
3245 assert llama_index_tool .fn == tool .query
3346
3447
48+ def test_to_llamaindex_tool_import_error (
49+ mock_client_from_access_key : MagicMock ,
50+ ) -> None :
51+ with patch ("cleanlab_codex.codex_tool.Project" ) as mock_project :
52+ mock_project .from_access_key .return_value = MagicMock (client = mock_client_from_access_key , id = "test_project_id" )
53+
54+ tool = CodexTool .from_access_key ("sk-test-123" )
55+ patch_import_with_import_error ("llama_index" )
56+ with pytest .raises (MissingDependencyError ) as exc_info :
57+ tool .to_llamaindex_tool ()
58+
59+ assert exc_info .value .import_name == "llama_index"
60+
61+
3562def test_to_langchain_tool (mock_client_from_access_key : MagicMock ) -> None :
3663 with patch ("cleanlab_codex.codex_tool.Project" ) as mock_project :
3764 mock_project .from_access_key .return_value = MagicMock (client = mock_client_from_access_key , id = "test_project_id" )
@@ -50,6 +77,18 @@ def test_to_langchain_tool(mock_client_from_access_key: MagicMock) -> None:
5077 ), f"Expected description '{ tool .tool_description } ', got '{ langchain_tool .description } '."
5178
5279
80+ def test_to_langchain_tool_import_error (mock_client_from_access_key : MagicMock ) -> None :
81+ with patch ("cleanlab_codex.codex_tool.Project" ) as mock_project :
82+ mock_project .from_access_key .return_value = MagicMock (client = mock_client_from_access_key , id = "test_project_id" )
83+
84+ tool = CodexTool .from_access_key ("sk-test-123" )
85+ patch_import_with_import_error ("langchain" )
86+ with pytest .raises (MissingDependencyError ) as exc_info :
87+ tool .to_langchain_tool ()
88+
89+ assert exc_info .value .import_name == "langchain"
90+
91+
5392def test_to_aws_converse_tool (mock_client_from_access_key : MagicMock ) -> None :
5493 with patch ("cleanlab_codex.codex_tool.Project" ) as mock_project :
5594 mock_project .from_access_key .return_value = MagicMock (client = mock_client_from_access_key , id = "test_project_id" )
@@ -95,3 +134,21 @@ def test_to_smolagents_tool(mock_client_from_access_key: MagicMock) -> None:
95134 assert isinstance (smolagents_tool , Tool )
96135 assert smolagents_tool .name == tool .tool_name
97136 assert smolagents_tool .description == tool .tool_description
137+
138+
139+ def test_to_smolagents_tool_import_error (
140+ mock_client_from_access_key : MagicMock ,
141+ ) -> None :
142+ with patch ("cleanlab_codex.codex_tool.Project" ) as mock_project :
143+ mock_project .from_access_key .return_value = MagicMock (client = mock_client_from_access_key , id = "test_project_id" )
144+
145+ tool = CodexTool .from_access_key ("sk-test-123" )
146+ import_module_name = "smolagents"
147+ if sys .version_info >= (3 , 10 ):
148+ import_module_name = "cleanlab_codex.utils.smolagents"
149+ patch_import_with_import_error (import_module_name )
150+
151+ with pytest .raises (MissingDependencyError ) as exc_info :
152+ tool .to_smolagents_tool ()
153+
154+ assert exc_info .value .import_name == import_module_name
0 commit comments