quantalogic 0.61.1__py3-none-any.whl → 0.61.3__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 (31) hide show
  1. quantalogic/agent_config.py +4 -4
  2. quantalogic/codeact/agent.py +1 -1
  3. quantalogic/codeact/cli.py +5 -5
  4. quantalogic/codeact/tools_manager.py +1 -1
  5. quantalogic/coding_agent.py +1 -1
  6. quantalogic/tools/action_gen_safe.py +340 -0
  7. quantalogic/tools/write_file_tool.py +49 -43
  8. {quantalogic-0.61.1.dist-info → quantalogic-0.61.3.dist-info}/METADATA +4 -3
  9. {quantalogic-0.61.1.dist-info → quantalogic-0.61.3.dist-info}/RECORD +12 -30
  10. quantalogic/python_interpreter/__init__.py +0 -23
  11. quantalogic/python_interpreter/assignment_visitors.py +0 -63
  12. quantalogic/python_interpreter/base_visitors.py +0 -20
  13. quantalogic/python_interpreter/class_visitors.py +0 -22
  14. quantalogic/python_interpreter/comprehension_visitors.py +0 -172
  15. quantalogic/python_interpreter/context_visitors.py +0 -59
  16. quantalogic/python_interpreter/control_flow_visitors.py +0 -88
  17. quantalogic/python_interpreter/exception_visitors.py +0 -109
  18. quantalogic/python_interpreter/exceptions.py +0 -39
  19. quantalogic/python_interpreter/execution.py +0 -202
  20. quantalogic/python_interpreter/function_utils.py +0 -386
  21. quantalogic/python_interpreter/function_visitors.py +0 -209
  22. quantalogic/python_interpreter/import_visitors.py +0 -28
  23. quantalogic/python_interpreter/interpreter_core.py +0 -358
  24. quantalogic/python_interpreter/literal_visitors.py +0 -74
  25. quantalogic/python_interpreter/misc_visitors.py +0 -148
  26. quantalogic/python_interpreter/operator_visitors.py +0 -108
  27. quantalogic/python_interpreter/scope.py +0 -10
  28. quantalogic/python_interpreter/visit_handlers.py +0 -110
  29. {quantalogic-0.61.1.dist-info → quantalogic-0.61.3.dist-info}/LICENSE +0 -0
  30. {quantalogic-0.61.1.dist-info → quantalogic-0.61.3.dist-info}/WHEEL +0 -0
  31. {quantalogic-0.61.1.dist-info → quantalogic-0.61.3.dist-info}/entry_points.txt +0 -0
@@ -1,10 +1,10 @@
1
1
  quantalogic/__init__.py,sha256=qFbvfHOd_chAu536pH816E3uo6CdyAgXCpQOwMXXVnY,1076
2
2
  quantalogic/agent.py,sha256=VChZXFLEsIIrBtXVQZ-FGZ72GCUXDL3g9br8Vo1t5V8,75072
3
- quantalogic/agent_config.py,sha256=65dvgJ1rwC0eEysMtTv_Dsjln4WS0IvAIcn6r39Zq4k,8222
3
+ quantalogic/agent_config.py,sha256=HNXHmu3BiT4q9i-L2wJKUh6PuiZ_ryTNaB7ga24kaJo,8334
4
4
  quantalogic/agent_factory.py,sha256=soActorasOqs5g6NmlyeEjRYbJceIGGg7wuUS-vA898,6878
5
5
  quantalogic/codeact/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- quantalogic/codeact/agent.py,sha256=oajib7OsfBp230sg_IjmknqYsFz_lSURC39fj5brsP4,22454
7
- quantalogic/codeact/cli.py,sha256=FBqnqPUobq6ySuTL9oTLyXSenHC6V7wsCWAbNDK_xec,10810
6
+ quantalogic/codeact/agent.py,sha256=lF5Cq9e_XrBrGwhEZoNNbV-FxAMM2S12_u2og5W4994,22445
7
+ quantalogic/codeact/cli.py,sha256=Nxo5Biv08yvA72c860ikKI6Ebp0vlygoVrIMCpYsSxA,10867
8
8
  quantalogic/codeact/constants.py,sha256=_xJ2QwP5wUE9vwSDm0JTSMC4GVjXAaxHTwcZBjDCoKk,244
9
9
  quantalogic/codeact/events.py,sha256=4itxGsz54Te9vim13JC8QhacnLQ8cqtOOIyOWUrKFi0,1530
10
10
  quantalogic/codeact/llm_util.py,sha256=9HqN0prWyAgdt6FYtdzjWoIoPpDavHQ7EIIfJr2Fi8w,2749
@@ -12,9 +12,9 @@ quantalogic/codeact/prompts/error_format.j2,sha256=_8fNWxDr3U1Fq8SdzwRIBNsNG1WvP
12
12
  quantalogic/codeact/prompts/generate_action.j2,sha256=v0LXFxz6L2EwIPesu_mYSVqyNctjHOCIfdawHCb2rtc,1289
13
13
  quantalogic/codeact/prompts/generate_program.j2,sha256=05_1bAwIJLLBKt4o9c7sRWLHIoiHPyGl9OquieMZT5g,2048
