lionagi 0.0.201__py3-none-any.whl → 0.0.204__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. lionagi/_services/anthropic.py +79 -1
  2. lionagi/_services/base_service.py +1 -1
  3. lionagi/_services/services.py +61 -25
  4. lionagi/_services/transformers.py +46 -0
  5. lionagi/agents/__init__.py +0 -0
  6. lionagi/configs/oai_configs.py +1 -1
  7. lionagi/configs/openrouter_configs.py +1 -1
  8. lionagi/core/__init__.py +3 -7
  9. lionagi/core/branch/__init__.py +0 -0
  10. lionagi/core/branch/branch.py +589 -0
  11. lionagi/core/branch/branch_manager.py +139 -0
  12. lionagi/core/branch/cluster.py +1 -0
  13. lionagi/core/branch/conversation.py +484 -0
  14. lionagi/core/core_util.py +59 -0
  15. lionagi/core/flow/__init__.py +0 -0
  16. lionagi/core/flow/flow.py +19 -0
  17. lionagi/core/instruction_set/__init__.py +0 -0
  18. lionagi/core/instruction_set/instruction_set.py +343 -0
  19. lionagi/core/messages/__init__.py +0 -0
  20. lionagi/core/messages/messages.py +176 -0
  21. lionagi/core/sessions/__init__.py +0 -0
  22. lionagi/core/sessions/session.py +428 -0
  23. lionagi/models/__init__.py +0 -0
  24. lionagi/models/base_model.py +0 -0
  25. lionagi/models/imodel.py +53 -0
  26. lionagi/schema/data_logger.py +75 -155
  27. lionagi/tests/test_utils/test_call_util.py +658 -657
  28. lionagi/tools/tool_manager.py +121 -188
  29. lionagi/utils/__init__.py +5 -10
  30. lionagi/utils/call_util.py +667 -585
  31. lionagi/utils/io_util.py +3 -0
  32. lionagi/utils/nested_util.py +17 -211
  33. lionagi/utils/pd_util.py +57 -0
  34. lionagi/utils/sys_util.py +220 -184
  35. lionagi/utils/url_util.py +55 -0
  36. lionagi/version.py +1 -1
  37. {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/METADATA +12 -8
  38. {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/RECORD +47 -32
  39. lionagi/core/branch.py +0 -193
  40. lionagi/core/conversation.py +0 -341
  41. lionagi/core/flow.py +0 -8
  42. lionagi/core/instruction_set.py +0 -150
  43. lionagi/core/messages.py +0 -243
  44. lionagi/core/sessions.py +0 -474
  45. /lionagi/{tools → agents}/planner.py +0 -0
  46. /lionagi/{tools → agents}/prompter.py +0 -0
  47. /lionagi/{tools → agents}/scorer.py +0 -0
  48. /lionagi/{tools → agents}/summarizer.py +0 -0
  49. /lionagi/{tools → agents}/validator.py +0 -0
  50. /lionagi/core/{flow_util.py → flow/flow_util.py} +0 -0
  51. {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/LICENSE +0 -0
  52. {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/WHEEL +0 -0
  53. {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/top_level.txt +0 -0
@@ -1,784 +1,785 @@
1
- import unittest
2
- import asyncio
3
- import time
4
- import lionagi.utils.call_util as call_util
5
- from lionagi.utils.call_util import CallDecorator
6
- from lionagi.utils.call_util import Throttle
1
+ # import unittest
2
+ # import asyncio
3
+ # import time
4
+ # import lionagi.utils.call_util as call_util
5
+ # from lionagi.utils.call_util import CallDecorator
6
+ # from lionagi.utils.call_util import Throttle
7
7
 
8
8
 
9
- class TestToList(unittest.TestCase):
9
+ # class TestToList(unittest.TestCase):
10
10
 
11
- def test_empty_input(self):
12
- self.assertEqual(call_util.to_list([]), [])
11
+ # def test_empty_input(self):
12
+ # self.assertEqual(call_util.to_list([]), [])
13
13
 
14
- def test_single_element(self):
15
- self.assertEqual(call_util.to_list(5), [5])
14
+ # def test_single_element(self):
15
+ # self.assertEqual(call_util.to_list(5), [5])
16
16
 
17
- def test_list_input(self):
18
- self.assertEqual(call_util.to_list([1, [2, 3]], flatten=False), [1, [2, 3]])
17
+ # def test_list_input(self):
18
+ # self.assertEqual(call_util.to_list([1, [2, 3]], flatten=False), [1, [2, 3]])
19
19
 
20
- def test_nested_list(self):
21
- self.assertEqual(call_util.to_list([[1, 2], [3, 4]], flatten=True), [1, 2, 3, 4])
20
+ # def test_nested_list(self):
21
+ # self.assertEqual(call_util.to_list([[1, 2], [3, 4]], flatten=True), [1, 2, 3, 4])
22
22
 
23
- def test_non_list_iterable(self):
24
- self.assertEqual(call_util.to_list((1, 2, 3)), [1, 2, 3])
23
+ # def test_non_list_iterable(self):
24
+ # self.assertEqual(call_util.to_list((1, 2, 3)), [1, 2, 3])
25
25
 
26
- def test_string_handling(self):
27
- self.assertEqual(call_util.to_list("abc"), ["abc"])
26
+ # def test_string_handling(self):
27
+ # self.assertEqual(call_util.to_list("abc"), ["abc"])
28
28
 
29
- def test_drop_none(self):
30
- self.assertEqual(call_util.to_list([1, None, 2], dropna=True), [1, 2])
29
+ # def test_drop_none(self):
30
+ # self.assertEqual(call_util.to_list([1, None, 2], dropna=True), [1, 2])
31
31
 
32
- class FaultyIterable:
33
- """An iterable class that raises an exception when iterated over."""
32
+ # class FaultyIterable:
33
+ # """An iterable class that raises an exception when iterated over."""
34
34
 
35
- def __iter__(self):
36
- return self
35
+ # def __iter__(self):
36
+ # return self
37
37
 
38
- def __next__(self):
39
- raise RuntimeError("Fault during iteration")
38
+ # def __next__(self):
39
+ # raise RuntimeError("Fault during iteration")
40
40
 
41
- def test_invalid_input(self):
42
- with self.assertRaises(ValueError):
43
- call_util.to_list(TestToList.FaultyIterable())
41
+ # def test_invalid_input(self):
42
+ # with self.assertRaises(ValueError):
43
+ # call_util.to_list(TestToList.FaultyIterable())
44
44
 
45
45
 
46
- class TestLCall(unittest.TestCase):
46
+ # class TestLCall(unittest.TestCase):
47
47
 
48
- def test_empty_input(self):
49
- self.assertEqual(call_util.lcall([], lambda x: x*2), [])
48
+ # def test_empty_input(self):
49
+ # self.assertEqual(call_util.lcall([], lambda x: x*2), [])
50
50
 
51
- def test_single_element(self):
52
- self.assertEqual(call_util.lcall(5, lambda x: x*2), [10])
51
+ # def test_single_element(self):
52
+ # self.assertEqual(call_util.lcall(5, lambda x: x*2), [10])
53
53
 
54
- def test_list_input_with_simple_function(self):
55
- self.assertEqual(call_util.lcall([1, 2, 3], lambda x: x*2), [2, 4, 6])
54
+ # def test_list_input_with_simple_function(self):
55
+ # self.assertEqual(call_util.lcall([1, 2, 3], lambda x: x*2), [2, 4, 6])
56
56
 
57
- def test_flatten(self):
58
- self.assertEqual(call_util.lcall([[1, 2], [3, 4]], lambda x: x*2, flatten=True), [2, 4, 6, 8])
57
+ # def test_flatten(self):
58
+ # self.assertEqual(call_util.lcall([[1, 2], [3, 4]], lambda x: x*2, flatten=True), [2, 4, 6, 8])
59
59
 
60
- def test_drop_none(self):
61
- self.assertEqual(call_util.lcall([1, None, 2], lambda x: x, dropna=True), [1, 2])
60
+ # def test_drop_none(self):
61
+ # self.assertEqual(call_util.lcall([1, None, 2], lambda x: x, dropna=True), [1, 2])
62
62
 
63
- def test_with_lambda_function(self):
64
- self.assertEqual(call_util.lcall([1, 2, 3], lambda x: x + 1), [2, 3, 4])
63
+ # def test_with_lambda_function(self):
64
+ # self.assertEqual(call_util.lcall([1, 2, 3], lambda x: x + 1), [2, 3, 4])
65
65
 
66
- def test_exception_handling(self):
67
- def faulty_func(x):
68
- raise ValueError("Faulty Function")
69
- with self.assertRaises(ValueError):
70
- call_util.lcall([1, 2, 3], faulty_func)
66
+ # def test_exception_handling(self):
67
+ # def faulty_func(x):
68
+ # raise ValueError("Faulty Function")
69
+ # with self.assertRaises(ValueError):
70
+ # call_util.lcall([1, 2, 3], faulty_func)
71
71
 
72
- def test_with_additional_arguments(self):
73
- self.assertEqual(call_util.lcall([1, 2, 3], lambda x, y: x + y, y=2), [3, 4, 5])
72
+ # def test_with_additional_arguments(self):
73
+ # self.assertEqual(call_util.lcall([1, 2, 3], lambda x, y: x + y, y=2), [3, 4, 5])
74
74
 
75
75
 
76
- class TestAlCall(unittest.IsolatedAsyncioTestCase):
76
+ # class TestAlCall(unittest.IsolatedAsyncioTestCase):
77
77
 
78
- async def test_empty_input(self):
79
- result = await call_util.alcall([], lambda x: x*2)
80
- self.assertEqual(result, [])
78
+ # async def test_empty_input(self):
79
+ # result = await call_util.alcall([], lambda x: x*2)
80
+ # self.assertEqual(result, [])
81
81
 
82
- async def test_single_element_with_async_function(self):
83
- async def async_func(x):
84
- return x * 2
85
- result = await call_util.alcall(5, async_func)
86
- self.assertEqual(result, [10])
82
+ # async def test_single_element_with_async_function(self):
83
+ # async def async_func(x):
84
+ # return x * 2
85
+ # result = await call_util.alcall(5, async_func)
86
+ # self.assertEqual(result, [10])
87
87
 
88
- async def test_list_input_with_sync_function(self):
89
- result = await call_util.alcall([1, 2, 3], lambda x: x*2)
90
- self.assertEqual(result, [2, 4, 6])
88
+ # async def test_list_input_with_sync_function(self):
89
+ # result = await call_util.alcall([1, 2, 3], lambda x: x*2)
90
+ # self.assertEqual(result, [2, 4, 6])
91
91
 
92
- async def test_flatten_with_async_function(self):
93
- async def async_func(x):
94
- return x * 2
95
- result = await call_util.alcall([[1, 2], [3, 4]], async_func, flatten=True)
96
- self.assertEqual(result, [2, 4, 6, 8])
97
-
98
- async def test_drop_none_with_sync_function(self):
99
- result = await call_util.alcall([1, None, 2], lambda x: x, dropna=True)
100
- self.assertEqual(result, [1, 2])
101
-
102
- async def test_exception_handling_in_async_function(self):
103
- async def faulty_func(x):
104
- raise ValueError("Faulty Function")
105
- with self.assertRaises(ValueError):
106
- await call_util.alcall([1, 2, 3], faulty_func)
107
-
108
- async def test_with_additional_arguments(self):
109
- async def async_func(x, y):
110
- return x + y
111
- result = await call_util.alcall([1, 2, 3], async_func, y=2)
112
- self.assertEqual(result, [3, 4, 5])
113
-
114
-
115
- class TestTCall(unittest.IsolatedAsyncioTestCase):
116
-
117
- async def test_sync_function_call(self):
118
- def sync_func(x):
119
- return x * 2
120
- result = await call_util.tcall(5, sync_func)
121
- self.assertEqual(result, 10)
122
-
123
- async def test_async_function_call(self):
124
- async def async_func(x):
125
- return x * 2
126
- result = await call_util.tcall(5, async_func)
127
- self.assertEqual(result, 10)
128
-
129
- async def test_with_delay(self):
130
- async def async_func(x):
131
- return x * 2
132
- start_time = asyncio.get_event_loop().time()
133
- await call_util.tcall(5, async_func, sleep=1)
134
- elapsed = asyncio.get_event_loop().time() - start_time
135
- self.assertTrue(elapsed >= 1)
136
-
137
- async def test_error_handling(self):
138
- async def async_func(x):
139
- raise ValueError("Test Error")
140
- with self.assertRaises(ValueError):
141
- await call_util.tcall(5, async_func, message="Custom Error Message")
142
-
143
- async def test_execution_timing(self):
144
- async def async_func(x):
145
- return x * 2
146
- result, duration = await call_util.tcall(5, async_func, include_timing=True)
147
- self.assertEqual(result, 10)
148
- self.assertIsInstance(duration, float)
149
-
150
- async def test_ignore_error(self):
151
- def sync_func(x):
152
- raise ValueError("Test Error")
153
- result = await call_util.tcall(5, sync_func, ignore_error=True)
154
- self.assertIsNone(result)
155
-
156
- async def test_with_additional_arguments(self):
157
- async def async_func(x, y):
158
- return x + y
159
- result = await call_util.tcall(5, async_func, y=3)
160
- self.assertEqual(result, 8)
161
-
162
- class TestMCall(unittest.IsolatedAsyncioTestCase):
163
-
164
- async def test_single_function_single_input(self):
165
- async def async_func(x):
166
- return x * 2
167
- result = await call_util.mcall(5, async_func)
168
- self.assertEqual(result, [10])
169
-
170
- async def test_list_of_functions_single_input(self):
171
- async def async_func1(x):
172
- return x * 2
173
- async def async_func2(x):
174
- return x + 3
175
- with self.assertRaises(AssertionError):
176
- await call_util.mcall(5, [async_func1, async_func2])
177
-
178
- async def test_single_function_list_of_inputs(self):
179
- async def async_func(x):
180
- return x * 2
181
-
182
- with self.assertRaises(AssertionError):
183
- await call_util.mcall([1, 2, 3], async_func)
184
-
185
- async def test_list_of_functions_list_of_inputs_explode_false(self):
186
- async def async_func1(x):
187
- return x * 2
188
- async def async_func2(x):
189
- return x + 3
190
- result = await call_util.mcall([1, 2], [async_func1, async_func2])
191
- self.assertEqual(result, [2, 5])
192
-
193
- async def test_list_of_functions_list_of_inputs_explode_true(self):
194
- async def async_func1(x):
195
- return x * 2
196
- async def async_func2(x):
197
- return x + 3
198
- result = await call_util.mcall([1, 2], [async_func1, async_func2], explode=True)
199
- self.assertEqual(result, [[2, 4], [4, 5]])
200
-
201
- async def test_flatten_and_dropna(self):
202
- async def async_func1(x):
203
- return x * 2
204
- async def async_func2(x):
205
- return x + 3
206
- result = await call_util.mcall([[1, None], [None, 2]], [async_func1, async_func2], flatten=True, dropna=True)
207
- self.assertEqual(result, [2, 5])
208
-
209
- async def test_exception_handling(self):
210
- async def async_func(x):
211
- if x == 2:
212
- raise ValueError("Test Error")
213
- return x * 2
214
- with self.assertRaises(ValueError):
215
- await call_util.mcall([1, 2], [async_func, async_func])
216
-
217
- async def test_with_additional_arguments(self):
218
- async def async_func(x, y):
219
- return x + y
220
- result = await call_util.mcall([1, 2], [async_func, async_func], y=2)
221
- self.assertEqual(result, [3, 4])
222
-
223
- class TestBCall(unittest.IsolatedAsyncioTestCase):
224
-
225
- async def test_empty_input_list(self):
226
- async def async_func(x):
227
- return x * 2
228
- result = await call_util.bcall([], async_func, batch_size=2)
229
- self.assertEqual(result, [])
230
-
231
- async def test_sync_function_call(self):
232
- def sync_func(x):
233
- return x * 2
234
- result = await call_util.bcall([1, 2, 3], sync_func, batch_size=2)
235
- self.assertEqual(result, [2, 4, 6])
236
-
237
- async def test_async_function_call(self):
238
- async def async_func(x):
239
- return x * 2
240
- result = await call_util.bcall([1, 2, 3], async_func, batch_size=2)
241
- self.assertEqual(result, [2, 4, 6])
242
-
243
- async def test_batch_processing(self):
244
- async def async_func(x):
245
- return x * 2
246
- # Test with 4 elements and a batch size of 2
247
- result = await call_util.bcall([1, 2, 3, 4], async_func, batch_size=2)
248
- self.assertEqual(result, [2, 4, 6, 8])
249
-
250
- async def test_exception_handling(self):
251
- async def async_func(x):
252
- if x == 2:
253
- raise ValueError("Test Error")
254
- return x * 2
255
- with self.assertRaises(ValueError):
256
- await call_util.bcall([1, 2, 3], async_func, batch_size=2)
257
-
258
- async def test_with_additional_arguments(self):
259
- async def async_func(x, y):
260
- return x + y
261
- result = await call_util.bcall([1, 2, 3], async_func, batch_size=2, y=3)
262
- self.assertEqual(result, [4, 5, 6])
263
-
264
-
265
- class TestRCall(unittest.IsolatedAsyncioTestCase):
266
-
267
- async def test_sync_function_without_timeout(self):
268
- def sync_func(x):
269
- return x * 2
270
- result = await call_util.rcall(sync_func, 5)
271
- self.assertEqual(result, 10)
272
-
273
- async def test_async_function_without_timeout(self):
274
- async def async_func(x):
275
- return x * 2
276
- result = await call_util.rcall(async_func, 5)
277
- self.assertEqual(result, 10)
278
-
279
- async def test_timeout(self):
280
- async def async_func(x):
281
- await asyncio.sleep(2)
282
- return x
283
- with self.assertRaises(asyncio.TimeoutError):
284
- await call_util.rcall(async_func, 5, timeout=1)
285
-
286
- async def test_timeout(self):
287
- def async_func(x):
288
- time.sleep(2)
289
- return x
290
- with self.assertRaises(asyncio.TimeoutError):
291
- await call_util.rcall(async_func, 5, timeout=1)
292
-
293
- async def test_retry_mechanism(self):
294
- attempt_count = 0
295
- def sync_func(x):
296
- nonlocal attempt_count
297
- attempt_count += 1
298
- raise ValueError("Test Error")
299
- with self.assertRaises(ValueError):
300
- await call_util.rcall(sync_func, 5, retries=3)
301
- self.assertEqual(attempt_count, 3) # Initial call + 3 retries
302
-
303
- async def test_default_value_on_exception(self):
304
- def sync_func(x):
305
- raise ValueError("Test Error")
306
- result = await call_util.rcall(sync_func, 5, default=10)
307
- self.assertEqual(result, 10)
308
-
309
- async def test_exception_propagation(self):
310
- def sync_func(x):
311
- raise ValueError("Test Error")
312
- with self.assertRaises(ValueError):
313
- await call_util.rcall(sync_func, 5)
314
-
315
-
316
- class TestCallDecorator(unittest.IsolatedAsyncioTestCase):
317
-
318
- def test_cache_decorator_sync(self):
319
- @CallDecorator.cache
320
- def sync_func(x):
321
- return x * 2
322
-
323
- first_call = sync_func(5)
324
- second_call = sync_func(5)
325
-
326
- self.assertEqual(first_call, 10)
327
- self.assertIs(first_call, second_call)
328
-
329
- async def test_cache_decorator_async(self):
330
- @CallDecorator.cache
331
- async def async_func(x):
332
- return x * 2
333
-
334
- first_call = await async_func(5)
335
- second_call = await async_func(5)
336
-
337
- self.assertEqual(first_call, 10)
338
- self.assertIs(first_call, second_call)
339
-
340
- def test_timeout_with_sync_function(self):
341
- @CallDecorator.timeout(1) # 1 second timeout
342
- def sync_func(x):
343
- time.sleep(2) # Sleep for 2 seconds, should trigger timeout
344
- return x
345
-
346
- with self.assertRaises(asyncio.TimeoutError):
347
- asyncio.run(sync_func(5))
348
-
349
- def test_no_timeout_with_sync_function(self):
350
- @CallDecorator.timeout(2) # 2 second timeout
351
- def sync_func(x):
352
- time.sleep(1) # Sleep for 1 second, within timeout
353
- return x
354
-
355
- result = sync_func(5)
356
- self.assertEqual(result, 5)
357
-
358
- async def test_timeout_with_async_function(self):
359
- @CallDecorator.timeout(1) # 1 second timeout
360
- async def async_func(x):
361
- await asyncio.sleep(2) # Sleep for 2 seconds, should trigger timeout
362
- return x
363
-
364
- with self.assertRaises(asyncio.TimeoutError):
365
- await async_func(5)
366
-
367
- async def test_no_timeout_with_async_function(self):
368
- @CallDecorator.timeout(2) # 2 second timeout
369
- async def async_func(x):
370
- await asyncio.sleep(1) # Sleep for 1 second, within timeout
371
- return x
372
-
373
- result = await async_func(5)
374
- self.assertEqual(result, 5)
375
-
376
- def test_successful_retry(self):
377
- attempt = 0
378
-
379
- @CallDecorator.retry(retries=3, initial_delay=1, backoff_factor=2)
380
- def test_func():
381
- nonlocal attempt
382
- attempt += 1
383
- if attempt < 3:
384
- raise ValueError("Test failure")
385
- return "Success"
386
-
387
- result = test_func()
388
- self.assertEqual(result, "Success")
389
- self.assertEqual(attempt, 3)
390
-
391
- def test_retry_limit(self):
392
- attempt = 0
393
-
394
- @CallDecorator.retry(retries=2, initial_delay=1, backoff_factor=2)
395
- def test_func():
396
- nonlocal attempt
397
- attempt += 1
398
- raise ValueError("Test failure")
399
-
400
- with self.assertRaises(ValueError):
401
- test_func()
402
- self.assertEqual(attempt, 2)
403
-
404
- def test_immediate_success(self):
405
- attempt = 0
406
-
407
- @CallDecorator.retry(retries=3, initial_delay=1, backoff_factor=2)
408
- def test_func():
409
- nonlocal attempt
410
- attempt += 1
411
- return "Success"
92
+ # async def test_flatten_with_async_function(self):
93
+ # async def async_func(x):
94
+ # return x * 2
95
+ # result = await call_util.alcall([[1, 2], [3, 4]], async_func, flatten=True)
96
+ # self.assertEqual(result, [2, 4, 6, 8])
97
+
98
+ # async def test_drop_none_with_sync_function(self):
99
+ # result = await call_util.alcall([1, None, 2], lambda x: x, dropna=True)
100
+ # self.assertEqual(result, [1, 2])
101
+
102
+ # async def test_exception_handling_in_async_function(self):
103
+ # async def faulty_func(x):
104
+ # raise ValueError("Faulty Function")
105
+ # with self.assertRaises(ValueError):
106
+ # await call_util.alcall([1, 2, 3], faulty_func)
107
+
108
+ # async def test_with_additional_arguments(self):
109
+ # async def async_func(x, y):
110
+ # return x + y
111
+ # result = await call_util.alcall([1, 2, 3], async_func, y=2)
112
+ # self.assertEqual(result, [3, 4, 5])
113
+
114
+
115
+ # class TestTCall(unittest.IsolatedAsyncioTestCase):
116
+
117
+ # async def test_sync_function_call(self):
118
+ # def sync_func(x):
119
+ # return x * 2
120
+ # result = await call_util.tcall(5, sync_func)
121
+ # self.assertEqual(result, 10)
122
+
123
+ # async def test_async_function_call(self):
124
+ # async def async_func(x):
125
+ # return x * 2
126
+ # result = await call_util.tcall(5, async_func)
127
+ # self.assertEqual(result, 10)
128
+
129
+ # async def test_with_delay(self):
130
+ # async def async_func(x):
131
+ # return x * 2
132
+ # start_time = asyncio.get_event_loop().time()
133
+ # await call_util.tcall(5, async_func, sleep=1)
134
+ # elapsed = asyncio.get_event_loop().time() - start_time
135
+ # self.assertTrue(elapsed >= 1)
136
+
137
+ # async def test_error_handling(self):
138
+ # async def async_func(x):
139
+ # raise ValueError("Test Error")
140
+ # with self.assertRaises(ValueError):
141
+ # await call_util.tcall(5, async_func, message="Custom Error Message")
142
+
143
+ # async def test_execution_timing(self):
144
+ # async def async_func(x):
145
+ # return x * 2
146
+ # result, duration = await call_util.tcall(5, async_func, include_timing=True)
147
+ # self.assertEqual(result, 10)
148
+ # self.assertIsInstance(duration, float)
149
+
150
+ # async def test_ignore_error(self):
151
+ # def sync_func(x):
152
+ # raise ValueError("Test Error")
153
+ # result = await call_util.tcall(5, sync_func, ignore_error=True)
154
+ # self.assertIsNone(result)
155
+
156
+ # async def test_with_additional_arguments(self):
157
+ # async def async_func(x, y):
158
+ # return x + y
159
+ # result = await call_util.tcall(5, async_func, y=3)
160
+ # self.assertEqual(result, 8)
161
+
162
+ # class TestMCall(unittest.IsolatedAsyncioTestCase):
163
+
164
+ # async def test_single_function_single_input(self):
165
+ # async def async_func(x):
166
+ # return x * 2
167
+ # result = await call_util.mcall(5, async_func)
168
+ # self.assertEqual(result, [10])
169
+
170
+ # async def test_list_of_functions_single_input(self):
171
+ # async def async_func1(x):
172
+ # return x * 2
173
+ # async def async_func2(x):
174
+ # return x + 3
175
+ # with self.assertRaises(AssertionError):
176
+ # await call_util.mcall(5, [async_func1, async_func2])
177
+
178
+ # async def test_single_function_list_of_inputs(self):
179
+ # async def async_func(x):
180
+ # return x * 2
181
+
182
+ # with self.assertRaises(AssertionError):
183
+ # await call_util.mcall([1, 2, 3], async_func)
184
+
185
+ # async def test_list_of_functions_list_of_inputs_explode_false(self):
186
+ # async def async_func1(x):
187
+ # return x * 2
188
+ # async def async_func2(x):
189
+ # return x + 3
190
+ # result = await call_util.mcall([1, 2], [async_func1, async_func2])
191
+ # self.assertEqual(result, [2, 5])
192
+
193
+ # async def test_list_of_functions_list_of_inputs_explode_true(self):
194
+ # async def async_func1(x):
195
+ # return x * 2
196
+ # async def async_func2(x):
197
+ # return x + 3
198
+ # result = await call_util.mcall([1, 2], [async_func1, async_func2], explode=True)
199
+ # self.assertEqual(result, [[2, 4], [4, 5]])
200
+
201
+ # async def test_flatten_and_dropna(self):
202
+ # async def async_func1(x):
203
+ # return x * 2
204
+ # async def async_func2(x):
205
+ # return x + 3
206
+ # result = await call_util.mcall([[1, None], [None, 2]], [async_func1, async_func2], flatten=True, dropna=True)
207
+ # self.assertEqual(result, [2, 5])
208
+
209
+ # async def test_exception_handling(self):
210
+ # async def async_func(x):
211
+ # if x == 2:
212
+ # raise ValueError("Test Error")
213
+ # return x * 2
214
+ # with self.assertRaises(ValueError):
215
+ # await call_util.mcall([1, 2], [async_func, async_func])
216
+
217
+ # async def test_with_additional_arguments(self):
218
+ # async def async_func(x, y):
219
+ # return x + y
220
+ # result = await call_util.mcall([1, 2], [async_func, async_func], y=2)
221
+ # self.assertEqual(result, [3, 4])
222
+
223
+ # class TestBCall(unittest.IsolatedAsyncioTestCase):
224
+
225
+ # async def test_empty_input_list(self):
226
+ # async def async_func(x):
227
+ # return x * 2
228
+ # result = await call_util.bcall([], async_func, batch_size=2)
229
+ # self.assertEqual(result, [])
230
+
231
+ # async def test_sync_function_call(self):
232
+ # def sync_func(x):
233
+ # return x * 2
234
+ # result = await call_util.bcall([1, 2, 3], sync_func, batch_size=2)
235
+ # self.assertEqual(result, [2, 4, 6])
236
+
237
+ # async def test_async_function_call(self):
238
+ # async def async_func(x):
239
+ # return x * 2
240
+ # result = await call_util.bcall([1, 2, 3], async_func, batch_size=2)
241
+ # self.assertEqual(result, [2, 4, 6])
242
+
243
+ # async def test_batch_processing(self):
244
+ # async def async_func(x):
245
+ # return x * 2
246
+ # # Test with 4 elements and a batch size of 2
247
+ # result = await call_util.bcall([1, 2, 3, 4], async_func, batch_size=2)
248
+ # self.assertEqual(result, [2, 4, 6, 8])
249
+
250
+ # async def test_exception_handling(self):
251
+ # async def async_func(x):
252
+ # if x == 2:
253
+ # raise ValueError("Test Error")
254
+ # return x * 2
255
+ # with self.assertRaises(ValueError):
256
+ # await call_util.bcall([1, 2, 3], async_func, batch_size=2)
257
+
258
+ # async def test_with_additional_arguments(self):
259
+ # async def async_func(x, y):
260
+ # return x + y
261
+ # result = await call_util.bcall([1, 2, 3], async_func, batch_size=2, y=3)
262
+ # self.assertEqual(result, [4, 5, 6])
263
+
264
+
265
+ # class TestRCall(unittest.IsolatedAsyncioTestCase):
266
+
267
+ # async def test_sync_function_without_timeout(self):
268
+ # def sync_func(x):
269
+ # return x * 2
270
+ # result = await call_util.rcall(sync_func, 5)
271
+ # self.assertEqual(result, 10)
272
+
273
+ # async def test_async_function_without_timeout(self):
274
+ # async def async_func(x):
275
+ # return x * 2
276
+ # result = await call_util.rcall(async_func, 5)
277
+ # self.assertEqual(result, 10)
278
+
279
+ # async def test_timeout(self):
280
+ # async def async_func(x):
281
+ # await asyncio.sleep(2)
282
+ # return x
283
+ # with self.assertRaises(asyncio.TimeoutError):
284
+ # await call_util.rcall(async_func, 5, timeout=1)
285
+
286
+ # async def test_timeout(self):
287
+ # def async_func(x):
288
+ # time.sleep(2)
289
+ # return x
290
+ # with self.assertRaises(asyncio.TimeoutError):
291
+ # await call_util.rcall(async_func, 5, timeout=1)
292
+
293
+ # async def test_retry_mechanism(self):
294
+ # attempt_count = 0
295
+ # def sync_func(x):
296
+ # nonlocal attempt_count
297
+ # attempt_count += 1
298
+ # raise ValueError("Test Error")
299
+ # with self.assertRaises(ValueError):
300
+ # await call_util.rcall(sync_func, 5, retries=3)
301
+ # self.assertEqual(attempt_count, 4) # Initial call + 3 retries
302
+
303
+ # async def test_default_value_on_exception(self):
304
+ # def sync_func(x):
305
+ # raise ValueError("Test Error")
306
+ # result = await call_util.rcall(sync_func, 5, default=10)
307
+ # self.assertEqual(result, 10)
308
+
309
+ # async def test_exception_propagation(self):
310
+ # def sync_func(x):
311
+ # raise ValueError("Test Error")
312
+ # with self.assertRaises(ValueError):
313
+ # await call_util.rcall(sync_func, 5)
314
+
315
+
316
+ # class TestCallDecorator(unittest.IsolatedAsyncioTestCase):
317
+
318
+ # def test_cache_decorator_sync(self):
319
+ # @CallDecorator.cache
320
+ # def sync_func(x):
321
+ # return x * 2
322
+
323
+ # first_call = sync_func(5)
324
+ # second_call = sync_func(5)
325
+
326
+ # self.assertEqual(first_call, 10)
327
+ # self.assertIs(first_call, second_call)
328
+
329
+ # async def test_cache_decorator_async(self):
330
+ # @CallDecorator.cache
331
+ # async def async_func(x):
332
+ # return x * 2
333
+
334
+ # first_call = await async_func(5)
335
+ # second_call = await async_func(5)
336
+
337
+ # self.assertEqual(first_call, 10)
338
+ # self.assertIs(first_call, second_call)
339
+
340
+ # def test_timeout_with_sync_function(self):
341
+ # @CallDecorator.timeout(1) # 1 second timeout
342
+ # def sync_func(x):
343
+ # time.sleep(2) # Sleep for 2 seconds, should trigger timeout
344
+ # return x
345
+
346
+ # with self.assertRaises(asyncio.TimeoutError):
347
+ # asyncio.run(sync_func(5))
348
+
349
+ # def test_no_timeout_with_sync_function(self):
350
+ # @CallDecorator.timeout(2) # 2 second timeout
351
+ # def sync_func(x):
352
+ # time.sleep(1) # Sleep for 1 second, within timeout
353
+ # return x
354
+
355
+ # result = sync_func(5)
356
+ # self.assertEqual(result, 5)
357
+
358
+ # async def test_timeout_with_async_function(self):
359
+ # @CallDecorator.timeout(1) # 1 second timeout
360
+ # async def async_func(x):
361
+ # await asyncio.sleep(2) # Sleep for 2 seconds, should trigger timeout
362
+ # return x
363
+
364
+ # with self.assertRaises(asyncio.TimeoutError):
365
+ # await async_func(5)
366
+
367
+ # async def test_no_timeout_with_async_function(self):
368
+ # @CallDecorator.timeout(2) # 2 second timeout
369
+ # async def async_func(x):
370
+ # await asyncio.sleep(1) # Sleep for 1 second, within timeout
371
+ # return x
372
+
373
+ # result = await async_func(5)
374
+ # self.assertEqual(result, 5)
375
+
376
+ # def test_successful_retry(self):
377
+ # attempt = 0
378
+
379
+ # @CallDecorator.retry(retries=3, initial_delay=1, backoff_factor=2)
380
+ # def test_func():
381
+ # nonlocal attempt
382
+ # attempt += 1
383
+ # if attempt < 3:
384
+ # raise ValueError("Test failure")
385
+ # return "Success"
386
+
387
+ # result = test_func()
388
+ # self.assertEqual(result, "Success")
389
+ # self.assertEqual(attempt, 3)
390
+
391
+ # def test_retry_limit(self):
392
+ # attempt = 0
393
+
394
+ # @CallDecorator.retry(retries=2, initial_delay=1, backoff_factor=2)
395
+ # def test_func():
396
+ # nonlocal attempt
397
+ # attempt += 1
398
+ # raise ValueError("Test failure")
399
+
400
+ # with self.assertRaises(ValueError):
401
+ # test_func()
402
+ # self.assertEqual(attempt, 3)
403
+
404
+ # def test_immediate_success(self):
405
+ # attempt = 0
406
+
407
+ # @CallDecorator.retry(retries=3, initial_delay=1, backoff_factor=2)
408
+ # def test_func():
409
+ # nonlocal attempt
410
+ # attempt += 1
411
+ # return "Success"
412
412
 
413
- result = test_func()
414
- self.assertEqual(result, "Success")
415
- self.assertEqual(attempt, 1)
416
-
417
- def test_retry_with_delays(self):
418
- attempt = 0
419
- start_time = time.time()
420
-
421
- @CallDecorator.retry(retries=3, initial_delay=1, backoff_factor=2)
422
- def test_func():
423
- nonlocal attempt
424
- attempt += 1
425
- if attempt < 3:
426
- raise ValueError("Test failure")
427
- return "Success"
428
-
429
- result = test_func()
430
- end_time = time.time()
431
- elapsed_time = end_time - start_time
432
-
433
- self.assertEqual(result, "Success")
434
- self.assertTrue(elapsed_time >= 3)
435
- self.assertEqual(attempt, 3)
436
413
 
437
- def test_default_value_on_exception(self):
438
- @CallDecorator.default(default_value="Default")
439
- def test_func():
440
- raise ValueError("Test failure")
441
-
442
- result = test_func()
443
- self.assertEqual(result, "Default")
414
+ # result = test_func()
415
+ # self.assertEqual(result, "Success")
416
+ # self.assertEqual(attempt, 1)
444
417
 
445
- def test_no_exception(self):
446
- @CallDecorator.default(default_value="Default")
447
- def test_func():
448
- return "Success"
418
+ # def test_retry_with_delays(self):
419
+ # attempt = 0
420
+ # start_time = time.time()
449
421
 
450
- result = test_func()
451
- self.assertEqual(result, "Success")
422
+ # @CallDecorator.retry(retries=3, initial_delay=1, backoff_factor=2)
423
+ # def test_func():
424
+ # nonlocal attempt
425
+ # attempt += 1
426
+ # if attempt < 3:
427
+ # raise ValueError("Test failure")
428
+ # return "Success"
429
+
430
+ # result = test_func()
431
+ # end_time = time.time()
432
+ # elapsed_time = end_time - start_time
452
433
 
453
- def test_throttling_behavior(self):
454
- @CallDecorator.throttle(period=2) # 2 seconds throttle period
455
- def test_func():
456
- return time.time()
434
+ # self.assertEqual(result, "Success")
435
+ # self.assertTrue(elapsed_time >= 3)
436
+ # self.assertEqual(attempt, 3)
457
437
 
458
- start_time = time.time()
459
- first_call = test_func()
460
- second_call = test_func()
461
- end_time = time.time()
438
+ # def test_default_value_on_exception(self):
439
+ # @CallDecorator.default(default_value="Default")
440
+ # def test_func():
441
+ # raise ValueError("Test failure")
462
442
 
463
- self.assertLess(first_call - start_time, 1) # First call should be immediate
464
- self.assertGreaterEqual(second_call - first_call, 2) # Second call should be delayed
465
- self.assertLessEqual(end_time - start_time, 3) # Total time should be within reasonable bounds
443
+ # result = test_func()
444
+ # self.assertEqual(result, "Default")
466
445
 
467
- def test_successive_calls_outside_throttle_period(self):
468
- @CallDecorator.throttle(period=1) # 1 second throttle period
469
- def test_func():
470
- return time.time()
446
+ # def test_no_exception(self):
447
+ # @CallDecorator.default(default_value="Default")
448
+ # def test_func():
449
+ # return "Success"
471
450
 
472
- first_call = test_func()
473
- time.sleep(1.1) # Sleep to exceed the throttle period
474
- second_call = test_func()
451
+ # result = test_func()
452
+ # self.assertEqual(result, "Success")
475
453
 
476
- self.assertGreaterEqual(second_call - first_call, 1) # Second call should not be delayed
454
+ # def test_throttling_behavior(self):
455
+ # @CallDecorator.throttle(period=2) # 2 seconds throttle period
456
+ # def test_func():
457
+ # return time.time()
477
458
 
478
- def test_throttling_with_different_inputs(self):
479
- @CallDecorator.throttle(period=2) # 2 seconds throttle period
480
- def test_func(x):
481
- return x
459
+ # start_time = time.time()
460
+ # first_call = test_func()
461
+ # second_call = test_func()
462
+ # end_time = time.time()
482
463
 
483
- first_call = test_func(1)
484
- time.sleep(0.5)
485
- second_call = test_func(2)
464
+ # self.assertLess(first_call - start_time, 1) # First call should be immediate
465
+ # self.assertGreaterEqual(second_call - first_call, 2) # Second call should be delayed
466
+ # self.assertLessEqual(end_time - start_time, 3) # Total time should be within reasonable bounds
486
467
 
487
- self.assertEqual(first_call, 1)
488
- self.assertEqual(second_call, 2) # Should return the result of the first call due to throttling
468
+ # def test_successive_calls_outside_throttle_period(self):
469
+ # @CallDecorator.throttle(period=1) # 1 second throttle period
470
+ # def test_func():
471
+ # return time.time()
489
472
 
490
- def test_preprocessing(self):
491
- def preprocess(x):
492
- return x * 2
473
+ # first_call = test_func()
474
+ # time.sleep(1.1) # Sleep to exceed the throttle period
475
+ # second_call = test_func()
493
476
 
494
- @CallDecorator.pre_post_process(preprocess, lambda x: x)
495
- def test_func(x):
496
- return x + 3
477
+ # self.assertGreaterEqual(second_call - first_call, 1) # Second call should not be delayed
497
478
 
498
- result = test_func(2) # Preprocess: 2 * 2 -> 4, Func: 4 + 3
499
- self.assertEqual(result, 7)
479
+ # def test_throttling_with_different_inputs(self):
480
+ # @CallDecorator.throttle(period=2) # 2 seconds throttle period
481
+ # def test_func(x):
482
+ # return x
500
483
 
501
- def test_postprocessing(self):
502
- def postprocess(x):
503
- return x * 3
484
+ # first_call = test_func(1)
485
+ # time.sleep(0.5)
486
+ # second_call = test_func(2)
504
487
 
505
- @CallDecorator.pre_post_process(lambda x: x, postprocess)
506
- def test_func(x):
507
- return x + 2
488
+ # self.assertEqual(first_call, 1)
489
+ # self.assertEqual(second_call, 2) # Should return the result of the first call due to throttling
508
490
 
509
- result = test_func(2) # Func: 2 + 2 -> 4, Postprocess: 4 * 3
510
- self.assertEqual(result, 12)
491
+ # def test_preprocessing(self):
492
+ # def preprocess(x):
493
+ # return x * 2
511
494
 
495
+ # @CallDecorator.pre_post_process(preprocess, lambda x: x)
496
+ # def test_func(x):
497
+ # return x + 3
512
498
 
513
- def test_preprocessing_and_postprocessing(self):
514
- def preprocess(x):
515
- return x * 2
499
+ # result = test_func(2) # Preprocess: 2 * 2 -> 4, Func: 4 + 3
500
+ # self.assertEqual(result, 7)
516
501
 
517
- def postprocess(x):
518
- return x * 3
502
+ # def test_postprocessing(self):
503
+ # def postprocess(x):
504
+ # return x * 3
519
505
 
520
- @CallDecorator.pre_post_process(preprocess, postprocess)
521
- def test_func(x):
522
- return x + 1
506
+ # @CallDecorator.pre_post_process(lambda x: x, postprocess)
507
+ # def test_func(x):
508
+ # return x + 2
523
509
 
524
- result = test_func(2) # Preprocess: 2 * 2 -> 4, Func: 4 + 1 -> 5, Postprocess: 5 * 3
525
- self.assertEqual(result, 15)
510
+ # result = test_func(2) # Func: 2 + 2 -> 4, Postprocess: 4 * 3
511
+ # self.assertEqual(result, 12)
526
512
 
527
- def test_filtering_based_on_predicate(self):
528
- is_even = lambda x: x % 2 == 0
529
513
 
530
- @CallDecorator.filter(is_even)
531
- def test_func():
532
- return [1, 2, 3, 4, 5]
514
+ # def test_preprocessing_and_postprocessing(self):
515
+ # def preprocess(x):
516
+ # return x * 2
533
517
 
534
- result = test_func()
535
- self.assertEqual(result, [2, 4])
518
+ # def postprocess(x):
519
+ # return x * 3
536
520
 
537
- def test_no_items_satisfy_predicate(self):
538
- is_negative = lambda x: x < 0
521
+ # @CallDecorator.pre_post_process(preprocess, postprocess)
522
+ # def test_func(x):
523
+ # return x + 1
539
524
 
540
- @CallDecorator.filter(is_negative)
541
- def test_func():
542
- return [1, 2, 3, 4, 5]
525
+ # result = test_func(2) # Preprocess: 2 * 2 -> 4, Func: 4 + 1 -> 5, Postprocess: 5 * 3
526
+ # self.assertEqual(result, 15)
543
527
 
544
- result = test_func()
545
- self.assertEqual(result, [])
528
+ # def test_filtering_based_on_predicate(self):
529
+ # is_even = lambda x: x % 2 == 0
546
530
 
547
- def test_all_items_satisfy_predicate(self):
548
- is_positive = lambda x: x > 0
531
+ # @CallDecorator.filter(is_even)
532
+ # def test_func():
533
+ # return [1, 2, 3, 4, 5]
549
534
 
550
- @CallDecorator.filter(is_positive)
551
- def test_func():
552
- return [1, 2, 3, 4, 5]
535
+ # result = test_func()
536
+ # self.assertEqual(result, [2, 4])
553
537
 
554
- result = test_func()
555
- self.assertEqual(result, [1, 2, 3, 4, 5])
538
+ # def test_no_items_satisfy_predicate(self):
539
+ # is_negative = lambda x: x < 0
556
540
 
557
- def test_mapping_function(self):
558
- double = lambda x: x * 2
541
+ # @CallDecorator.filter(is_negative)
542
+ # def test_func():
543
+ # return [1, 2, 3, 4, 5]
559
544
 
560
- @CallDecorator.map(double)
561
- def test_func():
562
- return [1, 2, 3, 4, 5]
545
+ # result = test_func()
546
+ # self.assertEqual(result, [])
563
547
 
564
- result = test_func()
565
- self.assertEqual(result, [2, 4, 6, 8, 10])
548
+ # def test_all_items_satisfy_predicate(self):
549
+ # is_positive = lambda x: x > 0
566
550
 
567
- def test_empty_list(self):
568
- double = lambda x: x * 2
551
+ # @CallDecorator.filter(is_positive)
552
+ # def test_func():
553
+ # return [1, 2, 3, 4, 5]
569
554
 
570
- @CallDecorator.map(double)
571
- def test_func():
572
- return []
555
+ # result = test_func()
556
+ # self.assertEqual(result, [1, 2, 3, 4, 5])
573
557
 
574
- result = test_func()
575
- self.assertEqual(result, [])
558
+ # def test_mapping_function(self):
559
+ # double = lambda x: x * 2
576
560
 
577
- def test_mapping_with_different_data_types(self):
578
- to_string = lambda x: str(x)
561
+ # @CallDecorator.map(double)
562
+ # def test_func():
563
+ # return [1, 2, 3, 4, 5]
579
564
 
580
- @CallDecorator.map(to_string)
581
- def test_func():
582
- return [1, 2.5, 'test', True]
565
+ # result = test_func()
566
+ # self.assertEqual(result, [2, 4, 6, 8, 10])
583
567
 
584
- result = test_func()
585
- self.assertEqual(result, ['1', '2.5', 'test', 'True'])
568
+ # def test_empty_list(self):
569
+ # double = lambda x: x * 2
586
570
 
587
- def test_reduction_function(self):
588
- sum_func = lambda x, y: x + y
571
+ # @CallDecorator.map(double)
572
+ # def test_func():
573
+ # return []
589
574
 
590
- @CallDecorator.reduce(sum_func, 0)
591
- def test_func():
592
- return [1, 2, 3, 4, 5]
575
+ # result = test_func()
576
+ # self.assertEqual(result, [])
593
577
 
594
- result = test_func()
595
- self.assertEqual(result, 15) # Sum of 1, 2, 3, 4, 5
578
+ # def test_mapping_with_different_data_types(self):
579
+ # to_string = lambda x: str(x)
596
580
 
597
- def test_empty_list(self):
598
- sum_func = lambda x, y: x + y
581
+ # @CallDecorator.map(to_string)
582
+ # def test_func():
583
+ # return [1, 2.5, 'test', True]
599
584
 
600
- @CallDecorator.reduce(sum_func, 0)
601
- def test_func():
602
- return []
585
+ # result = test_func()
586
+ # self.assertEqual(result, ['1', '2.5', 'test', 'True'])
603
587
 
604
- result = test_func()
605
- self.assertEqual(result, 0) # Initial value
588
+ # def test_reduction_function(self):
589
+ # sum_func = lambda x, y: x + y
606
590
 
607
- def test_reduction_with_initial_value(self):
608
- sum_func = lambda x, y: x + y
591
+ # @CallDecorator.reduce(sum_func, 0)
592
+ # def test_func():
593
+ # return [1, 2, 3, 4, 5]
609
594
 
610
- @CallDecorator.reduce(sum_func, 10)
611
- def test_func():
612
- return [1, 2, 3, 4, 5]
595
+ # result = test_func()
596
+ # self.assertEqual(result, 15) # Sum of 1, 2, 3, 4, 5
613
597
 
614
- result = test_func()
615
- self.assertEqual(result, 25) # 10 (initial) + Sum of 1, 2, 3, 4, 5
598
+ # def test_empty_list(self):
599
+ # sum_func = lambda x, y: x + y
616
600
 
617
- def test_function_composition(self):
618
- double = lambda x: x * 2
619
- add_five = lambda x: x + 5
601
+ # @CallDecorator.reduce(sum_func, 0)
602
+ # def test_func():
603
+ # return []
620
604
 
621
- @CallDecorator.compose(add_five, double) # First add_five, then double
622
- def test_func():
623
- return 3
605
+ # result = test_func()
606
+ # self.assertEqual(result, 0) # Initial value
624
607
 
625
- result = test_func()
626
- self.assertEqual(result, (3 + 5) * 2)
608
+ # def test_reduction_with_initial_value(self):
609
+ # sum_func = lambda x, y: x + y
627
610
 
628
- def test_empty_function_list(self):
629
- @CallDecorator.compose()
630
- def test_func():
631
- return "test"
611
+ # @CallDecorator.reduce(sum_func, 10)
612
+ # def test_func():
613
+ # return [1, 2, 3, 4, 5]
632
614
 
633
- result = test_func()
634
- self.assertEqual(result, "test")
615
+ # result = test_func()
616
+ # self.assertEqual(result, 25) # 10 (initial) + Sum of 1, 2, 3, 4, 5
635
617
 
636
- def test_error_handling_in_composition(self):
637
- def raise_error(x):
638
- raise ValueError("Error in function")
618
+ # def test_function_composition(self):
619
+ # double = lambda x: x * 2
620
+ # add_five = lambda x: x + 5
639
621
 
640
- @CallDecorator.compose(raise_error)
641
- def test_func():
642
- return 3
622
+ # @CallDecorator.compose(add_five, double) # First add_five, then double
623
+ # def test_func():
624
+ # return 3
643
625
 
644
- with self.assertRaises(ValueError):
645
- test_func()
626
+ # result = test_func()
627
+ # self.assertEqual(result, (3 + 5) * 2)
646
628
 
647
- def test_caching_behavior(self):
648
- @CallDecorator.memorize(maxsize=10)
649
- def test_func(x):
650
- return x * 2
629
+ # def test_empty_function_list(self):
630
+ # @CallDecorator.compose()
631
+ # def test_func():
632
+ # return "test"
651
633
 
652
- first_call = test_func(5)
653
- second_call = test_func(5)
634
+ # result = test_func()
635
+ # self.assertEqual(result, "test")
654
636
 
655
- self.assertEqual(first_call, 10)
656
- self.assertIs(first_call, second_call) # Should return cached result
637
+ # def test_error_handling_in_composition(self):
638
+ # def raise_error(x):
639
+ # raise ValueError("Error in function")
657
640
 
658
- def test_different_arguments(self):
659
- @CallDecorator.memorize(maxsize=10)
660
- def test_func(x):
661
- return x * 2
641
+ # @CallDecorator.compose(raise_error)
642
+ # def test_func():
643
+ # return 3
662
644
 
663
- first_call = test_func(5)
664
- second_call = test_func(6)
645
+ # with self.assertRaises(ValueError):
646
+ # test_func()
665
647
 
666
- self.assertNotEqual(first_call, second_call)
667
- self.assertIsNot(first_call, second_call)
648
+ # def test_caching_behavior(self):
649
+ # @CallDecorator.memorize(maxsize=10)
650
+ # def test_func(x):
651
+ # return x * 2
668
652
 
669
- def test_cache_size_limit(self):
670
- @CallDecorator.memorize(maxsize=2)
671
- def test_func(x):
672
- return x * 2
653
+ # first_call = test_func(5)
654
+ # second_call = test_func(5)
673
655
 
674
- test_func(1) # Cache this
675
- test_func(2) # Cache this
676
- test_func(3) # Cache should evict the first entry (1)
677
- result = test_func(1) # Recompute as it should be evicted
656
+ # self.assertEqual(first_call, 10)
657
+ # self.assertIs(first_call, second_call) # Should return cached result
678
658
 
679
- self.assertEqual(result, 2)
659
+ # def test_different_arguments(self):
660
+ # @CallDecorator.memorize(maxsize=10)
661
+ # def test_func(x):
662
+ # return x * 2
680
663
 
681
- def test_type_validation(self):
682
- @CallDecorator.validate(validate_type=int)
683
- def test_func():
684
- return 5
664
+ # first_call = test_func(5)
665
+ # second_call = test_func(6)
685
666
 
686
- result = test_func()
687
- self.assertEqual(result, 5)
667
+ # self.assertNotEqual(first_call, second_call)
668
+ # self.assertIsNot(first_call, second_call)
688
669
 
689
- def test_type_conversion(self):
690
- @CallDecorator.validate(convert_type=str)
691
- def test_func():
692
- return 5
670
+ # def test_cache_size_limit(self):
671
+ # @CallDecorator.memorize(maxsize=2)
672
+ # def test_func(x):
673
+ # return x * 2
693
674
 
694
- result = test_func()
695
- self.assertEqual(result, "5")
675
+ # test_func(1) # Cache this
676
+ # test_func(2) # Cache this
677
+ # test_func(3) # Cache should evict the first entry (1)
678
+ # result = test_func(1) # Recompute as it should be evicted
696
679
 
697
- def test_error_handling_on_invalid_type(self):
698
- @CallDecorator.validate(validate_type=int)
699
- def test_func():
700
- return "not an int"
680
+ # self.assertEqual(result, 2)
701
681
 
702
- with self.assertRaises(TypeError):
703
- test_func()
682
+ # def test_type_validation(self):
683
+ # @CallDecorator.validate(validate_type=int)
684
+ # def test_func():
685
+ # return 5
704
686
 
705
- def test_default_value_on_error(self):
706
- @CallDecorator.validate(validate_type=int, handle_error={'default': 0})
707
- def test_func():
708
- return "not an int"
687
+ # result = test_func()
688
+ # self.assertEqual(result, 5)
709
689
 
710
- result = test_func()
711
- self.assertEqual(result, 0)
690
+ # def test_type_conversion(self):
691
+ # @CallDecorator.validate(convert_type=str)
692
+ # def test_func():
693
+ # return 5
712
694
 
713
- async def test_concurrency_limit(self):
714
- current_concurrency = 0
715
- max_concurrent_calls = 0
695
+ # result = test_func()
696
+ # self.assertEqual(result, "5")
716
697
 
717
- @CallDecorator.max_concurrency(limit=2)
718
- async def test_func():
719
- nonlocal current_concurrency, max_concurrent_calls
720
- current_concurrency += 1
721
- max_concurrent_calls = max(max_concurrent_calls, current_concurrency)
722
- await asyncio.sleep(0.1) # Simulate async work
723
- current_concurrency -= 1
698
+ # def test_error_handling_on_invalid_type(self):
699
+ # @CallDecorator.validate(validate_type=int)
700
+ # def test_func():
701
+ # return "not an int"
724
702
 
725
- await asyncio.gather(*(test_func() for _ in range(5)))
726
- self.assertEqual(max_concurrent_calls, 2)
703
+ # with self.assertRaises(TypeError):
704
+ # test_func()
727
705
 
728
- async def test_function_completing_within_limit(self):
729
- @CallDecorator.max_concurrency(limit=2)
730
- async def test_func(x):
731
- await asyncio.sleep(0.1)
732
- return x
706
+ # def test_default_value_on_error(self):
707
+ # @CallDecorator.validate(validate_type=int, handle_error={'default': 0})
708
+ # def test_func():
709
+ # return "not an int"
733
710
 
734
- results = await asyncio.gather(*(test_func(i) for i in range(5)))
735
- self.assertEqual(results, [0, 1, 2, 3, 4])
711
+ # result = test_func()
712
+ # self.assertEqual(result, 0)
736
713
 
714
+ # async def test_concurrency_limit(self):
715
+ # current_concurrency = 0
716
+ # max_concurrent_calls = 0
737
717
 
738
- class TestThrottleClass(unittest.TestCase):
718
+ # @CallDecorator.max_concurrency(limit=2)
719
+ # async def test_func():
720
+ # nonlocal current_concurrency, max_concurrent_calls
721
+ # current_concurrency += 1
722
+ # max_concurrent_calls = max(max_concurrent_calls, current_concurrency)
723
+ # await asyncio.sleep(0.1) # Simulate async work
724
+ # current_concurrency -= 1
739
725
 
740
- def test_throttling_behavior_sync(self):
741
- throttle_decorator = Throttle(2) # 2 seconds throttle period
726
+ # await asyncio.gather(*(test_func() for _ in range(5)))
727
+ # self.assertEqual(max_concurrent_calls, 2)
742
728
 
743
- @throttle_decorator
744
- def test_func():
745
- return time.time()
729
+ # async def test_function_completing_within_limit(self):
730
+ # @CallDecorator.max_concurrency(limit=2)
731
+ # async def test_func(x):
732
+ # await asyncio.sleep(0.1)
733
+ # return x
746
734
 
747
- first_call_time = test_func()
748
- time.sleep(1) # Sleep less than the throttle period
749
- second_call_time = test_func()
735
+ # results = await asyncio.gather(*(test_func(i) for i in range(5)))
736
+ # self.assertEqual(results, [0, 1, 2, 3, 4])
750
737
 
751
- self.assertGreaterEqual(second_call_time - first_call_time, 2) # Second call should be throttled
752
738
 
753
- def test_throttling_behavior_async(self):
754
- throttle_decorator = Throttle(2) # 2 seconds throttle period
739
+ # class TestThrottleClass(unittest.TestCase):
755
740
 
756
- @throttle_decorator
757
- async def test_func():
758
- return time.time()
741
+ # def test_throttling_behavior_sync(self):
742
+ # throttle_decorator = Throttle(2) # 2 seconds throttle period
759
743
 
760
- async def async_test():
761
- first_call_time = await test_func()
762
- await asyncio.sleep(1) # Sleep less than the throttle period
763
- second_call_time = await test_func()
744
+ # @throttle_decorator
745
+ # def test_func():
746
+ # return time.time()
764
747
 
765
- self.assertGreaterEqual(second_call_time - first_call_time, 2) # Second call should be throttled
748
+ # first_call_time = test_func()
749
+ # time.sleep(1) # Sleep less than the throttle period
750
+ # second_call_time = test_func()
766
751
 
767
- asyncio.run(async_test())
752
+ # self.assertGreaterEqual(second_call_time - first_call_time, 2) # Second call should be throttled
768
753
 
769
- def test_successive_calls_with_sufficient_delay(self):
770
- throttle_decorator = Throttle(1) # 1 second throttle period
754
+ # def test_throttling_behavior_async(self):
755
+ # throttle_decorator = Throttle(2) # 2 seconds throttle period
771
756
 
772
- @throttle_decorator
773
- def test_func():
774
- return time.time()
757
+ # @throttle_decorator
758
+ # async def test_func():
759
+ # return time.time()
775
760
 
776
- first_call_time = test_func()
777
- time.sleep(1.1) # Sleep more than the throttle period
778
- second_call_time = test_func()
761
+ # async def async_test():
762
+ # first_call_time = await test_func()
763
+ # await asyncio.sleep(1) # Sleep less than the throttle period
764
+ # second_call_time = await test_func()
779
765
 
780
- self.assertLess(second_call_time - first_call_time, 1.5) # Second call should not be throttled
766
+ # self.assertGreaterEqual(second_call_time - first_call_time, 2) # Second call should be throttled
781
767
 
768
+ # asyncio.run(async_test())
782
769
 
783
- if __name__ == '__main__':
784
- unittest.main()
770
+ # def test_successive_calls_with_sufficient_delay(self):
771
+ # throttle_decorator = Throttle(1) # 1 second throttle period
772
+
773
+ # @throttle_decorator
774
+ # def test_func():
775
+ # return time.time()
776
+
777
+ # first_call_time = test_func()
778
+ # time.sleep(1.1) # Sleep more than the throttle period
779
+ # second_call_time = test_func()
780
+
781
+ # self.assertLess(second_call_time - first_call_time, 1.5) # Second call should not be throttled
782
+
783
+
784
+ # if __name__ == '__main__':
785
+ # unittest.main()