@@ -32,220 +32,6 @@ def tool_module(tool_path):
3232 return "." .join (os .path .splitext (tool_path )[0 ].split (os .sep )[- 2 :])
3333
3434
35- @pytest .mark .parametrize (
36- "tool_path" ,
37- [
38- textwrap .dedent ("""
39- import strands
40-
41- @strands.tools.tool
42- def identity(a: int):
43- return a
44- """ )
45- ],
46- indirect = True ,
47- )
48- def test_load_python_tool_path_function_based (tool_path ):
49- tool = ToolLoader .load_python_tool (tool_path , "identity" )
50-
51- assert isinstance (tool , DecoratedFunctionTool )
52-
53-
54- @pytest .mark .parametrize (
55- "tool_path" ,
56- [
57- textwrap .dedent ("""
58- TOOL_SPEC = {
59- "name": "identity",
60- "description": "identity tool",
61- "inputSchema": {
62- "type": "object",
63- "properties": {
64- "a": {
65- "type": "integer",
66- },
67- },
68- },
69- }
70-
71- def identity(a: int):
72- return a
73- """ )
74- ],
75- indirect = True ,
76- )
77- def test_load_python_tool_path_module_based (tool_path ):
78- tool = ToolLoader .load_python_tool (tool_path , "identity" )
79-
80- assert isinstance (tool , PythonAgentTool )
81-
82-
83- def test_load_python_tool_path_invalid ():
84- with pytest .raises (ImportError , match = "Could not create spec for identity" ):
85- ToolLoader .load_python_tool ("invalid" , "identity" )
86-
87-
88- @pytest .mark .parametrize (
89- "tool_path" ,
90- [
91- textwrap .dedent ("""
92- def no_spec():
93- return
94- """ )
95- ],
96- indirect = True ,
97- )
98- def test_load_python_tool_path_no_spec (tool_path ):
99- with pytest .raises (AttributeError , match = "Tool no_spec missing TOOL_SPEC" ):
100- ToolLoader .load_python_tool (tool_path , "no_spec" )
101-
102-
103- @pytest .mark .parametrize (
104- "tool_path" ,
105- [
106- textwrap .dedent ("""
107- TOOL_SPEC = {"name": "no_function"}
108- """ )
109- ],
110- indirect = True ,
111- )
112- def test_load_python_tool_path_no_function (tool_path ):
113- with pytest .raises (AttributeError , match = "Tool no_function missing function" ):
114- ToolLoader .load_python_tool (tool_path , "no_function" )
115-
116-
117- @pytest .mark .parametrize (
118- "tool_path" ,
119- [
120- textwrap .dedent ("""
121- TOOL_SPEC = {"name": "no_callable"}
122-
123- no_callable = "not callable"
124- """ )
125- ],
126- indirect = True ,
127- )
128- def test_load_python_tool_path_no_callable (tool_path ):
129- with pytest .raises (TypeError , match = "Tool no_callable function is not callable" ):
130- ToolLoader .load_python_tool (tool_path , "no_callable" )
131-
132-
133- @pytest .mark .parametrize (
134- "tool_path" ,
135- [
136- textwrap .dedent ("""
137- import strands
138-
139- @strands.tools.tool
140- def identity(a: int):
141- return a
142- """ )
143- ],
144- indirect = True ,
145- )
146- def test_load_python_tool_dot_function_based (tool_path , tool_module ):
147- _ = tool_path
148- tool_module = f"{ tool_module } :identity"
149-
150- tool = ToolLoader .load_python_tool (tool_module , "identity" )
151-
152- assert isinstance (tool , DecoratedFunctionTool )
153-
154-
155- @pytest .mark .parametrize (
156- "tool_path" ,
157- [
158- textwrap .dedent ("""
159- TOOL_SPEC = {"name": "no_function"}
160- """ )
161- ],
162- indirect = True ,
163- )
164- def test_load_python_tool_dot_no_function (tool_path , tool_module ):
165- _ = tool_path
166-
167- with pytest .raises (AttributeError , match = re .escape (f"Module { tool_module } has no function named no_function" )):
168- ToolLoader .load_python_tool (f"{ tool_module } :no_function" , "no_function" )
169-
170-
171- @pytest .mark .parametrize (
172- "tool_path" ,
173- [
174- textwrap .dedent ("""
175- def no_decorator():
176- return
177- """ )
178- ],
179- indirect = True ,
180- )
181- def test_load_python_tool_dot_no_decorator (tool_path , tool_module ):
182- _ = tool_path
183-
184- with pytest .raises (ValueError , match = re .escape (f"Function no_decorator in { tool_module } is not a valid tool" )):
185- ToolLoader .load_python_tool (f"{ tool_module } :no_decorator" , "no_decorator" )
186-
187-
188- def test_load_python_tool_dot_missing ():
189- with pytest .raises (ImportError , match = "Failed to import module missing" ):
190- ToolLoader .load_python_tool ("missing:function" , "function" )
191-
192-
193- @pytest .mark .parametrize (
194- "tool_path" ,
195- [
196- textwrap .dedent ("""
197- import strands
198-
199- @strands.tools.tool
200- def identity(a: int):
201- return a
202- """ )
203- ],
204- indirect = True ,
205- )
206- def test_load_tool (tool_path ):
207- tool = ToolLoader .load_tool (tool_path , "identity" )
208-
209- assert isinstance (tool , DecoratedFunctionTool )
210-
211-
212- def test_load_tool_missing ():
213- with pytest .raises (FileNotFoundError , match = "Tool file not found" ):
214- ToolLoader .load_tool ("missing" , "function" )
215-
216-
217- def test_load_tool_invalid_ext (tmp_path ):
218- tool_path = tmp_path / "tool.txt"
219- tool_path .touch ()
220-
221- with pytest .raises (ValueError , match = "Unsupported tool file type: .txt" ):
222- ToolLoader .load_tool (str (tool_path ), "function" )
223-
224-
225- @pytest .mark .parametrize (
226- "tool_path" ,
227- [
228- textwrap .dedent ("""
229- def no_spec():
230- return
231- """ )
232- ],
233- indirect = True ,
234- )
235- def test_load_tool_no_spec (tool_path ):
236- with pytest .raises (AttributeError , match = "Tool no_spec missing TOOL_SPEC" ):
237- ToolLoader .load_tool (tool_path , "no_spec" )
238-
239- with pytest .raises (AttributeError , match = "Tool no_spec missing TOOL_SPEC" ):
240- ToolLoader .load_tools (tool_path , "no_spec" )
241-
242- with pytest .raises (AttributeError , match = "Tool no_spec missing TOOL_SPEC" ):
243- ToolLoader .load_python_tool (tool_path , "no_spec" )
244-
245- with pytest .raises (AttributeError , match = "Tool no_spec missing TOOL_SPEC" ):
246- ToolLoader .load_python_tools (tool_path , "no_spec" )
247-
248-
24935@pytest .mark .parametrize (
25036 "tool_path" ,
25137 [
@@ -284,29 +70,3 @@ def test_load_python_tool_path_multiple_function_based(tool_path):
28470 assert names == {"alpha" , "bravo" }
28571
28672
287- @pytest .mark .parametrize (
288- "tool_path" ,
289- [
290- textwrap .dedent (
291- """
292- import strands
293-
294- @strands.tools.tool
295- def alpha():
296- return "alpha"
297-
298- @strands.tools.tool
299- def bravo():
300- return "bravo"
301- """
302- )
303- ],
304- indirect = True ,
305- )
306- def test_load_tool_path_returns_single_tool (tool_path ):
307- # loaded_python_tool and loaded_tool returns single item
308- loaded_python_tool = ToolLoader .load_python_tool (tool_path , "alpha" )
309- loaded_tool = ToolLoader .load_tool (tool_path , "alpha" )
310-
311- assert loaded_python_tool .tool_name == "alpha"
312- assert loaded_tool .tool_name == "alpha"
0 commit comments