14
14
  quantalogic/codeact/prompts/response_format.j2,sha256=TwO43dEG-3justNigpX4yyzGR1TGS3YDlpJQq8Z5Vf4,355
15
- quantalogic/codeact/tools_manager.py,sha256=l2cpHLuQP-MW0uP8d2e6IdMToeveaIOdilwDGPjPciY,4464
15
+ quantalogic/codeact/tools_manager.py,sha256=Q_BGtqN3E8QGbobtaYMpQXqqTv_eb5HmIoZelleUMeI,4491
16
16
  quantalogic/codeact/utils.py,sha256=B7Xowk4id6Sgoyl0eBJsi6JiKa-BAwnj0a5z70vrV1M,5308
17
- quantalogic/coding_agent.py,sha256=i4QYY1Q7AXfJFCVfrowxukH33nuqByUOX6bt-hAcGDE,5504
17
+ quantalogic/coding_agent.py,sha256=WFfabRwwPZFV3Pw3seLKpSrFE9Li4pz8Z8mCdsUIDi8,5532
18
18
  quantalogic/config.py,sha256=bmPI2rvQ9M8Zdl1H7K588JgJdnkxSE0L5_i5aBqsagA,564
19
19
  quantalogic/console_print_events.py,sha256=yDtfOr7s5r_gLTgwkl_XoKSkUqNRZhqqq4hwR_oJsUw,2050
20
20
  quantalogic/console_print_token.py,sha256=5IRVoPhwWZtSc4LpNoAsCQhCB_RnAW9chycGgyD3_5U,437
@@ -57,25 +57,6 @@ quantalogic/prompts/task_summary_prompt.j2,sha256=fcjV96nqi6jsfR8l6uyep20rCaOi-z
57
57
  quantalogic/prompts/tools_prompt.j2,sha256=ZjvTAZtAk-FmzDb1QuyDJg1hzo-FqayQ7wN_ytHAi2s,385
58
58
  quantalogic/prompts/variables_prompt.j2,sha256=N3OsMbzy3PfEUqYZVF_34wVidhh2ghVToSgdRCv2qgM,231
59
59
  quantalogic/prompts.py,sha256=zqmyosq4hdYpzHI-FG0m5CKV2wQnjgyMJf6Vo1ZaLW4,1982
60
- quantalogic/python_interpreter/__init__.py,sha256=cNYxH9jy5QEAPZo44zmJzy3Kci14e0lL2h20Cbrs7RQ,675
61
- quantalogic/python_interpreter/assignment_visitors.py,sha256=t6ttdYuwjcz8VtqJS5vMaaUUG6GbEhoNmnNDUj8dZiI,2771
62
- quantalogic/python_interpreter/base_visitors.py,sha256=aD1pc3DbdlPdjQ3yJTYhBqNpN6tant7NOHXShts8coo,765
63
- quantalogic/python_interpreter/class_visitors.py,sha256=FUgBVg_TmpAdLdLlYlPnruSm8iViijW3gTBQveJjkpI,862
64
- quantalogic/python_interpreter/comprehension_visitors.py,sha256=AdPn047QUeoG5D1VD4wU2JuXS2KBTwLOIGbApmx9s7A,8468
65
- quantalogic/python_interpreter/context_visitors.py,sha256=_4-Xfk0wzsla2rSIJZYEyYK4yIK7yRZWX6-HNBFSWTs,2137
66
- quantalogic/python_interpreter/control_flow_visitors.py,sha256=trJ0Led1pPWKyseQF7BbIF5LFopkOiRDSVHz9Hi7-hI,3662
67
- quantalogic/python_interpreter/exception_visitors.py,sha256=dbRuk2CaEZN-tYrzcRxZQh_UdLfpcW7wwrG8iQoGeE8,4571
68
- quantalogic/python_interpreter/exceptions.py,sha256=mL4G9a0PZrvW_hAjkweMohvN8ryZsZOiIOolZUDSq9Y,1296
69
- quantalogic/python_interpreter/execution.py,sha256=bggzv-GMnFe0Pkt00T4IlPUnDMsuqcHO1Qo0Wq6rEbs,8420
70
- quantalogic/python_interpreter/function_utils.py,sha256=1LCEqCDt0p0uBTeC6rcre84r_j06jc6HuWLZ5Fc8m8M,18133
71
- quantalogic/python_interpreter/function_visitors.py,sha256=WcGBWXZ_A7vekkrejL2XTuVPyqsKymK4svJr6-kR-OI,11317
72
- quantalogic/python_interpreter/import_visitors.py,sha256=AgqFM8SO1wuJluDRsDGBwm-FQ5K374pQrXgbXXEBgPI,1331
73
- quantalogic/python_interpreter/interpreter_core.py,sha256=PV_XFx0xhUG9ACvhz3FGat2FSaXK3C031HjRizHbox0,16646
74
- quantalogic/python_interpreter/literal_visitors.py,sha256=TX9-02rn093OFTDvKkhp0PbTsXqIU1voBfbxs-TXfu0,3715
75
- quantalogic/python_interpreter/misc_visitors.py,sha256=_olOaGD04icqKDqeEFUPIY5Nq0cH5pdGkq-8T6xbilM,6758
76
- quantalogic/python_interpreter/operator_visitors.py,sha256=WTf4EfwE88lMoTKjuL8UBNpbwJ8Z6DTdrwvVffVw-Ic,4048
77
- quantalogic/python_interpreter/scope.py,sha256=HSSbtDAMeDbE5LjSckTHvFlhcOUGv8UzxpI4NgUbp5U,257
78
- quantalogic/python_interpreter/visit_handlers.py,sha256=dGh7BxwGArnBnmwxVzpV6l_uXQ5J6esUm2xKtXne30M,2610
79
60
  quantalogic/quantlitellm.py,sha256=nf-awyOxP0ANoAPGHNvHfdLu8gNn65L39gl7x4saIQc,5550
80
61
  quantalogic/search_agent.py,sha256=tr0cwscJ4wu_G1aumjFyvGHQ0eQv5OL5sxj17s6Ocls,2470
81
62
  quantalogic/server/__init__.py,sha256=8sz_PYAUCrkM6JM5EAUeIzNM4NPW6j6UT72JVkc21WQ,91
@@ -91,6 +72,7 @@ quantalogic/task_runner.py,sha256=NB7TqNuwCstCAsTkjGcJSQRapNk8-iXe7d_2qf-fs1s,15
91
72
  quantalogic/tool_manager.py,sha256=vNA7aBKgdU3wpw_goom6i9rg_64pNZapNxvg4cUhhCI,6983
92
73
  quantalogic/tools/__init__.py,sha256=NU_M6VYYaAbSUtb2Qdu1lsYaDh0G3f_8jnrZTsBD0eY,2390
93
74
  quantalogic/tools/action_gen.py,sha256=M16voPq7tMR1qiCKTaZAusmVchFbBIluuBbLQH9kEG4,15580
75
+ quantalogic/tools/action_gen_safe.py,sha256=7doUtPnV9oxBc02N_N-xcMxmfT9Nd6gHfkNU7MtwVUk,13996
94
76
  quantalogic/tools/agent_tool.py,sha256=MXCXxWHRch7VK4UWhtRP1jeI8Np9Ne2CUGo8vm1oZiM,3064
95
77
  quantalogic/tools/composio/__init__.py,sha256=Yo9ygNx0qQILVhIfRgqpO8fgnCgp5WoZMd3Hm5D20GY,429
96
78
  quantalogic/tools/composio/composio.py,sha256=icVHA_Scr1pViBhahGGBGBRBl9JSB3hGSqpgQzAIUH8,17627
@@ -188,7 +170,7 @@ quantalogic/tools/utils/generate_database_report.py,sha256=IU_XGTDNXfJXxzpHR1F4c
188
170
  quantalogic/tools/web_navigation/__init__.py,sha256=O7SkVqbGwN4zt8Sm3H8AHF9451FSgI5h0J3fDj1rFS4,142
189
171
  quantalogic/tools/web_navigation/web_tool.py,sha256=AxAxQLUNwCElqxP2ceOOjHVY80ck-Md-uNsjHdR9ErA,4721
190
172
  quantalogic/tools/wikipedia_search_tool.py,sha256=LXQSPH8961Efw2QNxKe-cD5ZiIYD3ufEgrxH4y5uB74,5180
191
- quantalogic/tools/write_file_tool.py,sha256=qyRhDwE77rakRb_CuAC00V0E2vqIRNxwKD4PHLGgyW8,5230
173
+ quantalogic/tools/write_file_tool.py,sha256=cOheTr2ZTWNbPHlB1PRhc1btJ2mW8TvE5PLQFIdbUb8,5578
192
174
  quantalogic/utils/__init__.py,sha256=E442CJQuTohKzgI0Wrd4NZEpKascFjz6F4Vy8Y1c_0Y,634
193
175
  quantalogic/utils/ask_user_validation.py,sha256=kSr7TXPTpsLR9zgwpGWgvffx8-cKAC_rdFRdLqwC22A,1176
194
176
  quantalogic/utils/async_utils.py,sha256=FOizWRbHdsZwoD36dNErzunfwPlE7zDprS6RXcWuWSo,963
@@ -209,8 +191,8 @@ quantalogic/version_check.py,sha256=JyQFTNMDWtpHCLnN-BiakzB2cyXf6kUFsTjvmSruZi4,
209
191
  quantalogic/welcome_message.py,sha256=o4tHdgabNuIV9kbIDPgS3_2yzJhayK30oKad2UouYDc,3020
210
192
  quantalogic/xml_parser.py,sha256=bLLwIwO-VEHWF3heNS7nuPC8wgdYw9F_fVZZNW1figY,11728
211
193
  quantalogic/xml_tool_parser.py,sha256=hGHA1q20JUoTNTbZYmi4FTdA5I25-AGEIP8DwZgQCNA,3897
212
- quantalogic-0.61.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
213
- quantalogic-0.61.1.dist-info/METADATA,sha256=k40t7hc00o09Fz4lEn4bqdk4XIOQRKIrRg6Jg3U0QoU,32998
214
- quantalogic-0.61.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
215
- quantalogic-0.61.1.dist-info/entry_points.txt,sha256=h74O_Q3qBRCrDR99qvwB4BpBGzASPUIjCfxHq6Qnups,183
216
- quantalogic-0.61.1.dist-info/RECORD,,
194
+ quantalogic-0.61.3.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
195
+ quantalogic-0.61.3.dist-info/METADATA,sha256=6VPi8J-lWUhZsEKVuCKFuJaWChJ2bHRO6qCQN47I_Cw,33029
196
+ quantalogic-0.61.3.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
197
+ quantalogic-0.61.3.dist-info/entry_points.txt,sha256=h74O_Q3qBRCrDR99qvwB4BpBGzASPUIjCfxHq6Qnups,183
198
+ quantalogic-0.61.3.dist-info/RECORD,,
@@ -1,23 +0,0 @@
1
- # quantalogic/utils/__init__.py
2
- from .exceptions import BreakException, ContinueException, ReturnException, WrappedException, has_await
3
- from .execution import AsyncExecutionResult, execute_async, interpret_ast, interpret_code
4
- from .function_utils import AsyncFunction, Function, LambdaFunction
5
- from .interpreter_core import ASTInterpreter
6
- from .scope import Scope
7
-
8
- __all__ = [
9
- 'ASTInterpreter',
10
- 'execute_async',
11
- 'interpret_ast',
12
- 'interpret_code',
13
- 'AsyncExecutionResult',
14
- 'ReturnException',
15
- 'BreakException',
16
- 'ContinueException',
17
- 'WrappedException',
18
- 'has_await',
19
- 'Function',
20
- 'AsyncFunction',
21
- 'LambdaFunction',
22
- 'Scope',
23
- ]
@@ -1,63 +0,0 @@
1
- import ast
2
- from typing import Any
3
-
4
- from .interpreter_core import ASTInterpreter
5
-
6
- async def visit_Assign(self: ASTInterpreter, node: ast.Assign, wrap_exceptions: bool = True) -> None:
7
- value: Any = await self.visit(node.value, wrap_exceptions=wrap_exceptions)
8
- for target in node.targets:
9
- if isinstance(target, ast.Subscript):
10
- obj = await self.visit(target.value, wrap_exceptions=wrap_exceptions)
11
- key = await self.visit(target.slice, wrap_exceptions=wrap_exceptions)
12
- obj[key] = value
13
- else:
14
- await self.assign(target, value)
15
-
16
- async def visit_AugAssign(self: ASTInterpreter, node: ast.AugAssign, wrap_exceptions: bool = True) -> Any:
17
- if isinstance(node.target, ast.Name):
18
- current_val: Any = self.get_variable(node.target.id)
19
- else:
20
- current_val: Any = await self.visit(node.target, wrap_exceptions=wrap_exceptions)
21
- right_val: Any = await self.visit(node.value, wrap_exceptions=wrap_exceptions)
22
- op = node.op
23
- if isinstance(op, ast.Add):
24
- result: Any = current_val + right_val
25
- elif isinstance(op, ast.Sub):
26
- result = current_val - right_val
27
- elif isinstance(op, ast.Mult):
28
- result = current_val * right_val
29
- elif isinstance(op, ast.Div):
30
- result = current_val / right_val
31
- elif isinstance(op, ast.FloorDiv):
32
- result = current_val // right_val
33
- elif isinstance(op, ast.Mod):
34
- result = current_val % right_val
35
- elif isinstance(op, ast.Pow):
36
- result = current_val**right_val
37
- elif isinstance(op, ast.BitAnd):
38
- result = current_val & right_val
39
- elif isinstance(op, ast.BitOr):
40
- result = current_val | right_val
41
- elif isinstance(op, ast.BitXor):
42
- result = current_val ^ right_val
43
- elif isinstance(op, ast.LShift):
44
- result = current_val << right_val
45
- elif isinstance(op, ast.RShift):
46
- result = current_val >> right_val
47
- else:
48
- raise Exception("Unsupported augmented operator: " + str(op))
49
- await self.assign(node.target, result)
50
- return result
51
-
52
- async def visit_AnnAssign(self: ASTInterpreter, node: ast.AnnAssign, wrap_exceptions: bool = True) -> None:
53
- value = await self.visit(node.value, wrap_exceptions=wrap_exceptions) if node.value else None
54
- annotation = await self.visit(node.annotation, wrap_exceptions=True)
55
- if isinstance(node.target, ast.Name):
56
- self.type_hints[node.target.id] = annotation
57
- if value is not None or node.simple:
58
- await self.assign(node.target, value)
59
-
60
- async def visit_NamedExpr(self: ASTInterpreter, node: ast.NamedExpr, wrap_exceptions: bool = True) -> Any:
61
- value = await self.visit(node.value, wrap_exceptions=wrap_exceptions)
62
- await self.assign(node.target, value)
63
- return value
@@ -1,20 +0,0 @@
1
- import ast
2
- from typing import Any
3
-
4
- from .exceptions import WrappedException
5
- from .interpreter_core import ASTInterpreter
6
-
7
- async def visit_Module(self: ASTInterpreter, node: ast.Module, wrap_exceptions: bool = True) -> Any:
8
- last_value = None
9
- for stmt in node.body:
10
- last_value = await self.visit(stmt, wrap_exceptions=True)
11
- return last_value
12
-
13
- async def visit_Expr(self: ASTInterpreter, node: ast.Expr, wrap_exceptions: bool = True) -> Any:
14
- return await self.visit(node.value, wrap_exceptions=wrap_exceptions)
15
-
16
- async def visit_Pass(self: ASTInterpreter, node: ast.Pass, wrap_exceptions: bool = True) -> None:
17
- return None
18
-
19
- async def visit_TypeIgnore(self: ASTInterpreter, node: ast.TypeIgnore, wrap_exceptions: bool = True) -> None:
20
- pass
@@ -1,22 +0,0 @@
1
- import ast
2
- from typing import Any, Dict, List
3
-
4
- from .function_utils import Function
5
- from .interpreter_core import ASTInterpreter
6
-
7
- async def visit_ClassDef(self: ASTInterpreter, node: ast.ClassDef, wrap_exceptions: bool = True) -> Any:
8
- base_frame = {}
9
- self.env_stack.append(base_frame)
10
- bases = [await self.visit(base, wrap_exceptions=True) for base in node.bases]
11
- try:
12
- for stmt in node.body:
13
- await self.visit(stmt, wrap_exceptions=True)
14
- class_dict = {k: v for k, v in self.env_stack[-1].items() if k not in ["__builtins__"]}
15
- cls = type(node.name, tuple(bases), class_dict)
16
- for name, value in class_dict.items():
17
- if isinstance(value, Function):
18
- value.defining_class = cls
19
- self.env_stack[-2][node.name] = cls
20
- return cls
21
- finally:
22
- self.env_stack.pop()
@@ -1,172 +0,0 @@
1
- import ast
2
- from typing import Any, Dict, List
3
-
4
- from .interpreter_core import ASTInterpreter
5
- from .exceptions import WrappedException
6
-
7
- async def visit_ListComp(self: ASTInterpreter, node: ast.ListComp, wrap_exceptions: bool = True) -> List[Any]:
8
- result = []
9
- base_frame = self.env_stack[-1].copy()
10
- self.env_stack.append(base_frame)
11
-
12
- async def rec(gen_idx: int):
13
- if gen_idx == len(node.generators):
14
- element = await self.visit(node.elt, wrap_exceptions=wrap_exceptions)
15
- result.append(element)
16
- else:
17
- comp = node.generators[gen_idx]
18
- iterable = await self.visit(comp.iter, wrap_exceptions=wrap_exceptions)
19
- if hasattr(iterable, '__aiter__'):
20
- async for item in iterable:
21
- new_frame = self.env_stack[-1].copy()
22
- self.env_stack.append(new_frame)
23
- await self.assign(comp.target, item)
24
- conditions = [await self.visit(if_clause, wrap_exceptions=True) for if_clause in comp.ifs]
25
- if all(conditions):
26
- await rec(gen_idx + 1)
27
- self.env_stack.pop()
28
- else:
29
- try:
30
- for item in iterable:
31
- new_frame = self.env_stack[-1].copy()
32
- self.env_stack.append(new_frame)
33
- await self.assign(comp.target, item)
34
- conditions = [await self.visit(if_clause, wrap_exceptions=True) for if_clause in comp.ifs]
35
- if all(conditions):
36
- await rec(gen_idx + 1)
37
- self.env_stack.pop()
38
- except TypeError as e:
39
- lineno = getattr(node, "lineno", 1)
40
- col = getattr(node, "col_offset", 0)
41
- context_line = self.source_lines[lineno - 1] if self.source_lines and lineno <= len(self.source_lines) else ""
42
- raise WrappedException(f"Object {iterable} is not iterable", e, lineno, col, context_line) from e
43
-
44
- await rec(0)
45
- self.env_stack.pop()
46
- return result
47
-
48
- async def visit_DictComp(self: ASTInterpreter, node: ast.DictComp, wrap_exceptions: bool = True) -> Dict[Any, Any]:
49
- result = {}
50
- base_frame = self.env_stack[-1].copy()
51
- self.env_stack.append(base_frame)
52
-
53
- async def rec(gen_idx: int):
54
- if gen_idx == len(node.generators):
55
- key = await self.visit(node.key, wrap_exceptions=True)
56
- val = await self.visit(node.value, wrap_exceptions=True)
57
- result[key] = val
58
- else:
59
- comp = node.generators[gen_idx]
60
- iterable = await self.visit(comp.iter, wrap_exceptions=wrap_exceptions)
61
- if hasattr(iterable, '__aiter__'):
62
- async for item in iterable:
63
- new_frame = self.env_stack[-1].copy()
64
- self.env_stack.append(new_frame)
65
- await self.assign(comp.target, item)
66
- conditions = [await self.visit(if_clause, wrap_exceptions=True) for if_clause in comp.ifs]
67
- if all(conditions):
68
- await rec(gen_idx + 1)
69
- self.env_stack.pop()
70
- else:
71
- try:
72
- for item in iterable:
73
- new_frame = self.env_stack[-1].copy()
74
- self.env_stack.append(new_frame)
75
- await self.assign(comp.target, item)
76
- conditions = [await self.visit(if_clause, wrap_exceptions=True) for if_clause in comp.ifs]
77
- if all(conditions):
78
- await rec(gen_idx + 1)
79
- self.env_stack.pop()
80
- except TypeError as e:
81
- lineno = getattr(node, "lineno", 1)
82
- col = getattr(node, "col_offset", 0)
83
- context_line = self.source_lines[lineno - 1] if self.source_lines and lineno <= len(self.source_lines) else ""
84
- raise WrappedException(f"Object {iterable} is not iterable", e, lineno, col, context_line) from e
85
-
86
- await rec(0)
87
- self.env_stack.pop()
88
- return result
89
-
90
- async def visit_SetComp(self: ASTInterpreter, node: ast.SetComp, wrap_exceptions: bool = True) -> set:
91
- result = set()
92
- base_frame = self.env_stack[-1].copy()
93
- self.env_stack.append(base_frame)
94
-
95
- async def rec(gen_idx: int):
96
- if gen_idx == len(node.generators):
97
- result.add(await self.visit(node.elt, wrap_exceptions=True))
98
- else:
99
- comp = node.generators[gen_idx]
100
- iterable = await self.visit(comp.iter, wrap_exceptions=wrap_exceptions)
101
- if hasattr(iterable, '__aiter__'):
102
- async for item in iterable:
103
- new_frame = self.env_stack[-1].copy()
104
- self.env_stack.append(new_frame)
105
- await self.assign(comp.target, item)
106
- conditions = [await self.visit(if_clause, wrap_exceptions=True) for if_clause in comp.ifs]
107
- if all(conditions):
108
- await rec(gen_idx + 1)
109
- self.env_stack.pop()
110
- else:
111
- try:
112
- for item in iterable:
113
- new_frame = self.env_stack[-1].copy()
114
- self.env_stack.append(new_frame)
115
- await self.assign(comp.target, item)
116
- conditions = [await self.visit(if_clause, wrap_exceptions=True) for if_clause in comp.ifs]
117
- if all(conditions):
118
- await rec(gen_idx + 1)
119
- self.env_stack.pop()
120
- except TypeError as e:
121
- lineno = getattr(node, "lineno", 1)
122
- col = getattr(node, "col_offset", 0)
123
- context_line = self.source_lines[lineno - 1] if self.source_lines and lineno <= len(self.source_lines) else ""
124
- raise WrappedException(f"Object {iterable} is not iterable", e, lineno, col, context_line) from e
125
-
126
- await rec(0)
127
- self.env_stack.pop()
128
- return result
129
-
130
- async def visit_GeneratorExp(self: ASTInterpreter, node: ast.GeneratorExp, wrap_exceptions: bool = True) -> Any:
131
- base_frame: Dict[str, Any] = self.env_stack[-1].copy()
132
- self.env_stack.append(base_frame)
133
-
134
- async def gen():
135
- async def rec(gen_idx: int):
136
- if gen_idx == len(node.generators):
137
- yield await self.visit(node.elt, wrap_exceptions=True)
138
- else:
139
- comp = node.generators[gen_idx]
140
- iterable = await self.visit(comp.iter, wrap_exceptions=wrap_exceptions)
141
- if hasattr(iterable, '__aiter__'):
142
- async for item in iterable:
143
- new_frame = self.env_stack[-1].copy()
144
- self.env_stack.append(new_frame)
145
- await self.assign(comp.target, item)
146
- conditions = [await self.visit(if_clause, wrap_exceptions=True) for if_clause in comp.ifs]
147
- if all(conditions):
148
- async for val in rec(gen_idx + 1):
149
- yield val
150
- self.env_stack.pop()
151
- else:
152
- try:
153
- for item in iterable:
154
- new_frame = self.env_stack[-1].copy()
155
- self.env_stack.append(new_frame)
156
- await self.assign(comp.target, item)
157
- conditions = [await self.visit(if_clause, wrap_exceptions=True) for if_clause in comp.ifs]
158
- if all(conditions):
159
- async for val in rec(gen_idx + 1):
160
- yield val
161
- self.env_stack.pop()
162
- except TypeError as e:
163
- lineno = getattr(node, "lineno", 1)
164
- col = getattr(node, "col_offset", 0)
165
- context_line = self.source_lines[lineno - 1] if self.source_lines and lineno <= len(self.source_lines) else ""
166
- raise WrappedException(f"Object {iterable} is not iterable", e, lineno, col, context_line) from e
167
-
168
- async for val in rec(0):
169
- yield val
170
-
171
- self.env_stack.pop()
172
- return gen()
@@ -1,59 +0,0 @@
1
- import ast
2
- from typing import Any
3
-
4
- from .exceptions import ReturnException
5
- from .interpreter_core import ASTInterpreter
6
-
7
- async def visit_With(self: ASTInterpreter, node: ast.With, wrap_exceptions: bool = True) -> Any:
8
- result = None
9
- contexts = []
10
- for item in node.items:
11
- ctx = await self.visit(item.context_expr, wrap_exceptions=wrap_exceptions)
12
- val = ctx.__enter__()
13
- contexts.append((ctx, val))
14
- if item.optional_vars:
15
- await self.assign(item.optional_vars, val)
16
- try:
17
- for stmt in node.body:
18
- result = await self.visit(stmt, wrap_exceptions=wrap_exceptions)
19
- except ReturnException as ret:
20
- for ctx, _ in reversed(contexts):
21
- ctx.__exit__(None, None, None)
22
- raise ret
23
- except Exception as e:
24
- exc_type, exc_value, tb = type(e), e, e.__traceback__
25
- for ctx, _ in reversed(contexts):
26
- if not ctx.__exit__(exc_type, exc_value, tb):
27
- raise
28
- raise
29
- else:
30
- for ctx, _ in reversed(contexts):
31
- ctx.__exit__(None, None, None)
32
- return result
33
-
34
- async def visit_AsyncWith(self: ASTInterpreter, node: ast.AsyncWith, wrap_exceptions: bool = True) -> Any:
35
- result = None
36
- contexts = []
37
- for item in node.items:
38
- ctx = await self.visit(item.context_expr, wrap_exceptions=wrap_exceptions)
39
- val = await ctx.__aenter__()
40
- contexts.append((ctx, val))
41
- if item.optional_vars:
42
- await self.assign(item.optional_vars, val)
43
- try:
44
- for stmt in node.body:
45
- result = await self.visit(stmt, wrap_exceptions=wrap_exceptions)
46
- except ReturnException as ret:
47
- for ctx, _ in reversed(contexts):
48
- await ctx.__aexit__(None, None, None)
49
- raise ret
50
- except Exception as e:
51
- exc_type, exc_value, tb = type(e), e, e.__traceback__
52
- for ctx, _ in reversed(contexts):
53
- if not await ctx.__aexit__(exc_type, exc_value, tb):
54
- raise
55
- raise
56
- else:
57
- for ctx, _ in reversed(contexts):
58
- await ctx.__aexit__(None, None, None)
59
- return result
@@ -1,88 +0,0 @@
1
- import ast
2
- from typing import Any
3
-
4
- from .exceptions import BreakException, ContinueException, ReturnException
5
- from .interpreter_core import ASTInterpreter
6
-
7
- async def visit_If(self: ASTInterpreter, node: ast.If, wrap_exceptions: bool = True) -> Any:
8
- if await self.visit(node.test, wrap_exceptions=wrap_exceptions):
9
- branch = node.body
10
- else:
11
- branch = node.orelse
12
- result = None
13
- if branch:
14
- for stmt in branch[:-1]:
15
- await self.visit(stmt, wrap_exceptions=wrap_exceptions)
16
- result = await self.visit(branch[-1], wrap_exceptions=wrap_exceptions)
17
- return result
18
-
19
- async def visit_While(self: ASTInterpreter, node: ast.While, wrap_exceptions: bool = True) -> None:
20
- while await self.visit(node.test, wrap_exceptions=wrap_exceptions):
21
- try:
22
- for stmt in node.body:
23
- await self.visit(stmt, wrap_exceptions=wrap_exceptions)
24
- except BreakException:
25
- break
26
- except ContinueException:
27
- continue
28
- for stmt in node.orelse:
29
- await self.visit(stmt, wrap_exceptions=wrap_exceptions)
30
-
31
- async def visit_For(self: ASTInterpreter, node: ast.For, wrap_exceptions: bool = True) -> None:
32
- iter_obj: Any = await self.visit(node.iter, wrap_exceptions=wrap_exceptions)
33
- broke = False
34
- if hasattr(iter_obj, '__aiter__'):
35
- async for item in iter_obj:
36
- await self.assign(node.target, item)
37
- try:
38
- for stmt in node.body:
39
- await self.visit(stmt, wrap_exceptions=wrap_exceptions)
40
- except BreakException:
41
- broke = True
42
- break
43
- except ContinueException:
44
- continue
45
- else:
46
- for item in iter_obj:
47
- await self.assign(node.target, item)
48
- try:
49
- for stmt in node.body:
50
- await self.visit(stmt, wrap_exceptions=wrap_exceptions)
51
- except BreakException:
52
- broke = True
53
- break
54
- except ContinueException:
55
- continue
56
- if not broke:
57
- for stmt in node.orelse:
58
- await self.visit(stmt, wrap_exceptions=wrap_exceptions)
59
-
60
- async def visit_AsyncFor(self: ASTInterpreter, node: ast.AsyncFor, wrap_exceptions: bool = True) -> None:
61
- iterable = await self.visit(node.iter, wrap_exceptions=wrap_exceptions)
62
- broke = False
63
- async for value in iterable:
64
- await self.assign(node.target, value)
65
- try:
66
- for stmt in node.body:
67
- await self.visit(stmt, wrap_exceptions=wrap_exceptions)
68
- except BreakException:
69
- broke = True
70
- break
71
- except ContinueException:
72
- continue
73
- if not broke:
74
- for stmt in node.orelse:
75
- await self.visit(stmt, wrap_exceptions=wrap_exceptions)
76
-
77
- async def visit_Break(self: ASTInterpreter, node: ast.Break, wrap_exceptions: bool = True) -> None:
78
- raise BreakException()
79
-
80
- async def visit_Continue(self: ASTInterpreter, node: ast.Continue, wrap_exceptions: bool = True) -> None:
81
- raise ContinueException()
82
-
83
- async def visit_Return(self: ASTInterpreter, node: ast.Return, wrap_exceptions: bool = True) -> None:
84
- value: Any = await self.visit(node.value, wrap_exceptions=wrap_exceptions) if node.value is not None else None
85
- raise ReturnException(value)
86
-
87
- async def visit_IfExp(self: ASTInterpreter, node: ast.IfExp, wrap_exceptions: bool = True) -> Any:
88
- return await self.visit(node.body, wrap_exceptions=wrap_exceptions) if await self.visit(node.test, wrap_exceptions=wrap_exceptions) else await self.visit(node.orelse, wrap_exceptions=wrap_exceptions)
@@ -1,109 +0,0 @@
1
- import ast
2
- from typing import Any, Optional, Tuple
3
-
4
- from .exceptions import BaseExceptionGroup, ReturnException, WrappedException
5
- from .interpreter_core import ASTInterpreter
6
-
7
- async def visit_Try(self: ASTInterpreter, node: ast.Try, wrap_exceptions: bool = True) -> Any:
8
- result: Any = None
9
- try:
10
- for stmt in node.body:
11
- result = await self.visit(stmt, wrap_exceptions=False)
12
- except ReturnException as ret:
13
- raise ret
14
- except Exception as e:
15
- original_e = e.original_exception if isinstance(e, WrappedException) else e
16
- for handler in node.handlers:
17
- exc_type = await self._resolve_exception_type(handler.type)
18
- if exc_type and isinstance(original_e, exc_type):
19
- if handler.name:
20
- self.set_variable(handler.name, original_e)
21
- handler_result = None
22
- try:
23
- for stmt in handler.body:
24
- handler_result = await self.visit(stmt, wrap_exceptions=True)
25
- except ReturnException as ret:
26
- raise ret
27
- if handler_result is not None:
28
- result = handler_result
29
- break
30
- else:
31
- raise
32
- else:
33
- for stmt in node.orelse:
34
- result = await self.visit(stmt, wrap_exceptions=True)
35
- finally:
36
- for stmt in node.finalbody:
37
- await self.visit(stmt, wrap_exceptions=True)
38
- return result
39
-
40
- async def visit_TryStar(self: ASTInterpreter, node: ast.TryStar, wrap_exceptions: bool = True) -> Any:
41
- result: Any = None
42
- exc_info: Optional[Tuple] = None
43
-
44
- try:
45
- for stmt in node.body:
46
- result = await self.visit(stmt, wrap_exceptions=False)
47
- except BaseException as e:
48
- exc_info = (type(e), e, e.__traceback__)
49
- handled = False
50
- if isinstance(e, BaseExceptionGroup):
51
- remaining_exceptions = []
52
- for handler in node.handlers:
53
- if handler.type is None:
54
- exc_type = BaseException
55
- elif isinstance(handler.type, ast.Name):
56
- exc_type = self.get_variable(handler.type.id)
57
- else:
58
- exc_type = await self.visit(handler.type, wrap_exceptions=True)
59
- matching_exceptions = [ex for ex in e.exceptions if isinstance(ex, exc_type)]
60
- if matching_exceptions:
61
- if handler.name:
62
- self.set_variable(handler.name, BaseExceptionGroup("", matching_exceptions))
63
- for stmt in handler.body:
64
- result = await self.visit(stmt, wrap_exceptions=True)
65
- handled = True
66
- remaining_exceptions.extend([ex for ex in e.exceptions if not isinstance(ex, exc_type)])
67
- if remaining_exceptions and not handled:
68
- raise BaseExceptionGroup("Uncaught exceptions", remaining_exceptions)
69
- if handled:
70
- exc_info = None
71
- else:
72
- for handler in node.handlers:
73
- if handler.type is None:
74
- exc_type = BaseException
75
- elif isinstance(handler.type, ast.Name):
76
- exc_type = self.get_variable(handler.type.id)
77
- else:
78
- exc_type = await self.visit(handler.type, wrap_exceptions=True)
79
- if exc_info and issubclass(exc_info[0], exc_type):
80
- if handler.name:
81
- self.set_variable(handler.name, exc_info[1])
82
- for stmt in handler.body:
83
- result = await self.visit(stmt, wrap_exceptions=True)
84
- exc_info = None
85
- handled = True
86
- break
87
- if exc_info and not handled:
88
- raise exc_info[1]
89
- else:
90
- for stmt in node.orelse:
91
- result = await self.visit(stmt, wrap_exceptions=True)
92
- finally:
93
- for stmt in node.finalbody:
94
- try:
95
- await self.visit(stmt, wrap_exceptions=True)
96
- except ReturnException:
97
- raise
98
- except Exception:
99
- if exc_info:
100
- raise exc_info[1]
101
- raise
102
-
103
- return result
104
-
105
- async def visit_Raise(self: ASTInterpreter, node: ast.Raise, wrap_exceptions: bool = True) -> None:
106
- exc = await self.visit(node.exc, wrap_exceptions=wrap_exceptions) if node.exc else None
107
- if exc:
108
- raise exc
109
- raise Exception("Raise with no exception specified")