superacli 1.1.4 → 1.1.6

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 (961) hide show
  1. package/__tests__/adapter-schema.test.js +2 -0
  2. package/__tests__/config.test.js +62 -1
  3. package/__tests__/help-json.test.js +2 -0
  4. package/__tests__/mcp-adapter.test.js +14 -4
  5. package/__tests__/mcp-local.test.js +159 -0
  6. package/__tests__/mcp-stdio-jsonrpc.test.js +105 -0
  7. package/__tests__/monty-plugin.test.js +121 -0
  8. package/__tests__/plugin-browser-use-uninstall.test.js +23 -0
  9. package/__tests__/plugin-browser-use.test.js +77 -0
  10. package/__tests__/plugins-command.test.js +92 -1
  11. package/__tests__/plugins-learn.test.js +62 -0
  12. package/__tests__/plugins-registry.test.js +3 -1
  13. package/__tests__/resend-plugin.test.js +122 -0
  14. package/__tests__/skills.test.js +4 -0
  15. package/cli/adapter-schema.js +3 -2
  16. package/cli/adapters/mcp.js +22 -3
  17. package/cli/adapters/process.js +34 -7
  18. package/cli/config.js +27 -1
  19. package/cli/help-json.js +2 -2
  20. package/cli/mcp-diagnostics.js +152 -0
  21. package/cli/mcp-discovery.js +221 -0
  22. package/cli/mcp-local.js +267 -25
  23. package/cli/mcp-stdio-jsonrpc.js +246 -0
  24. package/cli/plugin-install-guidance.js +25 -0
  25. package/cli/plugins-command.js +86 -3
  26. package/cli/plugins-learn.js +177 -0
  27. package/cli/plugins-manager.js +3 -0
  28. package/cli/plugins-registry.js +2 -1
  29. package/cli/skills-mcp.js +102 -0
  30. package/cli/skills.js +6 -40
  31. package/cli/supercli.js +7 -2
  32. package/docs/initial/mcp-local-mode.md +35 -0
  33. package/docs/mcp-cheatsheet.md +324 -0
  34. package/docs/plugins.md +7 -0
  35. package/package.json +1 -1
  36. package/plugins/browser-use/plugin.json +23 -0
  37. package/plugins/browser-use/scripts/post-install.js +146 -0
  38. package/plugins/browser-use/scripts/post-uninstall.js +28 -0
  39. package/plugins/browser-use/skills/quickstart/SKILL.md +47 -0
  40. package/plugins/monty/README.md +49 -0
  41. package/plugins/monty/plugin.json +69 -0
  42. package/plugins/monty/scripts/post-install.js +73 -0
  43. package/plugins/monty/scripts/post-uninstall.js +23 -0
  44. package/plugins/monty/scripts/run-python.js +140 -0
  45. package/plugins/monty/scripts/setup-monty.js +27 -0
  46. package/plugins/plugins.json +29 -0
  47. package/plugins/resend/plugin.json +371 -0
  48. package/plugins/resend/scripts/post-install.js +59 -0
  49. package/plugins/resend/scripts/post-uninstall.js +23 -0
  50. package/plugins/resend/scripts/setup-resend.js +27 -0
  51. package/plugins/resend/skills/quickstart/SKILL.md +80 -0
  52. package/ref-monty/.cargo/config.toml +3 -0
  53. package/ref-monty/.claude/settings.json +60 -0
  54. package/ref-monty/.claude/skills/fastmod/SKILL.md +22 -0
  55. package/ref-monty/.claude/skills/python-playground/SKILL.md +47 -0
  56. package/ref-monty/.codecov.yml +12 -0
  57. package/ref-monty/.github/actions/build-pgo-wheel/action.yml +72 -0
  58. package/ref-monty/.github/workflows/ci.yml +776 -0
  59. package/ref-monty/.github/workflows/codspeed.yml +45 -0
  60. package/ref-monty/.github/workflows/init-npm-packages.yml +82 -0
  61. package/ref-monty/.pre-commit-config.yaml +47 -0
  62. package/ref-monty/.python-version +1 -0
  63. package/ref-monty/.rustfmt.toml +4 -0
  64. package/ref-monty/.zed/settings.json +11 -0
  65. package/ref-monty/CLAUDE.md +535 -0
  66. package/ref-monty/Cargo.lock +3798 -0
  67. package/ref-monty/Cargo.toml +87 -0
  68. package/ref-monty/LICENSE +21 -0
  69. package/ref-monty/Makefile +216 -0
  70. package/ref-monty/README.md +430 -0
  71. package/ref-monty/RELEASING.md +47 -0
  72. package/ref-monty/crates/fuzz/Cargo.toml +30 -0
  73. package/ref-monty/crates/fuzz/fuzz_targets/string_input_panic.rs +37 -0
  74. package/ref-monty/crates/fuzz/fuzz_targets/tokens_input_panic.rs +552 -0
  75. package/ref-monty/crates/monty/Cargo.toml +68 -0
  76. package/ref-monty/crates/monty/benches/main.rs +247 -0
  77. package/ref-monty/crates/monty/build.rs +10 -0
  78. package/ref-monty/crates/monty/src/args.rs +733 -0
  79. package/ref-monty/crates/monty/src/asyncio.rs +179 -0
  80. package/ref-monty/crates/monty/src/builtins/abs.rs +55 -0
  81. package/ref-monty/crates/monty/src/builtins/all.rs +30 -0
  82. package/ref-monty/crates/monty/src/builtins/any.rs +30 -0
  83. package/ref-monty/crates/monty/src/builtins/bin.rs +59 -0
  84. package/ref-monty/crates/monty/src/builtins/chr.rs +46 -0
  85. package/ref-monty/crates/monty/src/builtins/divmod.rs +164 -0
  86. package/ref-monty/crates/monty/src/builtins/enumerate.rs +52 -0
  87. package/ref-monty/crates/monty/src/builtins/filter.rs +67 -0
  88. package/ref-monty/crates/monty/src/builtins/getattr.rs +65 -0
  89. package/ref-monty/crates/monty/src/builtins/hash.rs +28 -0
  90. package/ref-monty/crates/monty/src/builtins/hex.rs +58 -0
  91. package/ref-monty/crates/monty/src/builtins/id.rs +24 -0
  92. package/ref-monty/crates/monty/src/builtins/isinstance.rs +68 -0
  93. package/ref-monty/crates/monty/src/builtins/len.rs +25 -0
  94. package/ref-monty/crates/monty/src/builtins/map.rs +98 -0
  95. package/ref-monty/crates/monty/src/builtins/min_max.rs +113 -0
  96. package/ref-monty/crates/monty/src/builtins/mod.rs +246 -0
  97. package/ref-monty/crates/monty/src/builtins/next.rs +21 -0
  98. package/ref-monty/crates/monty/src/builtins/oct.rs +59 -0
  99. package/ref-monty/crates/monty/src/builtins/ord.rs +67 -0
  100. package/ref-monty/crates/monty/src/builtins/pow.rs +365 -0
  101. package/ref-monty/crates/monty/src/builtins/print.rs +141 -0
  102. package/ref-monty/crates/monty/src/builtins/repr.rs +16 -0
  103. package/ref-monty/crates/monty/src/builtins/reversed.rs +28 -0
  104. package/ref-monty/crates/monty/src/builtins/round.rs +174 -0
  105. package/ref-monty/crates/monty/src/builtins/sorted.rs +151 -0
  106. package/ref-monty/crates/monty/src/builtins/sum.rs +66 -0
  107. package/ref-monty/crates/monty/src/builtins/type_.rs +16 -0
  108. package/ref-monty/crates/monty/src/builtins/zip.rs +77 -0
  109. package/ref-monty/crates/monty/src/bytecode/builder.rs +699 -0
  110. package/ref-monty/crates/monty/src/bytecode/code.rs +310 -0
  111. package/ref-monty/crates/monty/src/bytecode/compiler.rs +3206 -0
  112. package/ref-monty/crates/monty/src/bytecode/mod.rs +24 -0
  113. package/ref-monty/crates/monty/src/bytecode/op.rs +617 -0
  114. package/ref-monty/crates/monty/src/bytecode/vm/async_exec.rs +1058 -0
  115. package/ref-monty/crates/monty/src/bytecode/vm/attr.rs +63 -0
  116. package/ref-monty/crates/monty/src/bytecode/vm/binary.rs +487 -0
  117. package/ref-monty/crates/monty/src/bytecode/vm/call.rs +767 -0
  118. package/ref-monty/crates/monty/src/bytecode/vm/collections.rs +741 -0
  119. package/ref-monty/crates/monty/src/bytecode/vm/compare.rs +147 -0
  120. package/ref-monty/crates/monty/src/bytecode/vm/exceptions.rs +297 -0
  121. package/ref-monty/crates/monty/src/bytecode/vm/format.rs +132 -0
  122. package/ref-monty/crates/monty/src/bytecode/vm/mod.rs +1958 -0
  123. package/ref-monty/crates/monty/src/bytecode/vm/scheduler.rs +620 -0
  124. package/ref-monty/crates/monty/src/exception_private.rs +1513 -0
  125. package/ref-monty/crates/monty/src/exception_public.rs +346 -0
  126. package/ref-monty/crates/monty/src/expressions.rs +694 -0
  127. package/ref-monty/crates/monty/src/fstring.rs +854 -0
  128. package/ref-monty/crates/monty/src/function.rs +119 -0
  129. package/ref-monty/crates/monty/src/heap.rs +1073 -0
  130. package/ref-monty/crates/monty/src/heap_data.rs +985 -0
  131. package/ref-monty/crates/monty/src/heap_traits.rs +312 -0
  132. package/ref-monty/crates/monty/src/intern.rs +837 -0
  133. package/ref-monty/crates/monty/src/io.rs +106 -0
  134. package/ref-monty/crates/monty/src/lib.rs +52 -0
  135. package/ref-monty/crates/monty/src/modules/asyncio.rs +144 -0
  136. package/ref-monty/crates/monty/src/modules/math.rs +1453 -0
  137. package/ref-monty/crates/monty/src/modules/mod.rs +120 -0
  138. package/ref-monty/crates/monty/src/modules/os.rs +116 -0
  139. package/ref-monty/crates/monty/src/modules/pathlib.rs +33 -0
  140. package/ref-monty/crates/monty/src/modules/re.rs +606 -0
  141. package/ref-monty/crates/monty/src/modules/sys.rs +60 -0
  142. package/ref-monty/crates/monty/src/modules/typing.rs +70 -0
  143. package/ref-monty/crates/monty/src/namespace.rs +21 -0
  144. package/ref-monty/crates/monty/src/object.rs +1040 -0
  145. package/ref-monty/crates/monty/src/os.rs +215 -0
  146. package/ref-monty/crates/monty/src/parse.rs +1730 -0
  147. package/ref-monty/crates/monty/src/prepare.rs +3015 -0
  148. package/ref-monty/crates/monty/src/repl.rs +1109 -0
  149. package/ref-monty/crates/monty/src/resource.rs +559 -0
  150. package/ref-monty/crates/monty/src/run.rs +457 -0
  151. package/ref-monty/crates/monty/src/run_progress.rs +821 -0
  152. package/ref-monty/crates/monty/src/signature.rs +651 -0
  153. package/ref-monty/crates/monty/src/sorting.rs +100 -0
  154. package/ref-monty/crates/monty/src/types/bytes.rs +2356 -0
  155. package/ref-monty/crates/monty/src/types/dataclass.rs +345 -0
  156. package/ref-monty/crates/monty/src/types/dict.rs +879 -0
  157. package/ref-monty/crates/monty/src/types/dict_view.rs +619 -0
  158. package/ref-monty/crates/monty/src/types/iter.rs +799 -0
  159. package/ref-monty/crates/monty/src/types/list.rs +929 -0
  160. package/ref-monty/crates/monty/src/types/long_int.rs +211 -0
  161. package/ref-monty/crates/monty/src/types/mod.rs +48 -0
  162. package/ref-monty/crates/monty/src/types/module.rs +146 -0
  163. package/ref-monty/crates/monty/src/types/namedtuple.rs +261 -0
  164. package/ref-monty/crates/monty/src/types/path.rs +596 -0
  165. package/ref-monty/crates/monty/src/types/property.rs +35 -0
  166. package/ref-monty/crates/monty/src/types/py_trait.rs +322 -0
  167. package/ref-monty/crates/monty/src/types/range.rs +285 -0
  168. package/ref-monty/crates/monty/src/types/re_match.rs +522 -0
  169. package/ref-monty/crates/monty/src/types/re_pattern.rs +726 -0
  170. package/ref-monty/crates/monty/src/types/set.rs +1373 -0
  171. package/ref-monty/crates/monty/src/types/slice.rs +257 -0
  172. package/ref-monty/crates/monty/src/types/str.rs +2051 -0
  173. package/ref-monty/crates/monty/src/types/tuple.rs +376 -0
  174. package/ref-monty/crates/monty/src/types/type.rs +407 -0
  175. package/ref-monty/crates/monty/src/value.rs +2558 -0
  176. package/ref-monty/crates/monty/test_cases/args__dict_get_no_args.py +3 -0
  177. package/ref-monty/crates/monty/test_cases/args__dict_get_too_many.py +3 -0
  178. package/ref-monty/crates/monty/test_cases/args__dict_items_with_args.py +3 -0
  179. package/ref-monty/crates/monty/test_cases/args__dict_keys_with_args.py +3 -0
  180. package/ref-monty/crates/monty/test_cases/args__dict_pop_no_args.py +3 -0
  181. package/ref-monty/crates/monty/test_cases/args__dict_pop_too_many.py +3 -0
  182. package/ref-monty/crates/monty/test_cases/args__dict_values_with_args.py +3 -0
  183. package/ref-monty/crates/monty/test_cases/args__id_too_many.py +2 -0
  184. package/ref-monty/crates/monty/test_cases/args__len_no_args.py +2 -0
  185. package/ref-monty/crates/monty/test_cases/args__len_too_many.py +2 -0
  186. package/ref-monty/crates/monty/test_cases/args__len_type_error_int.py +9 -0
  187. package/ref-monty/crates/monty/test_cases/args__len_type_error_none.py +9 -0
  188. package/ref-monty/crates/monty/test_cases/args__list_append_no_args.py +3 -0
  189. package/ref-monty/crates/monty/test_cases/args__list_append_too_many.py +3 -0
  190. package/ref-monty/crates/monty/test_cases/args__list_insert_too_few.py +3 -0
  191. package/ref-monty/crates/monty/test_cases/args__list_insert_too_many.py +3 -0
  192. package/ref-monty/crates/monty/test_cases/args__repr_no_args.py +2 -0
  193. package/ref-monty/crates/monty/test_cases/arith__div_zero_float.py +2 -0
  194. package/ref-monty/crates/monty/test_cases/arith__div_zero_int.py +2 -0
  195. package/ref-monty/crates/monty/test_cases/arith__floordiv_zero_float.py +2 -0
  196. package/ref-monty/crates/monty/test_cases/arith__floordiv_zero_int.py +2 -0
  197. package/ref-monty/crates/monty/test_cases/arith__pow_zero_neg.py +2 -0
  198. package/ref-monty/crates/monty/test_cases/arith__pow_zero_neg_builtin.py +9 -0
  199. package/ref-monty/crates/monty/test_cases/assert__expr_fail.py +2 -0
  200. package/ref-monty/crates/monty/test_cases/assert__fail.py +2 -0
  201. package/ref-monty/crates/monty/test_cases/assert__fail_msg.py +2 -0
  202. package/ref-monty/crates/monty/test_cases/assert__fn_fail.py +3 -0
  203. package/ref-monty/crates/monty/test_cases/assert__ops.py +11 -0
  204. package/ref-monty/crates/monty/test_cases/async__asyncio_run.py +47 -0
  205. package/ref-monty/crates/monty/test_cases/async__basic.py +10 -0
  206. package/ref-monty/crates/monty/test_cases/async__closure.py +14 -0
  207. package/ref-monty/crates/monty/test_cases/async__double_await_coroutine.py +16 -0
  208. package/ref-monty/crates/monty/test_cases/async__exception.py +10 -0
  209. package/ref-monty/crates/monty/test_cases/async__ext_call.py +73 -0
  210. package/ref-monty/crates/monty/test_cases/async__gather_all.py +85 -0
  211. package/ref-monty/crates/monty/test_cases/async__nested_await.py +15 -0
  212. package/ref-monty/crates/monty/test_cases/async__nested_gather_ext.py +37 -0
  213. package/ref-monty/crates/monty/test_cases/async__not_awaitable.py +10 -0
  214. package/ref-monty/crates/monty/test_cases/async__not_imported.py +14 -0
  215. package/ref-monty/crates/monty/test_cases/async__recursion_depth_isolation.py +27 -0
  216. package/ref-monty/crates/monty/test_cases/async__return_types.py +31 -0
  217. package/ref-monty/crates/monty/test_cases/async__sequential.py +16 -0
  218. package/ref-monty/crates/monty/test_cases/async__traceback.py +19 -0
  219. package/ref-monty/crates/monty/test_cases/async__with_args.py +14 -0
  220. package/ref-monty/crates/monty/test_cases/attr__get_int_error.py +9 -0
  221. package/ref-monty/crates/monty/test_cases/attr__get_list_error.py +9 -0
  222. package/ref-monty/crates/monty/test_cases/attr__set_frozen_nonfield.py +12 -0
  223. package/ref-monty/crates/monty/test_cases/attr__set_int_error.py +10 -0
  224. package/ref-monty/crates/monty/test_cases/attr__set_list_error.py +10 -0
  225. package/ref-monty/crates/monty/test_cases/bench__kitchen_sink.py +68 -0
  226. package/ref-monty/crates/monty/test_cases/bool__ops.py +20 -0
  227. package/ref-monty/crates/monty/test_cases/builtin__add_type_error.py +2 -0
  228. package/ref-monty/crates/monty/test_cases/builtin__filter.py +62 -0
  229. package/ref-monty/crates/monty/test_cases/builtin__filter_not_iterable.py +11 -0
  230. package/ref-monty/crates/monty/test_cases/builtin__getattr.py +84 -0
  231. package/ref-monty/crates/monty/test_cases/builtin__iter_funcs.py +42 -0
  232. package/ref-monty/crates/monty/test_cases/builtin__iter_next.py +66 -0
  233. package/ref-monty/crates/monty/test_cases/builtin__map.py +74 -0
  234. package/ref-monty/crates/monty/test_cases/builtin__map_not_iterable.py +11 -0
  235. package/ref-monty/crates/monty/test_cases/builtin__math_funcs.py +154 -0
  236. package/ref-monty/crates/monty/test_cases/builtin__more_iter_funcs.py +148 -0
  237. package/ref-monty/crates/monty/test_cases/builtin__next_stop_iteration.py +10 -0
  238. package/ref-monty/crates/monty/test_cases/builtin__print_invalid_kwarg.py +9 -0
  239. package/ref-monty/crates/monty/test_cases/builtin__print_kwargs.py +12 -0
  240. package/ref-monty/crates/monty/test_cases/builtin__repr.py +3 -0
  241. package/ref-monty/crates/monty/test_cases/builtin__string_funcs.py +73 -0
  242. package/ref-monty/crates/monty/test_cases/bytes__decode_invalid_utf8.py +18 -0
  243. package/ref-monty/crates/monty/test_cases/bytes__endswith_str_error.py +10 -0
  244. package/ref-monty/crates/monty/test_cases/bytes__getitem_index_error.py +10 -0
  245. package/ref-monty/crates/monty/test_cases/bytes__index_start_gt_end.py +10 -0
  246. package/ref-monty/crates/monty/test_cases/bytes__methods.py +394 -0
  247. package/ref-monty/crates/monty/test_cases/bytes__negative_count.py +9 -0
  248. package/ref-monty/crates/monty/test_cases/bytes__ops.py +90 -0
  249. package/ref-monty/crates/monty/test_cases/bytes__startswith_str_error.py +10 -0
  250. package/ref-monty/crates/monty/test_cases/call_object.py +3 -0
  251. package/ref-monty/crates/monty/test_cases/chain_comparison__all.py +79 -0
  252. package/ref-monty/crates/monty/test_cases/closure__param_shadows_outer.py +81 -0
  253. package/ref-monty/crates/monty/test_cases/closure__pep448.py +203 -0
  254. package/ref-monty/crates/monty/test_cases/closure__undefined_nonlocal.py +13 -0
  255. package/ref-monty/crates/monty/test_cases/compare__mixed_types.py +120 -0
  256. package/ref-monty/crates/monty/test_cases/comprehension__all.py +208 -0
  257. package/ref-monty/crates/monty/test_cases/comprehension__scope.py +7 -0
  258. package/ref-monty/crates/monty/test_cases/comprehension__unbound_local.py +14 -0
  259. package/ref-monty/crates/monty/test_cases/dataclass__basic.py +238 -0
  260. package/ref-monty/crates/monty/test_cases/dataclass__call_field_error.py +12 -0
  261. package/ref-monty/crates/monty/test_cases/dataclass__frozen_set_error.py +12 -0
  262. package/ref-monty/crates/monty/test_cases/dataclass__get_missing_attr_error.py +11 -0
  263. package/ref-monty/crates/monty/test_cases/dict__get_unhashable_key.py +3 -0
  264. package/ref-monty/crates/monty/test_cases/dict__literal_unhashable_key.py +2 -0
  265. package/ref-monty/crates/monty/test_cases/dict__method_pop_missing_error.py +3 -0
  266. package/ref-monty/crates/monty/test_cases/dict__methods.py +151 -0
  267. package/ref-monty/crates/monty/test_cases/dict__ops.py +133 -0
  268. package/ref-monty/crates/monty/test_cases/dict__pop_unhashable_key.py +4 -0
  269. package/ref-monty/crates/monty/test_cases/dict__popitem_empty.py +9 -0
  270. package/ref-monty/crates/monty/test_cases/dict__subscript_missing_key.py +3 -0
  271. package/ref-monty/crates/monty/test_cases/dict__unhashable_dict_key.py +2 -0
  272. package/ref-monty/crates/monty/test_cases/dict__unhashable_list_key.py +2 -0
  273. package/ref-monty/crates/monty/test_cases/dict__unpack_type_error.py +2 -0
  274. package/ref-monty/crates/monty/test_cases/dict__views.py +165 -0
  275. package/ref-monty/crates/monty/test_cases/edge__all.py +26 -0
  276. package/ref-monty/crates/monty/test_cases/edge__float_int_mod.py +2 -0
  277. package/ref-monty/crates/monty/test_cases/edge__int_float_mod.py +2 -0
  278. package/ref-monty/crates/monty/test_cases/exc__args.py +16 -0
  279. package/ref-monty/crates/monty/test_cases/exc__str.py +15 -0
  280. package/ref-monty/crates/monty/test_cases/execute_ok__all.py +54 -0
  281. package/ref-monty/crates/monty/test_cases/execute_raise__error_instance_str.py +2 -0
  282. package/ref-monty/crates/monty/test_cases/execute_raise__error_no_args.py +2 -0
  283. package/ref-monty/crates/monty/test_cases/execute_raise__error_string_arg.py +2 -0
  284. package/ref-monty/crates/monty/test_cases/execute_raise__error_string_arg_quotes.py +2 -0
  285. package/ref-monty/crates/monty/test_cases/execute_raise__error_type.py +2 -0
  286. package/ref-monty/crates/monty/test_cases/execute_raise__raise_instance_via_var.py +4 -0
  287. package/ref-monty/crates/monty/test_cases/execute_raise__raise_list.py +2 -0
  288. package/ref-monty/crates/monty/test_cases/execute_raise__raise_number.py +2 -0
  289. package/ref-monty/crates/monty/test_cases/execute_raise__raise_type_call_via_var.py +4 -0
  290. package/ref-monty/crates/monty/test_cases/execute_raise__raise_type_direct.py +3 -0
  291. package/ref-monty/crates/monty/test_cases/execute_raise__raise_type_via_var.py +4 -0
  292. package/ref-monty/crates/monty/test_cases/ext_call__arg_side_effect_bug.py +22 -0
  293. package/ref-monty/crates/monty/test_cases/ext_call__augmented.py +17 -0
  294. package/ref-monty/crates/monty/test_cases/ext_call__augmented_refcount_bug.py +7 -0
  295. package/ref-monty/crates/monty/test_cases/ext_call__bare_raise_after_resume.py +34 -0
  296. package/ref-monty/crates/monty/test_cases/ext_call__basic.py +99 -0
  297. package/ref-monty/crates/monty/test_cases/ext_call__boolean.py +37 -0
  298. package/ref-monty/crates/monty/test_cases/ext_call__boolean_side_effect_hang.py +17 -0
  299. package/ref-monty/crates/monty/test_cases/ext_call__closure_bug.py +16 -0
  300. package/ref-monty/crates/monty/test_cases/ext_call__comparison.py +26 -0
  301. package/ref-monty/crates/monty/test_cases/ext_call__deep_call_stack.py +18 -0
  302. package/ref-monty/crates/monty/test_cases/ext_call__elif.py +171 -0
  303. package/ref-monty/crates/monty/test_cases/ext_call__exc.py +4 -0
  304. package/ref-monty/crates/monty/test_cases/ext_call__exc_deep_stack.py +39 -0
  305. package/ref-monty/crates/monty/test_cases/ext_call__exc_in_function.py +17 -0
  306. package/ref-monty/crates/monty/test_cases/ext_call__exc_nested_functions.py +31 -0
  307. package/ref-monty/crates/monty/test_cases/ext_call__ext_exc.py +171 -0
  308. package/ref-monty/crates/monty/test_cases/ext_call__for.py +114 -0
  309. package/ref-monty/crates/monty/test_cases/ext_call__fstring.py +12 -0
  310. package/ref-monty/crates/monty/test_cases/ext_call__if.py +135 -0
  311. package/ref-monty/crates/monty/test_cases/ext_call__if_condition.py +37 -0
  312. package/ref-monty/crates/monty/test_cases/ext_call__in_closure.py +14 -0
  313. package/ref-monty/crates/monty/test_cases/ext_call__in_function.py +40 -0
  314. package/ref-monty/crates/monty/test_cases/ext_call__in_function_simple.py +7 -0
  315. package/ref-monty/crates/monty/test_cases/ext_call__literals.py +17 -0
  316. package/ref-monty/crates/monty/test_cases/ext_call__multi_in_func.py +32 -0
  317. package/ref-monty/crates/monty/test_cases/ext_call__name_lookup.py +69 -0
  318. package/ref-monty/crates/monty/test_cases/ext_call__name_lookup_undefined.py +4 -0
  319. package/ref-monty/crates/monty/test_cases/ext_call__nested_calls.py +14 -0
  320. package/ref-monty/crates/monty/test_cases/ext_call__recursion_bug.py +19 -0
  321. package/ref-monty/crates/monty/test_cases/ext_call__return.py +28 -0
  322. package/ref-monty/crates/monty/test_cases/ext_call__side_effects.py +25 -0
  323. package/ref-monty/crates/monty/test_cases/ext_call__subscript.py +7 -0
  324. package/ref-monty/crates/monty/test_cases/ext_call__ternary.py +28 -0
  325. package/ref-monty/crates/monty/test_cases/ext_call__try.py +280 -0
  326. package/ref-monty/crates/monty/test_cases/ext_call__try_simple.py +10 -0
  327. package/ref-monty/crates/monty/test_cases/ext_call__unary.py +13 -0
  328. package/ref-monty/crates/monty/test_cases/frozenset__ops.py +178 -0
  329. package/ref-monty/crates/monty/test_cases/fstring__all.py +236 -0
  330. package/ref-monty/crates/monty/test_cases/fstring__error_eq_align_on_str.py +3 -0
  331. package/ref-monty/crates/monty/test_cases/fstring__error_float_f_on_str.py +3 -0
  332. package/ref-monty/crates/monty/test_cases/fstring__error_int_d_on_float.py +3 -0
  333. package/ref-monty/crates/monty/test_cases/fstring__error_int_d_on_str.py +3 -0
  334. package/ref-monty/crates/monty/test_cases/fstring__error_invalid_spec.py +4 -0
  335. package/ref-monty/crates/monty/test_cases/fstring__error_invalid_spec_dynamic.py +4 -0
  336. package/ref-monty/crates/monty/test_cases/fstring__error_invalid_spec_str.py +4 -0
  337. package/ref-monty/crates/monty/test_cases/fstring__error_str_s_on_int.py +3 -0
  338. package/ref-monty/crates/monty/test_cases/function__call_duplicate_kwargs.py +6 -0
  339. package/ref-monty/crates/monty/test_cases/function__call_unpack.py +42 -0
  340. package/ref-monty/crates/monty/test_cases/function__defaults.py +117 -0
  341. package/ref-monty/crates/monty/test_cases/function__err_duplicate_arg.py +7 -0
  342. package/ref-monty/crates/monty/test_cases/function__err_duplicate_first_arg.py +7 -0
  343. package/ref-monty/crates/monty/test_cases/function__err_duplicate_kwarg_cleanup.py +9 -0
  344. package/ref-monty/crates/monty/test_cases/function__err_kwonly_as_positional.py +7 -0
  345. package/ref-monty/crates/monty/test_cases/function__err_missing_all_posonly.py +7 -0
  346. package/ref-monty/crates/monty/test_cases/function__err_missing_heap_cleanup.py +9 -0
  347. package/ref-monty/crates/monty/test_cases/function__err_missing_kwonly.py +7 -0
  348. package/ref-monty/crates/monty/test_cases/function__err_missing_posonly_with_kwarg.py +7 -0
  349. package/ref-monty/crates/monty/test_cases/function__err_missing_with_posonly.py +7 -0
  350. package/ref-monty/crates/monty/test_cases/function__err_posonly_as_kwarg.py +7 -0
  351. package/ref-monty/crates/monty/test_cases/function__err_posonly_first_as_kwarg.py +7 -0
  352. package/ref-monty/crates/monty/test_cases/function__err_too_many_posonly.py +7 -0
  353. package/ref-monty/crates/monty/test_cases/function__err_too_many_with_kwonly.py +7 -0
  354. package/ref-monty/crates/monty/test_cases/function__err_unexpected_kwarg.py +7 -0
  355. package/ref-monty/crates/monty/test_cases/function__err_unexpected_kwarg_cleanup.py +9 -0
  356. package/ref-monty/crates/monty/test_cases/function__err_unexpected_kwarg_quote.py +13 -0
  357. package/ref-monty/crates/monty/test_cases/function__err_unexpected_kwarg_simple.py +7 -0
  358. package/ref-monty/crates/monty/test_cases/function__err_unpack_duplicate_arg.py +6 -0
  359. package/ref-monty/crates/monty/test_cases/function__err_unpack_duplicate_heap.py +8 -0
  360. package/ref-monty/crates/monty/test_cases/function__err_unpack_int.py +6 -0
  361. package/ref-monty/crates/monty/test_cases/function__err_unpack_nonstring_key.py +6 -0
  362. package/ref-monty/crates/monty/test_cases/function__err_unpack_not_mapping.py +6 -0
  363. package/ref-monty/crates/monty/test_cases/function__kwargs_unpacking.py +173 -0
  364. package/ref-monty/crates/monty/test_cases/function__ops.py +294 -0
  365. package/ref-monty/crates/monty/test_cases/function__return_none.py +42 -0
  366. package/ref-monty/crates/monty/test_cases/function__signatures.py +47 -0
  367. package/ref-monty/crates/monty/test_cases/function__too_few_args_all.py +6 -0
  368. package/ref-monty/crates/monty/test_cases/function__too_few_args_one.py +6 -0
  369. package/ref-monty/crates/monty/test_cases/function__too_few_args_two.py +6 -0
  370. package/ref-monty/crates/monty/test_cases/function__too_many_args_one.py +6 -0
  371. package/ref-monty/crates/monty/test_cases/function__too_many_args_two.py +6 -0
  372. package/ref-monty/crates/monty/test_cases/function__too_many_args_zero.py +6 -0
  373. package/ref-monty/crates/monty/test_cases/global__error_assigned_before.py +7 -0
  374. package/ref-monty/crates/monty/test_cases/global__ops.py +163 -0
  375. package/ref-monty/crates/monty/test_cases/hash__dict_unhashable.py +2 -0
  376. package/ref-monty/crates/monty/test_cases/hash__list_unhashable.py +2 -0
  377. package/ref-monty/crates/monty/test_cases/hash__ops.py +153 -0
  378. package/ref-monty/crates/monty/test_cases/id__bytes_literals_distinct.py +3 -0
  379. package/ref-monty/crates/monty/test_cases/id__int_copy_distinct.py +5 -0
  380. package/ref-monty/crates/monty/test_cases/id__is_number_is_number.py +3 -0
  381. package/ref-monty/crates/monty/test_cases/id__non_overlapping_lifetimes_distinct_types.py +10 -0
  382. package/ref-monty/crates/monty/test_cases/id__non_overlapping_lifetimes_same_types.py +6 -0
  383. package/ref-monty/crates/monty/test_cases/id__ops.py +97 -0
  384. package/ref-monty/crates/monty/test_cases/id__str_literals_same.py +3 -0
  385. package/ref-monty/crates/monty/test_cases/if__elif_else.py +207 -0
  386. package/ref-monty/crates/monty/test_cases/if__raise_elif.py +11 -0
  387. package/ref-monty/crates/monty/test_cases/if__raise_else.py +13 -0
  388. package/ref-monty/crates/monty/test_cases/if__raise_if.py +9 -0
  389. package/ref-monty/crates/monty/test_cases/if__raise_in_elif_condition.py +18 -0
  390. package/ref-monty/crates/monty/test_cases/if__raise_in_if_condition.py +16 -0
  391. package/ref-monty/crates/monty/test_cases/if_else_expr__all.py +55 -0
  392. package/ref-monty/crates/monty/test_cases/import__error_cannot_import.py +9 -0
  393. package/ref-monty/crates/monty/test_cases/import__error_module_not_found.py +9 -0
  394. package/ref-monty/crates/monty/test_cases/import__local_scope.py +68 -0
  395. package/ref-monty/crates/monty/test_cases/import__os.py +25 -0
  396. package/ref-monty/crates/monty/test_cases/import__relative_error.py +9 -0
  397. package/ref-monty/crates/monty/test_cases/import__relative_no_module_error.py +9 -0
  398. package/ref-monty/crates/monty/test_cases/import__runtime_error_when_executed.py +14 -0
  399. package/ref-monty/crates/monty/test_cases/import__star_error.py +11 -0
  400. package/ref-monty/crates/monty/test_cases/import__sys.py +47 -0
  401. package/ref-monty/crates/monty/test_cases/import__sys_monty.py +28 -0
  402. package/ref-monty/crates/monty/test_cases/import__type_checking_guard.py +37 -0
  403. package/ref-monty/crates/monty/test_cases/import__typing.py +25 -0
  404. package/ref-monty/crates/monty/test_cases/import__typing_type_ignore.py +4 -0
  405. package/ref-monty/crates/monty/test_cases/int__bigint.py +467 -0
  406. package/ref-monty/crates/monty/test_cases/int__bigint_errors.py +260 -0
  407. package/ref-monty/crates/monty/test_cases/int__ops.py +219 -0
  408. package/ref-monty/crates/monty/test_cases/int__overflow_division.py +84 -0
  409. package/ref-monty/crates/monty/test_cases/is_variant__all.py +36 -0
  410. package/ref-monty/crates/monty/test_cases/isinstance__arg2_list_error.py +2 -0
  411. package/ref-monty/crates/monty/test_cases/isinstance__arg2_type_error.py +2 -0
  412. package/ref-monty/crates/monty/test_cases/iter__dict_mutation.py +4 -0
  413. package/ref-monty/crates/monty/test_cases/iter__for.py +243 -0
  414. package/ref-monty/crates/monty/test_cases/iter__for_loop_unpacking.py +66 -0
  415. package/ref-monty/crates/monty/test_cases/iter__generator_expr.py +20 -0
  416. package/ref-monty/crates/monty/test_cases/iter__generator_expr_type.py +7 -0
  417. package/ref-monty/crates/monty/test_cases/iter__not_iterable.py +3 -0
  418. package/ref-monty/crates/monty/test_cases/lambda__all.py +145 -0
  419. package/ref-monty/crates/monty/test_cases/list__extend_not_iterable.py +7 -0
  420. package/ref-monty/crates/monty/test_cases/list__getitem_out_of_bounds.py +3 -0
  421. package/ref-monty/crates/monty/test_cases/list__index_not_found.py +9 -0
  422. package/ref-monty/crates/monty/test_cases/list__index_start_gt_end.py +10 -0
  423. package/ref-monty/crates/monty/test_cases/list__ops.py +473 -0
  424. package/ref-monty/crates/monty/test_cases/list__pop_empty.py +9 -0
  425. package/ref-monty/crates/monty/test_cases/list__pop_out_of_range.py +9 -0
  426. package/ref-monty/crates/monty/test_cases/list__pop_type_error.py +9 -0
  427. package/ref-monty/crates/monty/test_cases/list__remove_not_found.py +9 -0
  428. package/ref-monty/crates/monty/test_cases/list__setitem_dict_index.py +13 -0
  429. package/ref-monty/crates/monty/test_cases/list__setitem_huge_int_index.py +13 -0
  430. package/ref-monty/crates/monty/test_cases/list__setitem_index_error.py +10 -0
  431. package/ref-monty/crates/monty/test_cases/list__setitem_type_error.py +10 -0
  432. package/ref-monty/crates/monty/test_cases/list__unpack_type_error.py +2 -0
  433. package/ref-monty/crates/monty/test_cases/longint__index_error.py +3 -0
  434. package/ref-monty/crates/monty/test_cases/longint__repeat_error.py +3 -0
  435. package/ref-monty/crates/monty/test_cases/loop__break_continue.py +113 -0
  436. package/ref-monty/crates/monty/test_cases/loop__break_finally.py +69 -0
  437. package/ref-monty/crates/monty/test_cases/loop__break_in_function_error.py +13 -0
  438. package/ref-monty/crates/monty/test_cases/loop__break_in_if_error.py +11 -0
  439. package/ref-monty/crates/monty/test_cases/loop__break_nested_except_clears.py +55 -0
  440. package/ref-monty/crates/monty/test_cases/loop__break_outside_error.py +9 -0
  441. package/ref-monty/crates/monty/test_cases/loop__continue_finally.py +81 -0
  442. package/ref-monty/crates/monty/test_cases/loop__continue_in_function_error.py +13 -0
  443. package/ref-monty/crates/monty/test_cases/loop__continue_in_if_error.py +11 -0
  444. package/ref-monty/crates/monty/test_cases/loop__continue_nested_except_clears.py +60 -0
  445. package/ref-monty/crates/monty/test_cases/loop__continue_outside_error.py +9 -0
  446. package/ref-monty/crates/monty/test_cases/math__acos_domain_error.py +11 -0
  447. package/ref-monty/crates/monty/test_cases/math__acosh_domain_error.py +11 -0
  448. package/ref-monty/crates/monty/test_cases/math__asin_domain_error.py +11 -0
  449. package/ref-monty/crates/monty/test_cases/math__atanh_domain_error.py +11 -0
  450. package/ref-monty/crates/monty/test_cases/math__cos_inf_error.py +11 -0
  451. package/ref-monty/crates/monty/test_cases/math__cosh_overflow_error.py +11 -0
  452. package/ref-monty/crates/monty/test_cases/math__exp_overflow_error.py +11 -0
  453. package/ref-monty/crates/monty/test_cases/math__factorial_float_error.py +11 -0
  454. package/ref-monty/crates/monty/test_cases/math__factorial_negative_error.py +11 -0
  455. package/ref-monty/crates/monty/test_cases/math__floor_inf_error.py +11 -0
  456. package/ref-monty/crates/monty/test_cases/math__floor_nan_error.py +11 -0
  457. package/ref-monty/crates/monty/test_cases/math__floor_str_error.py +11 -0
  458. package/ref-monty/crates/monty/test_cases/math__fmod_inf_error.py +11 -0
  459. package/ref-monty/crates/monty/test_cases/math__gamma_neg_int_error.py +11 -0
  460. package/ref-monty/crates/monty/test_cases/math__gcd_float_error.py +11 -0
  461. package/ref-monty/crates/monty/test_cases/math__isqrt_negative_error.py +11 -0
  462. package/ref-monty/crates/monty/test_cases/math__ldexp_overflow_error.py +11 -0
  463. package/ref-monty/crates/monty/test_cases/math__log1p_domain_error.py +11 -0
  464. package/ref-monty/crates/monty/test_cases/math__log_base1_error.py +11 -0
  465. package/ref-monty/crates/monty/test_cases/math__log_zero_error.py +11 -0
  466. package/ref-monty/crates/monty/test_cases/math__module.py +1432 -0
  467. package/ref-monty/crates/monty/test_cases/math__pow_domain_error.py +11 -0
  468. package/ref-monty/crates/monty/test_cases/math__sin_inf_error.py +11 -0
  469. package/ref-monty/crates/monty/test_cases/math__sqrt_negative_error.py +11 -0
  470. package/ref-monty/crates/monty/test_cases/math__tan_inf_error.py +11 -0
  471. package/ref-monty/crates/monty/test_cases/math__trunc_str_error.py +11 -0
  472. package/ref-monty/crates/monty/test_cases/method__args_kwargs_unpacking.py +259 -0
  473. package/ref-monty/crates/monty/test_cases/name_error__unbound_local_func.py +19 -0
  474. package/ref-monty/crates/monty/test_cases/name_error__unbound_local_module.py +12 -0
  475. package/ref-monty/crates/monty/test_cases/name_error__undefined_call_chained.py +9 -0
  476. package/ref-monty/crates/monty/test_cases/name_error__undefined_call_in_expr.py +9 -0
  477. package/ref-monty/crates/monty/test_cases/name_error__undefined_call_in_function.py +16 -0
  478. package/ref-monty/crates/monty/test_cases/name_error__undefined_call_with_args.py +9 -0
  479. package/ref-monty/crates/monty/test_cases/name_error__undefined_global.py +10 -0
  480. package/ref-monty/crates/monty/test_cases/namedtuple__missing_attr.py +11 -0
  481. package/ref-monty/crates/monty/test_cases/namedtuple__ops.py +34 -0
  482. package/ref-monty/crates/monty/test_cases/nonlocal__error_module_level.py +3 -0
  483. package/ref-monty/crates/monty/test_cases/nonlocal__ops.py +353 -0
  484. package/ref-monty/crates/monty/test_cases/os__environ.py +40 -0
  485. package/ref-monty/crates/monty/test_cases/os__getenv_key_list_error.py +5 -0
  486. package/ref-monty/crates/monty/test_cases/os__getenv_key_type_error.py +5 -0
  487. package/ref-monty/crates/monty/test_cases/parse_error__complex.py +3 -0
  488. package/ref-monty/crates/monty/test_cases/pathlib__import.py +11 -0
  489. package/ref-monty/crates/monty/test_cases/pathlib__os.py +136 -0
  490. package/ref-monty/crates/monty/test_cases/pathlib__os_read_error.py +12 -0
  491. package/ref-monty/crates/monty/test_cases/pathlib__pure.py +81 -0
  492. package/ref-monty/crates/monty/test_cases/pyobject__cycle_dict_self.py +5 -0
  493. package/ref-monty/crates/monty/test_cases/pyobject__cycle_list_dict.py +6 -0
  494. package/ref-monty/crates/monty/test_cases/pyobject__cycle_list_self.py +5 -0
  495. package/ref-monty/crates/monty/test_cases/pyobject__cycle_multiple_refs.py +6 -0
  496. package/ref-monty/crates/monty/test_cases/range__error_no_args.py +2 -0
  497. package/ref-monty/crates/monty/test_cases/range__error_step_zero.py +2 -0
  498. package/ref-monty/crates/monty/test_cases/range__error_too_many_args.py +2 -0
  499. package/ref-monty/crates/monty/test_cases/range__getitem_index_error.py +10 -0
  500. package/ref-monty/crates/monty/test_cases/range__ops.py +236 -0
  501. package/ref-monty/crates/monty/test_cases/re__basic.py +756 -0
  502. package/ref-monty/crates/monty/test_cases/re__grouping.py +241 -0
  503. package/ref-monty/crates/monty/test_cases/re__match.py +148 -0
  504. package/ref-monty/crates/monty/test_cases/recursion__deep_drop.py +26 -0
  505. package/ref-monty/crates/monty/test_cases/recursion__deep_eq.py +23 -0
  506. package/ref-monty/crates/monty/test_cases/recursion__deep_hash.py +46 -0
  507. package/ref-monty/crates/monty/test_cases/recursion__deep_repr.py +12 -0
  508. package/ref-monty/crates/monty/test_cases/recursion__function_depth.py +13 -0
  509. package/ref-monty/crates/monty/test_cases/refcount__cycle_mutual_reference.py +18 -0
  510. package/ref-monty/crates/monty/test_cases/refcount__cycle_self_reference.py +12 -0
  511. package/ref-monty/crates/monty/test_cases/refcount__dict_basic.py +5 -0
  512. package/ref-monty/crates/monty/test_cases/refcount__dict_get.py +5 -0
  513. package/ref-monty/crates/monty/test_cases/refcount__dict_keys_and.py +14 -0
  514. package/ref-monty/crates/monty/test_cases/refcount__dict_overwrite.py +6 -0
  515. package/ref-monty/crates/monty/test_cases/refcount__gather_cleanup.py +16 -0
  516. package/ref-monty/crates/monty/test_cases/refcount__gather_exception.py +18 -0
  517. package/ref-monty/crates/monty/test_cases/refcount__gather_nested_cancel.py +25 -0
  518. package/ref-monty/crates/monty/test_cases/refcount__immediate_skipped.py +4 -0
  519. package/ref-monty/crates/monty/test_cases/refcount__kwargs_unpacking.py +27 -0
  520. package/ref-monty/crates/monty/test_cases/refcount__list_append_multiple.py +6 -0
  521. package/ref-monty/crates/monty/test_cases/refcount__list_append_ref.py +5 -0
  522. package/ref-monty/crates/monty/test_cases/refcount__list_concat.py +5 -0
  523. package/ref-monty/crates/monty/test_cases/refcount__list_getitem.py +5 -0
  524. package/ref-monty/crates/monty/test_cases/refcount__list_iadd.py +5 -0
  525. package/ref-monty/crates/monty/test_cases/refcount__nested_list.py +4 -0
  526. package/ref-monty/crates/monty/test_cases/refcount__re_pattern_sub_error_paths.py +37 -0
  527. package/ref-monty/crates/monty/test_cases/refcount__re_search_match.py +34 -0
  528. package/ref-monty/crates/monty/test_cases/refcount__re_sub_error_paths.py +31 -0
  529. package/ref-monty/crates/monty/test_cases/refcount__shared_reference.py +4 -0
  530. package/ref-monty/crates/monty/test_cases/refcount__single_list.py +3 -0
  531. package/ref-monty/crates/monty/test_cases/repr__cycle_detection.py +24 -0
  532. package/ref-monty/crates/monty/test_cases/set__ops.py +191 -0
  533. package/ref-monty/crates/monty/test_cases/set__review_bugs.py +35 -0
  534. package/ref-monty/crates/monty/test_cases/set__unpack_type_error.py +2 -0
  535. package/ref-monty/crates/monty/test_cases/slice__invalid_indices.py +2 -0
  536. package/ref-monty/crates/monty/test_cases/slice__kwargs.py +9 -0
  537. package/ref-monty/crates/monty/test_cases/slice__no_args.py +9 -0
  538. package/ref-monty/crates/monty/test_cases/slice__ops.py +149 -0
  539. package/ref-monty/crates/monty/test_cases/slice__step_zero.py +9 -0
  540. package/ref-monty/crates/monty/test_cases/slice__step_zero_bytes.py +9 -0
  541. package/ref-monty/crates/monty/test_cases/slice__step_zero_range.py +9 -0
  542. package/ref-monty/crates/monty/test_cases/slice__step_zero_str.py +9 -0
  543. package/ref-monty/crates/monty/test_cases/slice__step_zero_tuple.py +9 -0
  544. package/ref-monty/crates/monty/test_cases/slice__too_many_args.py +9 -0
  545. package/ref-monty/crates/monty/test_cases/str__getitem_index_error.py +10 -0
  546. package/ref-monty/crates/monty/test_cases/str__index_not_found.py +9 -0
  547. package/ref-monty/crates/monty/test_cases/str__join_no_args.py +9 -0
  548. package/ref-monty/crates/monty/test_cases/str__join_non_string.py +9 -0
  549. package/ref-monty/crates/monty/test_cases/str__join_not_iterable.py +9 -0
  550. package/ref-monty/crates/monty/test_cases/str__join_too_many_args.py +9 -0
  551. package/ref-monty/crates/monty/test_cases/str__methods.py +327 -0
  552. package/ref-monty/crates/monty/test_cases/str__ops.py +162 -0
  553. package/ref-monty/crates/monty/test_cases/str__partition_empty.py +9 -0
  554. package/ref-monty/crates/monty/test_cases/str__rsplit_empty_sep.py +9 -0
  555. package/ref-monty/crates/monty/test_cases/str__split_empty_sep.py +9 -0
  556. package/ref-monty/crates/monty/test_cases/sys__types.py +7 -0
  557. package/ref-monty/crates/monty/test_cases/traceback__division_error.py +30 -0
  558. package/ref-monty/crates/monty/test_cases/traceback__index_error.py +17 -0
  559. package/ref-monty/crates/monty/test_cases/traceback__insert_as_int.py +10 -0
  560. package/ref-monty/crates/monty/test_cases/traceback__nested_call.py +29 -0
  561. package/ref-monty/crates/monty/test_cases/traceback__nonlocal_module_scope.py +10 -0
  562. package/ref-monty/crates/monty/test_cases/traceback__nonlocal_unbound.py +24 -0
  563. package/ref-monty/crates/monty/test_cases/traceback__range_as_int.py +9 -0
  564. package/ref-monty/crates/monty/test_cases/traceback__recursion_error.py +23 -0
  565. package/ref-monty/crates/monty/test_cases/traceback__set_mutation.py +11 -0
  566. package/ref-monty/crates/monty/test_cases/traceback__undefined_attr_call.py +16 -0
  567. package/ref-monty/crates/monty/test_cases/traceback__undefined_call.py +16 -0
  568. package/ref-monty/crates/monty/test_cases/traceback__undefined_raise.py +16 -0
  569. package/ref-monty/crates/monty/test_cases/try_except__all.py +472 -0
  570. package/ref-monty/crates/monty/test_cases/try_except__bare_raise_no_context.py +2 -0
  571. package/ref-monty/crates/monty/test_cases/try_except__invalid_type.py +5 -0
  572. package/ref-monty/crates/monty/test_cases/tuple__getitem_out_of_bounds.py +3 -0
  573. package/ref-monty/crates/monty/test_cases/tuple__index_not_found.py +9 -0
  574. package/ref-monty/crates/monty/test_cases/tuple__index_start_gt_end.py +10 -0
  575. package/ref-monty/crates/monty/test_cases/tuple__methods.py +19 -0
  576. package/ref-monty/crates/monty/test_cases/tuple__ops.py +133 -0
  577. package/ref-monty/crates/monty/test_cases/tuple__unpack_type_error.py +2 -0
  578. package/ref-monty/crates/monty/test_cases/type__builtin_attr_error.py +9 -0
  579. package/ref-monty/crates/monty/test_cases/type__bytes_negative.py +2 -0
  580. package/ref-monty/crates/monty/test_cases/type__cell_not_builtin.py +9 -0
  581. package/ref-monty/crates/monty/test_cases/type__exception_attr_error.py +11 -0
  582. package/ref-monty/crates/monty/test_cases/type__float_conversion_error.py +2 -0
  583. package/ref-monty/crates/monty/test_cases/type__float_repr_both_quotes.py +9 -0
  584. package/ref-monty/crates/monty/test_cases/type__float_repr_newline.py +9 -0
  585. package/ref-monty/crates/monty/test_cases/type__float_repr_single_quote.py +9 -0
  586. package/ref-monty/crates/monty/test_cases/type__int_conversion_error.py +2 -0
  587. package/ref-monty/crates/monty/test_cases/type__list_not_iterable.py +2 -0
  588. package/ref-monty/crates/monty/test_cases/type__non_builtin_name_error.py +9 -0
  589. package/ref-monty/crates/monty/test_cases/type__ops.py +200 -0
  590. package/ref-monty/crates/monty/test_cases/type__shadow_exc.py +3 -0
  591. package/ref-monty/crates/monty/test_cases/type__shadow_int.py +9 -0
  592. package/ref-monty/crates/monty/test_cases/type__shadow_len.py +3 -0
  593. package/ref-monty/crates/monty/test_cases/type__tuple_not_iterable.py +2 -0
  594. package/ref-monty/crates/monty/test_cases/type_error__int_add_list.py +2 -0
  595. package/ref-monty/crates/monty/test_cases/type_error__int_div_str.py +2 -0
  596. package/ref-monty/crates/monty/test_cases/type_error__int_floordiv_str.py +2 -0
  597. package/ref-monty/crates/monty/test_cases/type_error__int_iadd_str.py +3 -0
  598. package/ref-monty/crates/monty/test_cases/type_error__int_mod_str.py +2 -0
  599. package/ref-monty/crates/monty/test_cases/type_error__int_pow_str.py +2 -0
  600. package/ref-monty/crates/monty/test_cases/type_error__int_sub_str.py +2 -0
  601. package/ref-monty/crates/monty/test_cases/type_error__list_add_int.py +2 -0
  602. package/ref-monty/crates/monty/test_cases/type_error__list_add_str.py +2 -0
  603. package/ref-monty/crates/monty/test_cases/type_error__list_iadd_int.py +6 -0
  604. package/ref-monty/crates/monty/test_cases/type_error__str_add_int.py +2 -0
  605. package/ref-monty/crates/monty/test_cases/type_error__str_iadd_int.py +3 -0
  606. package/ref-monty/crates/monty/test_cases/type_error__unary_invert_str.py +3 -0
  607. package/ref-monty/crates/monty/test_cases/type_error__unary_minus_str.py +4 -0
  608. package/ref-monty/crates/monty/test_cases/type_error__unary_neg_str.py +3 -0
  609. package/ref-monty/crates/monty/test_cases/type_error__unary_plus_str.py +4 -0
  610. package/ref-monty/crates/monty/test_cases/typing__types.py +24 -0
  611. package/ref-monty/crates/monty/test_cases/unpack__nested.py +48 -0
  612. package/ref-monty/crates/monty/test_cases/unpack__non_sequence.py +9 -0
  613. package/ref-monty/crates/monty/test_cases/unpack__not_enough.py +9 -0
  614. package/ref-monty/crates/monty/test_cases/unpack__ops.py +153 -0
  615. package/ref-monty/crates/monty/test_cases/unpack__star_not_enough.py +9 -0
  616. package/ref-monty/crates/monty/test_cases/unpack__too_many.py +9 -0
  617. package/ref-monty/crates/monty/test_cases/version__cpython.py +4 -0
  618. package/ref-monty/crates/monty/test_cases/walrus__all.py +178 -0
  619. package/ref-monty/crates/monty/test_cases/while__all.py +206 -0
  620. package/ref-monty/crates/monty/tests/asyncio.rs +764 -0
  621. package/ref-monty/crates/monty/tests/binary_serde.rs +185 -0
  622. package/ref-monty/crates/monty/tests/bytecode_limits.rs +248 -0
  623. package/ref-monty/crates/monty/tests/datatest_runner.rs +2029 -0
  624. package/ref-monty/crates/monty/tests/inputs.rs +420 -0
  625. package/ref-monty/crates/monty/tests/json_serde.rs +250 -0
  626. package/ref-monty/crates/monty/tests/main.rs +71 -0
  627. package/ref-monty/crates/monty/tests/math_module.rs +114 -0
  628. package/ref-monty/crates/monty/tests/name_lookup.rs +482 -0
  629. package/ref-monty/crates/monty/tests/os_tests.rs +459 -0
  630. package/ref-monty/crates/monty/tests/parse_errors.rs +441 -0
  631. package/ref-monty/crates/monty/tests/print_writer.rs +238 -0
  632. package/ref-monty/crates/monty/tests/py_object.rs +121 -0
  633. package/ref-monty/crates/monty/tests/regex.rs +90 -0
  634. package/ref-monty/crates/monty/tests/repl.rs +344 -0
  635. package/ref-monty/crates/monty/tests/resource_limits.rs +1826 -0
  636. package/ref-monty/crates/monty/tests/try_from.rs +167 -0
  637. package/ref-monty/crates/monty-cli/Cargo.toml +25 -0
  638. package/ref-monty/crates/monty-cli/src/main.rs +541 -0
  639. package/ref-monty/crates/monty-js/.cargo/config.toml +2 -0
  640. package/ref-monty/crates/monty-js/.prettierignore +8 -0
  641. package/ref-monty/crates/monty-js/Cargo.toml +32 -0
  642. package/ref-monty/crates/monty-js/README.md +207 -0
  643. package/ref-monty/crates/monty-js/__test__/async.spec.ts +350 -0
  644. package/ref-monty/crates/monty-js/__test__/basic.spec.ts +114 -0
  645. package/ref-monty/crates/monty-js/__test__/exceptions.spec.ts +427 -0
  646. package/ref-monty/crates/monty-js/__test__/external.spec.ts +354 -0
  647. package/ref-monty/crates/monty-js/__test__/inputs.spec.ts +143 -0
  648. package/ref-monty/crates/monty-js/__test__/limits.spec.ts +162 -0
  649. package/ref-monty/crates/monty-js/__test__/package.json +3 -0
  650. package/ref-monty/crates/monty-js/__test__/print.spec.ts +229 -0
  651. package/ref-monty/crates/monty-js/__test__/repl.spec.ts +34 -0
  652. package/ref-monty/crates/monty-js/__test__/serialize.spec.ts +205 -0
  653. package/ref-monty/crates/monty-js/__test__/start.spec.ts +443 -0
  654. package/ref-monty/crates/monty-js/__test__/type_check.spec.ts +147 -0
  655. package/ref-monty/crates/monty-js/__test__/types.spec.ts +319 -0
  656. package/ref-monty/crates/monty-js/build.rs +61 -0
  657. package/ref-monty/crates/monty-js/index-header.d.ts +3 -0
  658. package/ref-monty/crates/monty-js/package-lock.json +4694 -0
  659. package/ref-monty/crates/monty-js/package.json +100 -0
  660. package/ref-monty/crates/monty-js/scripts/smoke-test.sh +69 -0
  661. package/ref-monty/crates/monty-js/smoke-test/package.json +17 -0
  662. package/ref-monty/crates/monty-js/smoke-test/test.ts +171 -0
  663. package/ref-monty/crates/monty-js/smoke-test/tsconfig.json +11 -0
  664. package/ref-monty/crates/monty-js/src/convert.rs +648 -0
  665. package/ref-monty/crates/monty-js/src/exceptions.rs +293 -0
  666. package/ref-monty/crates/monty-js/src/lib.rs +41 -0
  667. package/ref-monty/crates/monty-js/src/limits.rs +53 -0
  668. package/ref-monty/crates/monty-js/src/monty_cls.rs +1407 -0
  669. package/ref-monty/crates/monty-js/tsconfig.json +17 -0
  670. package/ref-monty/crates/monty-js/wrapper.ts +701 -0
  671. package/ref-monty/crates/monty-python/Cargo.toml +38 -0
  672. package/ref-monty/crates/monty-python/README.md +134 -0
  673. package/ref-monty/crates/monty-python/build.rs +4 -0
  674. package/ref-monty/crates/monty-python/example.py +40 -0
  675. package/ref-monty/crates/monty-python/exercise.py +46 -0
  676. package/ref-monty/crates/monty-python/pyproject.toml +57 -0
  677. package/ref-monty/crates/monty-python/python/pydantic_monty/__init__.py +281 -0
  678. package/ref-monty/crates/monty-python/python/pydantic_monty/_monty.pyi +677 -0
  679. package/ref-monty/crates/monty-python/python/pydantic_monty/os_access.py +933 -0
  680. package/ref-monty/crates/monty-python/python/pydantic_monty/py.typed +0 -0
  681. package/ref-monty/crates/monty-python/src/convert.rs +273 -0
  682. package/ref-monty/crates/monty-python/src/dataclass.rs +461 -0
  683. package/ref-monty/crates/monty-python/src/exceptions.rs +557 -0
  684. package/ref-monty/crates/monty-python/src/external.rs +165 -0
  685. package/ref-monty/crates/monty-python/src/lib.rs +77 -0
  686. package/ref-monty/crates/monty-python/src/limits.rs +142 -0
  687. package/ref-monty/crates/monty-python/src/monty_cls.rs +1650 -0
  688. package/ref-monty/crates/monty-python/src/repl.rs +470 -0
  689. package/ref-monty/crates/monty-python/src/serialization.rs +761 -0
  690. package/ref-monty/crates/monty-python/tests/test_async.py +1201 -0
  691. package/ref-monty/crates/monty-python/tests/test_basic.py +66 -0
  692. package/ref-monty/crates/monty-python/tests/test_dataclasses.py +971 -0
  693. package/ref-monty/crates/monty-python/tests/test_exceptions.py +361 -0
  694. package/ref-monty/crates/monty-python/tests/test_external.py +367 -0
  695. package/ref-monty/crates/monty-python/tests/test_inputs.py +126 -0
  696. package/ref-monty/crates/monty-python/tests/test_limits.py +257 -0
  697. package/ref-monty/crates/monty-python/tests/test_os_access.py +1286 -0
  698. package/ref-monty/crates/monty-python/tests/test_os_access_compat.py +731 -0
  699. package/ref-monty/crates/monty-python/tests/test_os_access_raw.py +483 -0
  700. package/ref-monty/crates/monty-python/tests/test_os_calls.py +819 -0
  701. package/ref-monty/crates/monty-python/tests/test_print.py +208 -0
  702. package/ref-monty/crates/monty-python/tests/test_re.py +170 -0
  703. package/ref-monty/crates/monty-python/tests/test_readme_examples.py +20 -0
  704. package/ref-monty/crates/monty-python/tests/test_repl.py +749 -0
  705. package/ref-monty/crates/monty-python/tests/test_serialize.py +284 -0
  706. package/ref-monty/crates/monty-python/tests/test_start.py +346 -0
  707. package/ref-monty/crates/monty-python/tests/test_threading.py +163 -0
  708. package/ref-monty/crates/monty-python/tests/test_type_check.py +344 -0
  709. package/ref-monty/crates/monty-python/tests/test_types.py +553 -0
  710. package/ref-monty/crates/monty-type-checking/Cargo.toml +32 -0
  711. package/ref-monty/crates/monty-type-checking/src/db.rs +116 -0
  712. package/ref-monty/crates/monty-type-checking/src/lib.rs +4 -0
  713. package/ref-monty/crates/monty-type-checking/src/type_check.rs +280 -0
  714. package/ref-monty/crates/monty-type-checking/tests/bad_types.py +109 -0
  715. package/ref-monty/crates/monty-type-checking/tests/bad_types_output.txt +21 -0
  716. package/ref-monty/crates/monty-type-checking/tests/good_types.py +475 -0
  717. package/ref-monty/crates/monty-type-checking/tests/main.rs +205 -0
  718. package/ref-monty/crates/monty-type-checking/tests/reveal_types.py +56 -0
  719. package/ref-monty/crates/monty-type-checking/tests/reveal_types_output.txt +41 -0
  720. package/ref-monty/crates/monty-typeshed/Cargo.toml +29 -0
  721. package/ref-monty/crates/monty-typeshed/README.md +11 -0
  722. package/ref-monty/crates/monty-typeshed/build.rs +101 -0
  723. package/ref-monty/crates/monty-typeshed/custom/README.md +1 -0
  724. package/ref-monty/crates/monty-typeshed/custom/asyncio.pyi +138 -0
  725. package/ref-monty/crates/monty-typeshed/custom/os.pyi +87 -0
  726. package/ref-monty/crates/monty-typeshed/custom/sys.pyi +33 -0
  727. package/ref-monty/crates/monty-typeshed/src/lib.rs +56 -0
  728. package/ref-monty/crates/monty-typeshed/update.py +321 -0
  729. package/ref-monty/crates/monty-typeshed/vendor/typeshed/source_commit.txt +1 -0
  730. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/VERSIONS +20 -0
  731. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/_collections_abc.pyi +105 -0
  732. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/_typeshed/__init__.pyi +394 -0
  733. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/asyncio.pyi +138 -0
  734. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/builtins.pyi +1434 -0
  735. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/collections/__init__.pyi +527 -0
  736. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/collections/abc.pyi +2 -0
  737. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/dataclasses.pyi +502 -0
  738. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/enum.pyi +376 -0
  739. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/math.pyi +149 -0
  740. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/os.pyi +87 -0
  741. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/pathlib/__init__.pyi +395 -0
  742. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/pathlib/types.pyi +8 -0
  743. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/re.pyi +337 -0
  744. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/sys.pyi +33 -0
  745. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/types.pyi +741 -0
  746. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/typing.pyi +1217 -0
  747. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/typing_extensions.pyi +716 -0
  748. package/ref-monty/docs/usage-guide.md +117 -0
  749. package/ref-monty/examples/README.md +3 -0
  750. package/ref-monty/examples/expense_analysis/README.md +3 -0
  751. package/ref-monty/examples/expense_analysis/data.py +124 -0
  752. package/ref-monty/examples/expense_analysis/main.py +115 -0
  753. package/ref-monty/examples/sql_playground/README.md +20 -0
  754. package/ref-monty/examples/sql_playground/external_functions.py +129 -0
  755. package/ref-monty/examples/sql_playground/main.py +81 -0
  756. package/ref-monty/examples/sql_playground/sandbox_code.py +82 -0
  757. package/ref-monty/examples/sql_playground/type_stubs.pyi +14 -0
  758. package/ref-monty/examples/web_scraper/README.md +15 -0
  759. package/ref-monty/examples/web_scraper/browser.py +56 -0
  760. package/ref-monty/examples/web_scraper/example_code.py +59 -0
  761. package/ref-monty/examples/web_scraper/external_functions.py +324 -0
  762. package/ref-monty/examples/web_scraper/main.py +193 -0
  763. package/ref-monty/examples/web_scraper/sub_agent.py +79 -0
  764. package/ref-monty/monty-npm.md +235 -0
  765. package/ref-monty/pyproject.toml +162 -0
  766. package/ref-monty/scripts/check_imports.py +91 -0
  767. package/ref-monty/scripts/codecov_diff.py +412 -0
  768. package/ref-monty/scripts/complete_tests.py +146 -0
  769. package/ref-monty/scripts/flamegraph_to_text.py +208 -0
  770. package/ref-monty/scripts/iter_test_methods.py +540 -0
  771. package/ref-monty/scripts/run_traceback.py +180 -0
  772. package/ref-monty/scripts/startup_performance.py +130 -0
  773. package/ref-monty/uv.lock +1779 -0
  774. package/temp_resend_cli/repo/.github/scripts/pr-title-check.js +34 -0
  775. package/temp_resend_cli/repo/.github/workflows/ci.yml +67 -0
  776. package/temp_resend_cli/repo/.github/workflows/post-release.yml +51 -0
  777. package/temp_resend_cli/repo/.github/workflows/pr-title-check.yml +13 -0
  778. package/temp_resend_cli/repo/.github/workflows/release.yml +175 -0
  779. package/temp_resend_cli/repo/.github/workflows/test-install-unix.yml +34 -0
  780. package/temp_resend_cli/repo/.github/workflows/test-install-windows.yml +48 -0
  781. package/temp_resend_cli/repo/CHANGELOG.md +31 -0
  782. package/temp_resend_cli/repo/LICENSE +21 -0
  783. package/temp_resend_cli/repo/README.md +450 -0
  784. package/temp_resend_cli/repo/biome.json +36 -0
  785. package/temp_resend_cli/repo/install.ps1 +141 -0
  786. package/temp_resend_cli/repo/install.sh +301 -0
  787. package/temp_resend_cli/repo/package.json +61 -0
  788. package/temp_resend_cli/repo/pnpm-lock.yaml +2439 -0
  789. package/temp_resend_cli/repo/renovate.json +4 -0
  790. package/temp_resend_cli/repo/src/cli.ts +98 -0
  791. package/temp_resend_cli/repo/src/commands/api-keys/create.ts +114 -0
  792. package/temp_resend_cli/repo/src/commands/api-keys/delete.ts +47 -0
  793. package/temp_resend_cli/repo/src/commands/api-keys/index.ts +26 -0
  794. package/temp_resend_cli/repo/src/commands/api-keys/list.ts +35 -0
  795. package/temp_resend_cli/repo/src/commands/api-keys/utils.ts +8 -0
  796. package/temp_resend_cli/repo/src/commands/auth/index.ts +20 -0
  797. package/temp_resend_cli/repo/src/commands/auth/login.ts +234 -0
  798. package/temp_resend_cli/repo/src/commands/auth/logout.ts +105 -0
  799. package/temp_resend_cli/repo/src/commands/broadcasts/create.ts +196 -0
  800. package/temp_resend_cli/repo/src/commands/broadcasts/delete.ts +46 -0
  801. package/temp_resend_cli/repo/src/commands/broadcasts/get.ts +59 -0
  802. package/temp_resend_cli/repo/src/commands/broadcasts/index.ts +43 -0
  803. package/temp_resend_cli/repo/src/commands/broadcasts/list.ts +60 -0
  804. package/temp_resend_cli/repo/src/commands/broadcasts/send.ts +56 -0
  805. package/temp_resend_cli/repo/src/commands/broadcasts/update.ts +95 -0
  806. package/temp_resend_cli/repo/src/commands/broadcasts/utils.ts +35 -0
  807. package/temp_resend_cli/repo/src/commands/contact-properties/create.ts +118 -0
  808. package/temp_resend_cli/repo/src/commands/contact-properties/delete.ts +48 -0
  809. package/temp_resend_cli/repo/src/commands/contact-properties/get.ts +46 -0
  810. package/temp_resend_cli/repo/src/commands/contact-properties/index.ts +48 -0
  811. package/temp_resend_cli/repo/src/commands/contact-properties/list.ts +68 -0
  812. package/temp_resend_cli/repo/src/commands/contact-properties/update.ts +88 -0
  813. package/temp_resend_cli/repo/src/commands/contact-properties/utils.ts +17 -0
  814. package/temp_resend_cli/repo/src/commands/contacts/add-segment.ts +78 -0
  815. package/temp_resend_cli/repo/src/commands/contacts/create.ts +122 -0
  816. package/temp_resend_cli/repo/src/commands/contacts/delete.ts +49 -0
  817. package/temp_resend_cli/repo/src/commands/contacts/get.ts +53 -0
  818. package/temp_resend_cli/repo/src/commands/contacts/index.ts +58 -0
  819. package/temp_resend_cli/repo/src/commands/contacts/list.ts +57 -0
  820. package/temp_resend_cli/repo/src/commands/contacts/remove-segment.ts +48 -0
  821. package/temp_resend_cli/repo/src/commands/contacts/segments.ts +39 -0
  822. package/temp_resend_cli/repo/src/commands/contacts/topics.ts +45 -0
  823. package/temp_resend_cli/repo/src/commands/contacts/update-topics.ts +90 -0
  824. package/temp_resend_cli/repo/src/commands/contacts/update.ts +77 -0
  825. package/temp_resend_cli/repo/src/commands/contacts/utils.ts +119 -0
  826. package/temp_resend_cli/repo/src/commands/doctor.ts +216 -0
  827. package/temp_resend_cli/repo/src/commands/domains/create.ts +83 -0
  828. package/temp_resend_cli/repo/src/commands/domains/delete.ts +42 -0
  829. package/temp_resend_cli/repo/src/commands/domains/get.ts +47 -0
  830. package/temp_resend_cli/repo/src/commands/domains/index.ts +35 -0
  831. package/temp_resend_cli/repo/src/commands/domains/list.ts +53 -0
  832. package/temp_resend_cli/repo/src/commands/domains/update.ts +75 -0
  833. package/temp_resend_cli/repo/src/commands/domains/utils.ts +44 -0
  834. package/temp_resend_cli/repo/src/commands/domains/verify.ts +38 -0
  835. package/temp_resend_cli/repo/src/commands/emails/batch.ts +140 -0
  836. package/temp_resend_cli/repo/src/commands/emails/get.ts +44 -0
  837. package/temp_resend_cli/repo/src/commands/emails/index.ts +30 -0
  838. package/temp_resend_cli/repo/src/commands/emails/list.ts +84 -0
  839. package/temp_resend_cli/repo/src/commands/emails/receiving/attachment.ts +55 -0
  840. package/temp_resend_cli/repo/src/commands/emails/receiving/attachments.ts +68 -0
  841. package/temp_resend_cli/repo/src/commands/emails/receiving/get.ts +58 -0
  842. package/temp_resend_cli/repo/src/commands/emails/receiving/index.ts +28 -0
  843. package/temp_resend_cli/repo/src/commands/emails/receiving/list.ts +59 -0
  844. package/temp_resend_cli/repo/src/commands/emails/receiving/utils.ts +38 -0
  845. package/temp_resend_cli/repo/src/commands/emails/send.ts +189 -0
  846. package/temp_resend_cli/repo/src/commands/open.ts +27 -0
  847. package/temp_resend_cli/repo/src/commands/segments/create.ts +50 -0
  848. package/temp_resend_cli/repo/src/commands/segments/delete.ts +47 -0
  849. package/temp_resend_cli/repo/src/commands/segments/get.ts +38 -0
  850. package/temp_resend_cli/repo/src/commands/segments/index.ts +36 -0
  851. package/temp_resend_cli/repo/src/commands/segments/list.ts +58 -0
  852. package/temp_resend_cli/repo/src/commands/segments/utils.ts +7 -0
  853. package/temp_resend_cli/repo/src/commands/teams/index.ts +10 -0
  854. package/temp_resend_cli/repo/src/commands/teams/list.ts +35 -0
  855. package/temp_resend_cli/repo/src/commands/teams/remove.ts +86 -0
  856. package/temp_resend_cli/repo/src/commands/teams/switch.ts +76 -0
  857. package/temp_resend_cli/repo/src/commands/topics/create.ts +73 -0
  858. package/temp_resend_cli/repo/src/commands/topics/delete.ts +47 -0
  859. package/temp_resend_cli/repo/src/commands/topics/get.ts +42 -0
  860. package/temp_resend_cli/repo/src/commands/topics/index.ts +42 -0
  861. package/temp_resend_cli/repo/src/commands/topics/list.ts +34 -0
  862. package/temp_resend_cli/repo/src/commands/topics/update.ts +59 -0
  863. package/temp_resend_cli/repo/src/commands/topics/utils.ts +16 -0
  864. package/temp_resend_cli/repo/src/commands/webhooks/create.ts +128 -0
  865. package/temp_resend_cli/repo/src/commands/webhooks/delete.ts +49 -0
  866. package/temp_resend_cli/repo/src/commands/webhooks/get.ts +42 -0
  867. package/temp_resend_cli/repo/src/commands/webhooks/index.ts +42 -0
  868. package/temp_resend_cli/repo/src/commands/webhooks/list.ts +55 -0
  869. package/temp_resend_cli/repo/src/commands/webhooks/listen.ts +379 -0
  870. package/temp_resend_cli/repo/src/commands/webhooks/update.ts +83 -0
  871. package/temp_resend_cli/repo/src/commands/webhooks/utils.ts +36 -0
  872. package/temp_resend_cli/repo/src/commands/whoami.ts +71 -0
  873. package/temp_resend_cli/repo/src/lib/actions.ts +157 -0
  874. package/temp_resend_cli/repo/src/lib/client.ts +37 -0
  875. package/temp_resend_cli/repo/src/lib/config.ts +217 -0
  876. package/temp_resend_cli/repo/src/lib/files.ts +15 -0
  877. package/temp_resend_cli/repo/src/lib/help-text.ts +38 -0
  878. package/temp_resend_cli/repo/src/lib/output.ts +56 -0
  879. package/temp_resend_cli/repo/src/lib/pagination.ts +36 -0
  880. package/temp_resend_cli/repo/src/lib/prompts.ts +149 -0
  881. package/temp_resend_cli/repo/src/lib/spinner.ts +100 -0
  882. package/temp_resend_cli/repo/src/lib/table.ts +57 -0
  883. package/temp_resend_cli/repo/src/lib/tty.ts +28 -0
  884. package/temp_resend_cli/repo/src/lib/update-check.ts +169 -0
  885. package/temp_resend_cli/repo/src/lib/version.ts +4 -0
  886. package/temp_resend_cli/repo/tests/commands/api-keys/create.test.ts +196 -0
  887. package/temp_resend_cli/repo/tests/commands/api-keys/delete.test.ts +157 -0
  888. package/temp_resend_cli/repo/tests/commands/api-keys/list.test.ts +134 -0
  889. package/temp_resend_cli/repo/tests/commands/auth/login.test.ts +153 -0
  890. package/temp_resend_cli/repo/tests/commands/auth/logout.test.ts +153 -0
  891. package/temp_resend_cli/repo/tests/commands/broadcasts/create.test.ts +454 -0
  892. package/temp_resend_cli/repo/tests/commands/broadcasts/delete.test.ts +183 -0
  893. package/temp_resend_cli/repo/tests/commands/broadcasts/get.test.ts +147 -0
  894. package/temp_resend_cli/repo/tests/commands/broadcasts/list.test.ts +199 -0
  895. package/temp_resend_cli/repo/tests/commands/broadcasts/send.test.ts +162 -0
  896. package/temp_resend_cli/repo/tests/commands/broadcasts/update.test.ts +288 -0
  897. package/temp_resend_cli/repo/tests/commands/contact-properties/create.test.ts +251 -0
  898. package/temp_resend_cli/repo/tests/commands/contact-properties/delete.test.ts +184 -0
  899. package/temp_resend_cli/repo/tests/commands/contact-properties/get.test.ts +145 -0
  900. package/temp_resend_cli/repo/tests/commands/contact-properties/list.test.ts +181 -0
  901. package/temp_resend_cli/repo/tests/commands/contact-properties/update.test.ts +217 -0
  902. package/temp_resend_cli/repo/tests/commands/contacts/add-segment.test.ts +189 -0
  903. package/temp_resend_cli/repo/tests/commands/contacts/create.test.ts +271 -0
  904. package/temp_resend_cli/repo/tests/commands/contacts/delete.test.ts +193 -0
  905. package/temp_resend_cli/repo/tests/commands/contacts/get.test.ts +149 -0
  906. package/temp_resend_cli/repo/tests/commands/contacts/list.test.ts +176 -0
  907. package/temp_resend_cli/repo/tests/commands/contacts/remove-segment.test.ts +167 -0
  908. package/temp_resend_cli/repo/tests/commands/contacts/segments.test.ts +168 -0
  909. package/temp_resend_cli/repo/tests/commands/contacts/topics.test.ts +164 -0
  910. package/temp_resend_cli/repo/tests/commands/contacts/update-topics.test.ts +248 -0
  911. package/temp_resend_cli/repo/tests/commands/contacts/update.test.ts +206 -0
  912. package/temp_resend_cli/repo/tests/commands/doctor.test.ts +164 -0
  913. package/temp_resend_cli/repo/tests/commands/domains/create.test.ts +193 -0
  914. package/temp_resend_cli/repo/tests/commands/domains/delete.test.ts +157 -0
  915. package/temp_resend_cli/repo/tests/commands/domains/get.test.ts +138 -0
  916. package/temp_resend_cli/repo/tests/commands/domains/list.test.ts +165 -0
  917. package/temp_resend_cli/repo/tests/commands/domains/update.test.ts +224 -0
  918. package/temp_resend_cli/repo/tests/commands/domains/verify.test.ts +118 -0
  919. package/temp_resend_cli/repo/tests/commands/emails/batch.test.ts +324 -0
  920. package/temp_resend_cli/repo/tests/commands/emails/get.test.ts +132 -0
  921. package/temp_resend_cli/repo/tests/commands/emails/receiving/attachment.test.ts +141 -0
  922. package/temp_resend_cli/repo/tests/commands/emails/receiving/attachments.test.ts +169 -0
  923. package/temp_resend_cli/repo/tests/commands/emails/receiving/get.test.ts +141 -0
  924. package/temp_resend_cli/repo/tests/commands/emails/receiving/list.test.ts +182 -0
  925. package/temp_resend_cli/repo/tests/commands/emails/send.test.ts +312 -0
  926. package/temp_resend_cli/repo/tests/commands/segments/create.test.ts +164 -0
  927. package/temp_resend_cli/repo/tests/commands/segments/delete.test.ts +183 -0
  928. package/temp_resend_cli/repo/tests/commands/segments/get.test.ts +138 -0
  929. package/temp_resend_cli/repo/tests/commands/segments/list.test.ts +174 -0
  930. package/temp_resend_cli/repo/tests/commands/teams/list.test.ts +62 -0
  931. package/temp_resend_cli/repo/tests/commands/teams/remove.test.ts +110 -0
  932. package/temp_resend_cli/repo/tests/commands/teams/switch.test.ts +103 -0
  933. package/temp_resend_cli/repo/tests/commands/topics/create.test.ts +192 -0
  934. package/temp_resend_cli/repo/tests/commands/topics/delete.test.ts +157 -0
  935. package/temp_resend_cli/repo/tests/commands/topics/get.test.ts +126 -0
  936. package/temp_resend_cli/repo/tests/commands/topics/list.test.ts +125 -0
  937. package/temp_resend_cli/repo/tests/commands/topics/update.test.ts +178 -0
  938. package/temp_resend_cli/repo/tests/commands/webhooks/create.test.ts +225 -0
  939. package/temp_resend_cli/repo/tests/commands/webhooks/delete.test.ts +157 -0
  940. package/temp_resend_cli/repo/tests/commands/webhooks/get.test.ts +126 -0
  941. package/temp_resend_cli/repo/tests/commands/webhooks/list.test.ts +178 -0
  942. package/temp_resend_cli/repo/tests/commands/webhooks/update.test.ts +207 -0
  943. package/temp_resend_cli/repo/tests/commands/whoami.test.ts +98 -0
  944. package/temp_resend_cli/repo/tests/e2e/smoke.test.ts +93 -0
  945. package/temp_resend_cli/repo/tests/helpers.ts +86 -0
  946. package/temp_resend_cli/repo/tests/lib/client.test.ts +71 -0
  947. package/temp_resend_cli/repo/tests/lib/config.test.ts +451 -0
  948. package/temp_resend_cli/repo/tests/lib/files.test.ts +73 -0
  949. package/temp_resend_cli/repo/tests/lib/help-text.test.ts +97 -0
  950. package/temp_resend_cli/repo/tests/lib/output.test.ts +136 -0
  951. package/temp_resend_cli/repo/tests/lib/prompts.test.ts +185 -0
  952. package/temp_resend_cli/repo/tests/lib/spinner.test.ts +166 -0
  953. package/temp_resend_cli/repo/tests/lib/table.test.ts +63 -0
  954. package/temp_resend_cli/repo/tests/lib/tty.test.ts +89 -0
  955. package/temp_resend_cli/repo/tests/lib/update-check.test.ts +179 -0
  956. package/temp_resend_cli/repo/tsconfig.json +14 -0
  957. package/temp_resend_cli/repo/vitest.config.e2e.ts +8 -0
  958. package/temp_resend_cli/repo/vitest.config.ts +10 -0
  959. package/tests/test-mcp-browser-use-smoke.sh +28 -56
  960. package/tests/test-monty-smoke.sh +32 -0
  961. package/tests/test-resend-smoke.sh +36 -0
@@ -0,0 +1,1109 @@
1
+ //! Stateful REPL execution support for Monty.
2
+ //!
3
+ //! This module implements incremental snippet execution where each new snippet
4
+ //! is compiled and executed against persistent heap/namespace state without
5
+ //! replaying previously executed snippets.
6
+
7
+ use std::mem;
8
+
9
+ use ahash::AHashMap;
10
+ use ruff_python_ast::token::TokenKind;
11
+ use ruff_python_parser::{InterpolatedStringErrorType, LexicalErrorType, ParseErrorType, parse_module};
12
+
13
+ use crate::{
14
+ ExcType, MontyException,
15
+ asyncio::CallId,
16
+ bytecode::{Code, Compiler, FrameExit, VM, VMSnapshot},
17
+ exception_private::{RunError, RunResult},
18
+ heap::{DropWithHeap, Heap},
19
+ intern::{InternerBuilder, Interns},
20
+ io::PrintWriter,
21
+ namespace::NamespaceId,
22
+ object::MontyObject,
23
+ os::OsFunction,
24
+ parse::parse_with_interner,
25
+ prepare::prepare_with_existing_names,
26
+ resource::ResourceTracker,
27
+ run_progress::{ConvertedExit, ExtFunctionResult, NameLookupResult, convert_frame_exit},
28
+ value::Value,
29
+ };
30
+
31
+ /// Stateful REPL session that executes snippets incrementally without replay.
32
+ ///
33
+ /// `MontyRepl` preserves heap and global variable state between snippets.
34
+ /// Each `feed()` compiles and executes only the new snippet against the current
35
+ /// state, avoiding the cost and semantic risks of replaying prior code.
36
+ #[derive(Debug, serde::Serialize, serde::Deserialize)]
37
+ #[serde(bound(serialize = "T: serde::Serialize", deserialize = "T: serde::de::DeserializeOwned"))]
38
+ pub struct MontyRepl<T: ResourceTracker> {
39
+ /// Script name used for runtime error messages and REPL identification.
40
+ ///
41
+ /// Incremental `feed()` / `start()` snippets intentionally use internal script names
42
+ /// like `<python-input-0>` to match CPython's interactive traceback style.
43
+ script_name: String,
44
+ /// Counter for generated `<python-input-N>` snippet filenames.
45
+ next_input_id: u64,
46
+ /// Stable mapping of global variable names to namespace slot IDs.
47
+ global_name_map: AHashMap<String, NamespaceId>,
48
+ /// Persistent intern table across snippets so intern/function IDs remain valid.
49
+ interns: Interns,
50
+ /// Persistent heap across snippets.
51
+ heap: Heap<T>,
52
+ /// Persistent global variable values across snippets.
53
+ ///
54
+ /// Indexed by `NamespaceId` slots from `global_name_map`. Between snippet
55
+ /// executions these are the only VM values that persist — stack and frames
56
+ /// are transient.
57
+ globals: Vec<Value>,
58
+ }
59
+
60
+ impl<T: ResourceTracker> MontyRepl<T> {
61
+ /// Creates an empty REPL session with no code parsed or executed.
62
+ ///
63
+ /// All code execution is driven through `feed_run()` or `feed_start()`. This separates
64
+ /// construction from execution, matching the pattern used by `MontyRun::new()`.
65
+ #[must_use]
66
+ pub fn new(script_name: &str, resource_tracker: T) -> Self {
67
+ let heap = Heap::new(0, resource_tracker);
68
+
69
+ Self {
70
+ script_name: script_name.to_owned(),
71
+ next_input_id: 0,
72
+ global_name_map: AHashMap::new(),
73
+ interns: Interns::new(InternerBuilder::default(), Vec::new()),
74
+ heap,
75
+ globals: Vec::new(),
76
+ }
77
+ }
78
+
79
+ /// Starts executing a new snippet and returns suspendable REPL progress.
80
+ ///
81
+ /// This is the REPL equivalent of `MontyRun::start`: execution may complete,
82
+ /// suspend at external calls / OS calls / unresolved futures, or raise a Python
83
+ /// exception. Resume with the returned state object and eventually recover the
84
+ /// updated REPL from `ReplProgress::into_complete`.
85
+ ///
86
+ /// Unlike `MontyRepl::feed`, this method consumes `self` so runtime state can be
87
+ /// safely moved into snapshot objects for serialization and cross-process resume.
88
+ ///
89
+ /// On a Python-level runtime exception the REPL is **not** destroyed: it is
90
+ /// returned inside `ReplStartError` so the caller can continue feeding
91
+ /// subsequent snippets against the same heap and namespace state.
92
+ ///
93
+ /// # Errors
94
+ /// Returns `Err(Box<ReplStartError>)` for syntax, compile-time, or runtime
95
+ /// failures — the REPL session is always preserved inside the error.
96
+ pub fn feed_start(
97
+ self,
98
+ code: &str,
99
+ inputs: Vec<(String, MontyObject)>,
100
+ print: PrintWriter<'_>,
101
+ ) -> Result<ReplProgress<T>, Box<ReplStartError<T>>> {
102
+ let mut this = self;
103
+ if code.is_empty() {
104
+ return Ok(ReplProgress::Complete {
105
+ repl: this,
106
+ value: MontyObject::None,
107
+ });
108
+ }
109
+
110
+ let (input_names, input_values): (Vec<_>, Vec<_>) = inputs.into_iter().unzip();
111
+
112
+ let input_script_name = this.next_input_script_name();
113
+ let executor = match ReplExecutor::new_repl_snippet(
114
+ code.to_owned(),
115
+ &input_script_name,
116
+ this.global_name_map.clone(),
117
+ &this.interns,
118
+ input_names,
119
+ ) {
120
+ Ok(exec) => exec,
121
+ Err(error) => return Err(Box::new(ReplStartError { repl: this, error })),
122
+ };
123
+
124
+ this.ensure_globals_size(executor.namespace_size);
125
+
126
+ let mut vm = VM::new(mem::take(&mut this.globals), &mut this.heap, &executor.interns, print);
127
+
128
+ // Inject inputs with VM alive
129
+ if let Err(error) = inject_inputs_into_vm(&executor, input_values, &mut vm) {
130
+ this.globals = vm.take_globals();
131
+ vm.cleanup();
132
+ return Err(Box::new(ReplStartError { repl: this, error }));
133
+ }
134
+
135
+ let vm_result = vm.run_module(&executor.module_code);
136
+
137
+ // Convert while VM alive, then snapshot or reclaim globals
138
+ let converted = convert_frame_exit(vm_result, &mut vm);
139
+ if converted.needs_snapshot() {
140
+ let vm_state = vm.snapshot();
141
+ build_repl_progress(converted, Some(vm_state), executor, this)
142
+ } else {
143
+ this.globals = vm.take_globals();
144
+ vm.cleanup();
145
+ build_repl_progress(converted, None, executor, this)
146
+ }
147
+ }
148
+
149
+ /// Feeds and executes a new snippet against the current REPL state to completion.
150
+ ///
151
+ /// This compiles only `code` using the existing global slot map, extends the
152
+ /// global namespace if new names are introduced, and executes the snippet once.
153
+ /// Previously executed snippets are never replayed. If execution raises after
154
+ /// partially mutating globals, those mutations remain visible in later feeds,
155
+ /// matching Python REPL semantics.
156
+ ///
157
+ /// # Errors
158
+ /// Returns `MontyException` for syntax/compile/runtime failures.
159
+ pub fn feed_run(
160
+ &mut self,
161
+ code: &str,
162
+ inputs: Vec<(String, MontyObject)>,
163
+ print: PrintWriter<'_>,
164
+ ) -> Result<MontyObject, MontyException> {
165
+ if code.is_empty() {
166
+ return Ok(MontyObject::None);
167
+ }
168
+
169
+ let (input_names, input_values): (Vec<_>, Vec<_>) = inputs.into_iter().unzip();
170
+
171
+ let input_script_name = self.next_input_script_name();
172
+ let executor = ReplExecutor::new_repl_snippet(
173
+ code.to_owned(),
174
+ &input_script_name,
175
+ self.global_name_map.clone(),
176
+ &self.interns,
177
+ input_names,
178
+ )?;
179
+
180
+ self.ensure_globals_size(executor.namespace_size);
181
+
182
+ let mut vm = VM::new(mem::take(&mut self.globals), &mut self.heap, &executor.interns, print);
183
+
184
+ if let Err(e) = inject_inputs_into_vm(&executor, input_values, &mut vm) {
185
+ self.globals = vm.take_globals();
186
+ vm.cleanup();
187
+ return Err(e);
188
+ }
189
+
190
+ let mut frame_exit_result = vm.run_module(&executor.module_code);
191
+
192
+ // Handle NameLookup exits by raising NameError through the VM so that
193
+ // traceback information is properly captured. In the non-iterative REPL path,
194
+ // there's no host to resolve names, so all NameLookup exits become NameErrors.
195
+ while let Ok(FrameExit::NameLookup { name_id, .. }) = &frame_exit_result {
196
+ let name = executor.interns.get_str(*name_id);
197
+ let err = ExcType::name_error(name);
198
+ frame_exit_result = vm.resume_with_exception(err.into());
199
+ }
200
+
201
+ // Convert output while VM alive
202
+ let result = frame_exit_to_object(frame_exit_result, &mut vm);
203
+
204
+ // Reclaim globals before cleanup.
205
+ self.globals = vm.take_globals();
206
+ vm.cleanup();
207
+
208
+ // Commit compiler metadata even on runtime errors.
209
+ // Snippets can mutate globals before raising, and those values may contain
210
+ // FunctionId/StringId values that must be interpreted with the updated tables.
211
+ let ReplExecutor {
212
+ name_map,
213
+ interns,
214
+ code,
215
+ ..
216
+ } = executor;
217
+ self.global_name_map = name_map;
218
+ self.interns = interns;
219
+
220
+ result.map_err(|e| e.into_python_exception(&self.interns, &code))
221
+ }
222
+
223
+ /// Grows the globals vector to at least `size` slots.
224
+ ///
225
+ /// Newly introduced slots are initialized to `Undefined` to keep slot alignment
226
+ /// with the compiler's global-name map.
227
+ fn ensure_globals_size(&mut self, size: usize) {
228
+ if self.globals.len() < size {
229
+ self.globals.resize_with(size, || Value::Undefined);
230
+ }
231
+ }
232
+
233
+ /// Returns the generated filename for the next interactive snippet.
234
+ ///
235
+ /// CPython labels interactive snippets as `<python-input-N>` and increments
236
+ /// N for each feed attempt. Matching this improves traceback ergonomics and
237
+ /// makes REPL errors easier to correlate with user input history.
238
+ fn next_input_script_name(&mut self) -> String {
239
+ let input_id = self.next_input_id;
240
+ self.next_input_id += 1;
241
+ format!("<python-input-{input_id}>")
242
+ }
243
+ }
244
+
245
+ impl<T: ResourceTracker + serde::Serialize> MontyRepl<T> {
246
+ /// Serializes the REPL session state to bytes.
247
+ ///
248
+ /// This includes heap + globals + global slot mapping, allowing snapshot/restore
249
+ /// of interactive state between process runs.
250
+ ///
251
+ /// # Errors
252
+ /// Returns an error if serialization fails.
253
+ pub fn dump(&self) -> Result<Vec<u8>, postcard::Error> {
254
+ postcard::to_allocvec(self)
255
+ }
256
+ }
257
+
258
+ impl<T: ResourceTracker + serde::de::DeserializeOwned> MontyRepl<T> {
259
+ /// Restores a REPL session from bytes produced by `MontyRepl::dump`.
260
+ ///
261
+ /// # Errors
262
+ /// Returns an error if deserialization fails.
263
+ pub fn load(bytes: &[u8]) -> Result<Self, postcard::Error> {
264
+ postcard::from_bytes(bytes)
265
+ }
266
+ }
267
+
268
+ impl<T: ResourceTracker> Drop for MontyRepl<T> {
269
+ fn drop(&mut self) {
270
+ self.globals.drain(..).drop_with_heap(&mut self.heap);
271
+ }
272
+ }
273
+
274
+ // ---------------------------------------------------------------------------
275
+ // ReplProgress and per-variant structs
276
+ // ---------------------------------------------------------------------------
277
+
278
+ /// Result of a single suspendable REPL snippet execution.
279
+ ///
280
+ /// This mirrors `RunProgress` but returns the updated `MontyRepl` on completion
281
+ /// so callers can continue feeding additional snippets without replaying prior code.
282
+ /// Each variant (except `Complete`) wraps a dedicated struct with only the relevant
283
+ /// resume methods.
284
+ #[derive(Debug, serde::Serialize, serde::Deserialize)]
285
+ #[serde(bound(serialize = "T: serde::Serialize", deserialize = "T: serde::de::DeserializeOwned"))]
286
+ pub enum ReplProgress<T: ResourceTracker> {
287
+ /// Execution paused at an external function call or dataclass method call.
288
+ FunctionCall(ReplFunctionCall<T>),
289
+ /// Execution paused for an OS-level operation.
290
+ OsCall(ReplOsCall<T>),
291
+ /// All async tasks are blocked waiting for external futures to resolve.
292
+ ResolveFutures(ReplResolveFutures<T>),
293
+ /// Execution paused for an unresolved name lookup.
294
+ NameLookup(ReplNameLookup<T>),
295
+ /// Snippet execution completed with the updated REPL and result value.
296
+ Complete {
297
+ /// Updated REPL session state to continue feeding snippets.
298
+ repl: MontyRepl<T>,
299
+ /// Final result produced by the snippet.
300
+ value: MontyObject,
301
+ },
302
+ }
303
+
304
+ /// Error returned when a REPL snippet raises a Python exception during `start()` or `resume()`.
305
+ ///
306
+ /// Unlike syntax/compile errors which consume the REPL, runtime errors preserve
307
+ /// the full session state so the caller can inspect the error and continue feeding
308
+ /// subsequent snippets. Any global mutations that occurred before the exception
309
+ /// remain visible in the returned `repl`.
310
+ #[derive(Debug)]
311
+ pub struct ReplStartError<T: ResourceTracker> {
312
+ /// REPL session state after the failed snippet — ready for further use.
313
+ pub repl: MontyRepl<T>,
314
+ /// The Python exception that was raised.
315
+ pub error: MontyException,
316
+ }
317
+
318
+ impl<T: ResourceTracker> ReplProgress<T> {
319
+ /// Consumes the progress and returns the `ReplFunctionCall` struct.
320
+ #[must_use]
321
+ pub fn into_function_call(self) -> Option<ReplFunctionCall<T>> {
322
+ match self {
323
+ Self::FunctionCall(call) => Some(call),
324
+ _ => None,
325
+ }
326
+ }
327
+
328
+ /// Consumes the progress and returns the `ReplResolveFutures` struct.
329
+ #[must_use]
330
+ pub fn into_resolve_futures(self) -> Option<ReplResolveFutures<T>> {
331
+ match self {
332
+ Self::ResolveFutures(state) => Some(state),
333
+ _ => None,
334
+ }
335
+ }
336
+
337
+ /// Consumes the progress and returns the `ReplNameLookup` struct.
338
+ #[must_use]
339
+ pub fn into_name_lookup(self) -> Option<ReplNameLookup<T>> {
340
+ match self {
341
+ Self::NameLookup(lookup) => Some(lookup),
342
+ _ => None,
343
+ }
344
+ }
345
+
346
+ /// Consumes the progress and returns the completed REPL and value.
347
+ #[must_use]
348
+ pub fn into_complete(self) -> Option<(MontyRepl<T>, MontyObject)> {
349
+ match self {
350
+ Self::Complete { repl, value } => Some((repl, value)),
351
+ _ => None,
352
+ }
353
+ }
354
+
355
+ /// Extracts the REPL session from any progress variant, discarding
356
+ /// the in-flight execution state.
357
+ ///
358
+ /// Use this to recover the REPL when you need to abandon the current
359
+ /// snippet (e.g. because `feed_run` doesn't support async futures).
360
+ /// The REPL state reflects any mutations that occurred before the
361
+ /// snapshot was taken.
362
+ #[must_use]
363
+ pub fn into_repl(self) -> MontyRepl<T> {
364
+ match self {
365
+ Self::FunctionCall(call) => call.into_repl(),
366
+ Self::OsCall(call) => call.into_repl(),
367
+ Self::ResolveFutures(state) => state.into_repl(),
368
+ Self::NameLookup(lookup) => lookup.into_repl(),
369
+ Self::Complete { repl, .. } => repl,
370
+ }
371
+ }
372
+ }
373
+
374
+ impl<T: ResourceTracker + serde::Serialize> ReplProgress<T> {
375
+ /// Serializes the REPL execution progress to a binary format.
376
+ ///
377
+ /// # Errors
378
+ /// Returns an error if serialization fails.
379
+ pub fn dump(&self) -> Result<Vec<u8>, postcard::Error> {
380
+ postcard::to_allocvec(self)
381
+ }
382
+ }
383
+
384
+ impl<T: ResourceTracker + serde::de::DeserializeOwned> ReplProgress<T> {
385
+ /// Deserializes REPL execution progress from a binary format.
386
+ ///
387
+ /// # Errors
388
+ /// Returns an error if deserialization fails.
389
+ pub fn load(bytes: &[u8]) -> Result<Self, postcard::Error> {
390
+ postcard::from_bytes(bytes)
391
+ }
392
+ }
393
+
394
+ // ---------------------------------------------------------------------------
395
+ // ReplFunctionCall
396
+ // ---------------------------------------------------------------------------
397
+
398
+ /// REPL execution paused at an external function call or dataclass method call.
399
+ ///
400
+ /// Resume with `resume(result, print)` to provide the return value and continue,
401
+ /// or `resume_pending(print)` to push an `ExternalFuture` for async resolution.
402
+ #[derive(Debug, serde::Serialize, serde::Deserialize)]
403
+ #[serde(bound(serialize = "T: serde::Serialize", deserialize = "T: serde::de::DeserializeOwned"))]
404
+ pub struct ReplFunctionCall<T: ResourceTracker> {
405
+ /// The name of the function or method being called.
406
+ pub function_name: String,
407
+ /// The positional arguments passed to the function.
408
+ pub args: Vec<MontyObject>,
409
+ /// The keyword arguments passed to the function (key, value pairs).
410
+ pub kwargs: Vec<(MontyObject, MontyObject)>,
411
+ /// Unique identifier for this call (used for async correlation).
412
+ pub call_id: u32,
413
+ /// Whether this is a dataclass method call (first arg is `self`).
414
+ pub method_call: bool,
415
+ /// Internal REPL execution snapshot.
416
+ snapshot: ReplSnapshot<T>,
417
+ }
418
+
419
+ impl<T: ResourceTracker> ReplFunctionCall<T> {
420
+ /// Extracts the REPL session, discarding the in-flight execution state.
421
+ ///
422
+ /// Restores globals from the VM snapshot so the REPL remains usable.
423
+ #[must_use]
424
+ pub fn into_repl(self) -> MontyRepl<T> {
425
+ self.snapshot.into_repl()
426
+ }
427
+
428
+ /// Resumes snippet execution with an external result.
429
+ pub fn resume(
430
+ self,
431
+ result: impl Into<ExtFunctionResult>,
432
+ print: PrintWriter<'_>,
433
+ ) -> Result<ReplProgress<T>, Box<ReplStartError<T>>> {
434
+ self.snapshot.run(result, print)
435
+ }
436
+
437
+ /// Resumes execution by pushing an `ExternalFuture` for async resolution.
438
+ ///
439
+ /// Uses `self.call_id` internally — no need to pass it again.
440
+ pub fn resume_pending(self, print: PrintWriter<'_>) -> Result<ReplProgress<T>, Box<ReplStartError<T>>> {
441
+ self.snapshot.run(ExtFunctionResult::Future(self.call_id), print)
442
+ }
443
+ }
444
+
445
+ // ---------------------------------------------------------------------------
446
+ // ReplOsCall
447
+ // ---------------------------------------------------------------------------
448
+
449
+ /// REPL execution paused for an OS-level operation.
450
+ ///
451
+ /// Resume with `resume(result, print)` to provide the OS call result and continue.
452
+ #[derive(Debug, serde::Serialize, serde::Deserialize)]
453
+ #[serde(bound(serialize = "T: serde::Serialize", deserialize = "T: serde::de::DeserializeOwned"))]
454
+ pub struct ReplOsCall<T: ResourceTracker> {
455
+ /// The OS function to execute.
456
+ pub function: OsFunction,
457
+ /// The positional arguments for the OS function.
458
+ pub args: Vec<MontyObject>,
459
+ /// The keyword arguments passed to the function (key, value pairs).
460
+ pub kwargs: Vec<(MontyObject, MontyObject)>,
461
+ /// Unique identifier for this call (used for async correlation).
462
+ pub call_id: u32,
463
+ /// Internal REPL execution snapshot.
464
+ snapshot: ReplSnapshot<T>,
465
+ }
466
+
467
+ impl<T: ResourceTracker> ReplOsCall<T> {
468
+ /// Extracts the REPL session, discarding the in-flight execution state.
469
+ ///
470
+ /// Restores globals from the VM snapshot so the REPL remains usable.
471
+ #[must_use]
472
+ pub fn into_repl(self) -> MontyRepl<T> {
473
+ self.snapshot.into_repl()
474
+ }
475
+
476
+ /// Resumes snippet execution with the OS call result.
477
+ pub fn resume(
478
+ self,
479
+ result: impl Into<ExtFunctionResult>,
480
+ print: PrintWriter<'_>,
481
+ ) -> Result<ReplProgress<T>, Box<ReplStartError<T>>> {
482
+ self.snapshot.run(result, print)
483
+ }
484
+ }
485
+
486
+ // ---------------------------------------------------------------------------
487
+ // ReplNameLookup
488
+ // ---------------------------------------------------------------------------
489
+
490
+ /// REPL execution paused for an unresolved name lookup.
491
+ ///
492
+ /// The host should check if the name corresponds to a known external function or
493
+ /// value. Call `resume(result, print)` with the appropriate `NameLookupResult`.
494
+ /// The namespace slot and scope are managed internally.
495
+ #[derive(Debug, serde::Serialize, serde::Deserialize)]
496
+ #[serde(bound(serialize = "T: serde::Serialize", deserialize = "T: serde::de::DeserializeOwned"))]
497
+ pub struct ReplNameLookup<T: ResourceTracker> {
498
+ /// The name being looked up.
499
+ pub name: String,
500
+ /// The namespace slot where the resolved value should be cached.
501
+ namespace_slot: u16,
502
+ /// Whether this is a global slot or a local/function slot.
503
+ is_global: bool,
504
+ /// Internal REPL execution snapshot.
505
+ snapshot: ReplSnapshot<T>,
506
+ }
507
+
508
+ impl<T: ResourceTracker> ReplNameLookup<T> {
509
+ /// Extracts the REPL session, discarding the in-flight execution state.
510
+ ///
511
+ /// Restores globals from the VM snapshot so the REPL remains usable.
512
+ #[must_use]
513
+ pub fn into_repl(self) -> MontyRepl<T> {
514
+ self.snapshot.into_repl()
515
+ }
516
+
517
+ /// Resumes execution after name resolution.
518
+ ///
519
+ /// Caches the resolved value in the namespace slot before restoring the VM,
520
+ /// then either pushes the value onto the stack or raises `NameError`.
521
+ pub fn resume(
522
+ self,
523
+ result: NameLookupResult,
524
+ print: PrintWriter<'_>,
525
+ ) -> Result<ReplProgress<T>, Box<ReplStartError<T>>> {
526
+ let Self {
527
+ name,
528
+ namespace_slot,
529
+ is_global,
530
+ snapshot,
531
+ } = self;
532
+
533
+ let ReplSnapshot {
534
+ mut repl,
535
+ executor,
536
+ vm_state,
537
+ } = snapshot;
538
+
539
+ // Restore the VM first, then convert inside its lifetime
540
+ let mut vm = VM::restore(
541
+ vm_state,
542
+ &executor.module_code,
543
+ &mut repl.heap,
544
+ &executor.interns,
545
+ print,
546
+ );
547
+
548
+ // Resolve the name lookup result with the VM alive
549
+ let vm_result = match result {
550
+ NameLookupResult::Value(obj) => {
551
+ let value = match obj.to_value(&mut vm) {
552
+ Ok(v) => v,
553
+ Err(e) => {
554
+ repl.globals = vm.take_globals();
555
+ vm.cleanup();
556
+ let error = MontyException::runtime_error(format!("invalid name lookup result: {e}"));
557
+ return Err(Box::new(ReplStartError { repl, error }));
558
+ }
559
+ };
560
+
561
+ // Cache the resolved value in the appropriate slot
562
+ let slot = namespace_slot as usize;
563
+ if is_global {
564
+ let cloned = value.clone_with_heap(vm.heap);
565
+ let old = mem::replace(&mut vm.globals[slot], cloned);
566
+ old.drop_with_heap(vm.heap);
567
+ } else {
568
+ let stack_base = vm.current_stack_base();
569
+ let cloned = value.clone_with_heap(vm.heap);
570
+ let old = mem::replace(&mut vm.stack[stack_base + slot], cloned);
571
+ old.drop_with_heap(vm.heap);
572
+ }
573
+
574
+ vm.push(value);
575
+ vm.run()
576
+ }
577
+ NameLookupResult::Undefined => {
578
+ let err: RunError = ExcType::name_error(&name).into();
579
+ vm.resume_with_exception(err)
580
+ }
581
+ };
582
+
583
+ // Convert while VM alive, then snapshot or reclaim globals
584
+ let converted = convert_frame_exit(vm_result, &mut vm);
585
+ if converted.needs_snapshot() {
586
+ let vm_state = vm.snapshot();
587
+ build_repl_progress(converted, Some(vm_state), executor, repl)
588
+ } else {
589
+ repl.globals = vm.take_globals();
590
+ vm.cleanup();
591
+ build_repl_progress(converted, None, executor, repl)
592
+ }
593
+ }
594
+ }
595
+
596
+ // ---------------------------------------------------------------------------
597
+ // ReplResolveFutures
598
+ // ---------------------------------------------------------------------------
599
+
600
+ /// REPL execution state blocked on unresolved external futures.
601
+ ///
602
+ /// This is the REPL-aware counterpart to `ResolveFutures`.
603
+ #[derive(Debug, serde::Serialize, serde::Deserialize)]
604
+ #[serde(bound(serialize = "T: serde::Serialize", deserialize = "T: serde::de::DeserializeOwned"))]
605
+ pub struct ReplResolveFutures<T: ResourceTracker> {
606
+ /// Persistent REPL session state while this snippet is suspended.
607
+ repl: MontyRepl<T>,
608
+ /// Compiled snippet and intern/function tables for this execution.
609
+ executor: ReplExecutor,
610
+ /// VM stack/frame state at suspension.
611
+ vm_state: VMSnapshot,
612
+ /// Pending call IDs expected by this snapshot.
613
+ pending_call_ids: Vec<u32>,
614
+ }
615
+
616
+ impl<T: ResourceTracker> ReplResolveFutures<T> {
617
+ /// Extracts the REPL session, discarding the in-flight execution state.
618
+ #[must_use]
619
+ pub fn into_repl(self) -> MontyRepl<T> {
620
+ self.repl
621
+ }
622
+
623
+ /// Returns unresolved call IDs for this suspended state.
624
+ #[must_use]
625
+ pub fn pending_call_ids(&self) -> &[u32] {
626
+ &self.pending_call_ids
627
+ }
628
+
629
+ /// Resumes snippet execution with zero or more resolved futures.
630
+ ///
631
+ /// Supports incremental resolution: callers can provide only a subset of
632
+ /// pending call IDs and continue resolving over multiple resumes.
633
+ ///
634
+ /// All errors — including API misuse (unknown `call_id`) and Python-level
635
+ /// runtime failures — are returned as `Err(Box<ReplStartError>)` so the REPL
636
+ /// session is always preserved.
637
+ pub fn resume(
638
+ self,
639
+ results: Vec<(u32, ExtFunctionResult)>,
640
+ print: PrintWriter<'_>,
641
+ ) -> Result<ReplProgress<T>, Box<ReplStartError<T>>> {
642
+ let Self {
643
+ mut repl,
644
+ executor,
645
+ vm_state,
646
+ pending_call_ids,
647
+ } = self;
648
+
649
+ let invalid_call_id = results
650
+ .iter()
651
+ .find(|(call_id, _)| !pending_call_ids.contains(call_id))
652
+ .map(|(call_id, _)| *call_id);
653
+
654
+ let mut vm = VM::restore(
655
+ vm_state,
656
+ &executor.module_code,
657
+ &mut repl.heap,
658
+ &executor.interns,
659
+ print,
660
+ );
661
+
662
+ if let Some(call_id) = invalid_call_id {
663
+ repl.globals = vm.take_globals();
664
+ vm.cleanup();
665
+ let error = MontyException::runtime_error(format!(
666
+ "unknown call_id {call_id}, expected one of: {pending_call_ids:?}"
667
+ ));
668
+ return Err(Box::new(ReplStartError { repl, error }));
669
+ }
670
+
671
+ for (call_id, ext_result) in results {
672
+ match ext_result {
673
+ ExtFunctionResult::Return(obj) => {
674
+ if let Err(e) = vm.resolve_future(call_id, obj) {
675
+ repl.globals = vm.take_globals();
676
+ vm.cleanup();
677
+ let error =
678
+ MontyException::runtime_error(format!("Invalid return type for call {call_id}: {e}"));
679
+ return Err(Box::new(ReplStartError { repl, error }));
680
+ }
681
+ }
682
+ ExtFunctionResult::Error(exc) => vm.fail_future(call_id, RunError::from(exc)),
683
+ ExtFunctionResult::Future(_) => {}
684
+ ExtFunctionResult::NotFound(function_name) => {
685
+ vm.fail_future(call_id, ExtFunctionResult::not_found_exc(&function_name));
686
+ }
687
+ }
688
+ }
689
+
690
+ if let Some(error) = vm.take_failed_task_error() {
691
+ repl.globals = vm.take_globals();
692
+ vm.cleanup();
693
+ let error = error.into_python_exception(&executor.interns, &executor.code);
694
+ return Err(Box::new(ReplStartError { repl, error }));
695
+ }
696
+
697
+ let main_task_ready = vm.prepare_current_task_after_resolve();
698
+
699
+ let loaded_task = match vm.load_ready_task_if_needed() {
700
+ Ok(loaded) => loaded,
701
+ Err(e) => {
702
+ repl.globals = vm.take_globals();
703
+ vm.cleanup();
704
+ let error = e.into_python_exception(&executor.interns, &executor.code);
705
+ return Err(Box::new(ReplStartError { repl, error }));
706
+ }
707
+ };
708
+
709
+ if !main_task_ready && !loaded_task {
710
+ let pending_call_ids = vm.get_pending_call_ids();
711
+ if !pending_call_ids.is_empty() {
712
+ let vm_state = vm.snapshot();
713
+ let pending_call_ids: Vec<u32> = pending_call_ids.iter().map(|id| id.raw()).collect();
714
+ return Ok(ReplProgress::ResolveFutures(Self {
715
+ repl,
716
+ executor,
717
+ vm_state,
718
+ pending_call_ids,
719
+ }));
720
+ }
721
+ }
722
+
723
+ let vm_result = vm.run();
724
+
725
+ // Convert while VM alive, then snapshot or reclaim globals
726
+ let converted = convert_frame_exit(vm_result, &mut vm);
727
+ if converted.needs_snapshot() {
728
+ let vm_state = vm.snapshot();
729
+ build_repl_progress(converted, Some(vm_state), executor, repl)
730
+ } else {
731
+ repl.globals = vm.take_globals();
732
+ vm.cleanup();
733
+ build_repl_progress(converted, None, executor, repl)
734
+ }
735
+ }
736
+ }
737
+
738
+ // ---------------------------------------------------------------------------
739
+ // ReplContinuationMode — public utility for interactive input collection
740
+ // ---------------------------------------------------------------------------
741
+
742
+ /// Parse-derived continuation state for interactive REPL input collection.
743
+ ///
744
+ /// `monty-cli` uses this to decide whether to execute the buffered snippet
745
+ /// immediately, keep collecting continuation lines, or require a terminating
746
+ /// blank line for block statements (`if:`, `def:`, etc.).
747
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
748
+ pub enum ReplContinuationMode {
749
+ /// The current snippet is syntactically complete and can run now.
750
+ Complete,
751
+ /// The snippet is incomplete and needs more continuation lines.
752
+ IncompleteImplicit,
753
+ /// The snippet opened an indented block and should wait for a trailing blank
754
+ /// line before execution, matching CPython interactive behavior.
755
+ IncompleteBlock,
756
+ }
757
+
758
+ /// Detects whether REPL source is complete or needs more input.
759
+ ///
760
+ /// This mirrors CPython's broad interactive behavior:
761
+ /// - Incomplete bracketed / parenthesized / triple-quoted constructs continue.
762
+ /// - Clause headers (`if:`, `def:`, etc.) require an indented body and then a
763
+ /// terminating blank line before execution.
764
+ /// - All other parse outcomes are treated as complete (either valid code or a
765
+ /// syntax error that should be shown immediately).
766
+ #[must_use]
767
+ pub fn detect_repl_continuation_mode(source: &str) -> ReplContinuationMode {
768
+ let Err(error) = parse_module(source) else {
769
+ return ReplContinuationMode::Complete;
770
+ };
771
+
772
+ match error.error {
773
+ ParseErrorType::OtherError(msg) => {
774
+ if msg.starts_with("Expected an indented block after ") {
775
+ ReplContinuationMode::IncompleteBlock
776
+ } else {
777
+ ReplContinuationMode::Complete
778
+ }
779
+ }
780
+ ParseErrorType::Lexical(LexicalErrorType::Eof)
781
+ | ParseErrorType::ExpectedToken {
782
+ found: TokenKind::EndOfFile,
783
+ ..
784
+ }
785
+ | ParseErrorType::FStringError(InterpolatedStringErrorType::UnterminatedTripleQuotedString)
786
+ | ParseErrorType::TStringError(InterpolatedStringErrorType::UnterminatedTripleQuotedString) => {
787
+ ReplContinuationMode::IncompleteImplicit
788
+ }
789
+ _ => ReplContinuationMode::Complete,
790
+ }
791
+ }
792
+
793
+ // ---------------------------------------------------------------------------
794
+ // ReplExecutor — internal compilation helper
795
+ // ---------------------------------------------------------------------------
796
+
797
+ /// Compiled snippet representation used only by REPL execution.
798
+ ///
799
+ /// This intentionally mirrors the data shape needed by VM execution in
800
+ /// `run.rs` but lives in the REPL module so REPL evolution does not require
801
+ /// changing `run.rs`.
802
+ #[derive(Debug, serde::Serialize, serde::Deserialize)]
803
+ struct ReplExecutor {
804
+ /// Number of slots needed in the global namespace.
805
+ namespace_size: usize,
806
+ /// Maps variable names to their indices in the namespace.
807
+ ///
808
+ /// Stable slot assignment is required across snippets so previously created
809
+ /// objects continue to resolve names correctly.
810
+ name_map: AHashMap<String, NamespaceId>,
811
+ /// Compiled bytecode for the snippet.
812
+ module_code: Code,
813
+ /// Interned strings and compiled functions for this snippet.
814
+ interns: Interns,
815
+ /// Source code used for traceback/error rendering.
816
+ code: String,
817
+ /// Input variable names that were injected for this snippet.
818
+ ///
819
+ /// Stored so that `inject_inputs` can look up their namespace slots
820
+ /// after compilation assigns them.
821
+ input_names: Vec<String>,
822
+ }
823
+
824
+ impl ReplExecutor {
825
+ /// Compiles one REPL snippet against existing session metadata.
826
+ ///
827
+ /// This differs from normal compilation in three ways required for true
828
+ /// no-replay execution:
829
+ /// - Seeds parsing from `existing_interns` so old `StringId` values stay stable.
830
+ /// - Seeds compilation with existing functions so old `FunctionId` values remain valid.
831
+ /// - Reuses `existing_name_map` and appends new global names only.
832
+ ///
833
+ /// `input_names` are pre-registered in the name map before preparation so they
834
+ /// receive stable namespace slots that `inject_inputs` can use to store values.
835
+ fn new_repl_snippet(
836
+ code: String,
837
+ script_name: &str,
838
+ mut existing_name_map: AHashMap<String, NamespaceId>,
839
+ existing_interns: &Interns,
840
+ input_names: Vec<String>,
841
+ ) -> Result<Self, MontyException> {
842
+ // Pre-register input names so they get stable slots before preparation.
843
+ for name in &input_names {
844
+ let next_slot = existing_name_map.len();
845
+ existing_name_map
846
+ .entry(name.clone())
847
+ .or_insert_with(|| NamespaceId::new(next_slot));
848
+ }
849
+
850
+ let seeded_interner = InternerBuilder::from_interns(existing_interns, &code);
851
+ let parse_result = parse_with_interner(&code, script_name, seeded_interner)
852
+ .map_err(|e| e.into_python_exc(script_name, &code))?;
853
+ let prepared = prepare_with_existing_names(parse_result, existing_name_map)
854
+ .map_err(|e| e.into_python_exc(script_name, &code))?;
855
+
856
+ let existing_functions = existing_interns.functions_clone();
857
+ let mut interns = Interns::new(prepared.interner, Vec::new());
858
+ let namespace_size_u16 = u16::try_from(prepared.namespace_size).expect("module namespace size exceeds u16");
859
+ let compile_result =
860
+ Compiler::compile_module_with_functions(&prepared.nodes, &interns, namespace_size_u16, existing_functions)
861
+ .map_err(|e| e.into_python_exc(script_name, &code))?;
862
+ interns.set_functions(compile_result.functions);
863
+
864
+ Ok(Self {
865
+ namespace_size: prepared.namespace_size,
866
+ name_map: prepared.name_map,
867
+ module_code: compile_result.code,
868
+ interns,
869
+ code,
870
+ input_names,
871
+ })
872
+ }
873
+ }
874
+
875
+ // ---------------------------------------------------------------------------
876
+ // ReplSnapshot — internal execution state for suspend/resume
877
+ // ---------------------------------------------------------------------------
878
+
879
+ /// REPL execution state that can be resumed after an external call.
880
+ ///
881
+ /// This is the REPL-aware counterpart to `Snapshot`. It is `pub(crate)` —
882
+ /// callers interact with the per-variant structs (`ReplFunctionCall`, etc.).
883
+ #[derive(Debug, serde::Serialize, serde::Deserialize)]
884
+ #[serde(bound(serialize = "T: serde::Serialize", deserialize = "T: serde::de::DeserializeOwned"))]
885
+ pub(crate) struct ReplSnapshot<T: ResourceTracker> {
886
+ /// Persistent REPL session state while this snippet is suspended.
887
+ repl: MontyRepl<T>,
888
+ /// Compiled snippet and intern/function tables for this execution.
889
+ executor: ReplExecutor,
890
+ /// VM stack/frame state at suspension.
891
+ vm_state: VMSnapshot,
892
+ }
893
+
894
+ impl<T: ResourceTracker> ReplSnapshot<T> {
895
+ /// Extracts the REPL session, restoring globals from the VM snapshot.
896
+ ///
897
+ /// When a snapshot is taken, globals live inside the `VMSnapshot`.
898
+ /// This method creates an empty snapshot from just the globals so the REPL
899
+ /// can be used for further snippets.
900
+ fn into_repl(self) -> MontyRepl<T> {
901
+ let Self { mut repl, vm_state, .. } = self;
902
+ repl.globals = vm_state.globals;
903
+ repl
904
+ }
905
+
906
+ /// Continues snippet execution with an external result.
907
+ fn run(
908
+ self,
909
+ result: impl Into<ExtFunctionResult>,
910
+ print: PrintWriter<'_>,
911
+ ) -> Result<ReplProgress<T>, Box<ReplStartError<T>>> {
912
+ let Self {
913
+ mut repl,
914
+ executor,
915
+ vm_state,
916
+ } = self;
917
+
918
+ let ext_result = result.into();
919
+
920
+ let mut vm = VM::restore(
921
+ vm_state,
922
+ &executor.module_code,
923
+ &mut repl.heap,
924
+ &executor.interns,
925
+ print,
926
+ );
927
+
928
+ let vm_result = match ext_result {
929
+ ExtFunctionResult::Return(obj) => vm.resume(obj),
930
+ ExtFunctionResult::Error(exc) => vm.resume_with_exception(exc.into()),
931
+ ExtFunctionResult::Future(raw_call_id) => {
932
+ let call_id = CallId::new(raw_call_id);
933
+ vm.add_pending_call(call_id);
934
+ vm.push(Value::ExternalFuture(call_id));
935
+ vm.run()
936
+ }
937
+ ExtFunctionResult::NotFound(function_name) => {
938
+ vm.resume_with_exception(ExtFunctionResult::not_found_exc(&function_name))
939
+ }
940
+ };
941
+
942
+ // Convert while VM alive, then snapshot or reclaim globals
943
+ let converted = convert_frame_exit(vm_result, &mut vm);
944
+ if converted.needs_snapshot() {
945
+ let vm_state = vm.snapshot();
946
+ build_repl_progress(converted, Some(vm_state), executor, repl)
947
+ } else {
948
+ repl.globals = vm.take_globals();
949
+ vm.cleanup();
950
+ build_repl_progress(converted, None, executor, repl)
951
+ }
952
+ }
953
+ }
954
+
955
+ // ---------------------------------------------------------------------------
956
+ // Private helper functions
957
+ // ---------------------------------------------------------------------------
958
+
959
+ /// Injects input values into the VM's global namespace slots.
960
+ ///
961
+ /// Converts each `MontyObject` to a `Value` while the VM is alive, then stores
962
+ /// it in the global slot that the compiler assigned for the corresponding input name.
963
+ fn inject_inputs_into_vm(
964
+ executor: &ReplExecutor,
965
+ input_values: Vec<MontyObject>,
966
+ vm: &mut VM<'_, '_, impl ResourceTracker>,
967
+ ) -> Result<(), MontyException> {
968
+ for (name, obj) in executor.input_names.iter().zip(input_values) {
969
+ let slot = executor
970
+ .name_map
971
+ .get(name)
972
+ .expect("input name should have a namespace slot")
973
+ .index();
974
+ let value = obj
975
+ .to_value(vm)
976
+ .map_err(|e| MontyException::runtime_error(format!("invalid input type: {e}")))?;
977
+ let old = mem::replace(&mut vm.globals[slot], value);
978
+ old.drop_with_heap(vm.heap);
979
+ }
980
+ Ok(())
981
+ }
982
+
983
+ /// Converts module/frame exit results into plain `MontyObject` outputs.
984
+ ///
985
+ /// Used by the non-iterative `feed_run` path where suspendable outcomes (external calls,
986
+ /// name lookups) are not supported and should produce errors.
987
+ fn frame_exit_to_object(
988
+ frame_exit_result: RunResult<FrameExit>,
989
+ vm: &mut VM<'_, '_, impl ResourceTracker>,
990
+ ) -> RunResult<MontyObject> {
991
+ match frame_exit_result? {
992
+ FrameExit::Return(return_value) => Ok(MontyObject::new(return_value, vm)),
993
+ FrameExit::ExternalCall {
994
+ function_name, args, ..
995
+ } => {
996
+ args.drop_with_heap(vm.heap);
997
+ let function_name = function_name.as_str(vm.interns);
998
+ Err(ExcType::not_implemented(format!(
999
+ "External function '{function_name}' not implemented with standard execution"
1000
+ ))
1001
+ .into())
1002
+ }
1003
+ FrameExit::OsCall { function, args, .. } => {
1004
+ args.drop_with_heap(vm.heap);
1005
+ Err(ExcType::not_implemented(format!(
1006
+ "OS function '{function}' not implemented with standard execution"
1007
+ ))
1008
+ .into())
1009
+ }
1010
+ FrameExit::MethodCall { method_name, args, .. } => {
1011
+ args.drop_with_heap(vm.heap);
1012
+ let name = method_name.as_str(vm.interns);
1013
+ Err(
1014
+ ExcType::not_implemented(format!("Method call '{name}' not implemented with standard execution"))
1015
+ .into(),
1016
+ )
1017
+ }
1018
+ FrameExit::ResolveFutures(_) => {
1019
+ Err(ExcType::not_implemented("async futures not supported by standard execution.").into())
1020
+ }
1021
+ FrameExit::NameLookup { name_id, .. } => {
1022
+ let name = vm.interns.get_str(name_id);
1023
+ Err(ExcType::name_error(name).into())
1024
+ }
1025
+ }
1026
+ }
1027
+
1028
+ /// Assembles a `ReplProgress` from already-converted data.
1029
+ ///
1030
+ /// This is the REPL equivalent of `build_run_progress`. On completion/error,
1031
+ /// compiler metadata is committed to the REPL so subsequent snippets see
1032
+ /// updated intern tables and name maps.
1033
+ fn build_repl_progress<T: ResourceTracker>(
1034
+ converted: ConvertedExit,
1035
+ vm_state: Option<VMSnapshot>,
1036
+ executor: ReplExecutor,
1037
+ mut repl: MontyRepl<T>,
1038
+ ) -> Result<ReplProgress<T>, Box<ReplStartError<T>>> {
1039
+ macro_rules! new_repl_snapshot {
1040
+ () => {
1041
+ ReplSnapshot {
1042
+ repl,
1043
+ executor,
1044
+ vm_state: vm_state.expect("snapshot should exist"),
1045
+ }
1046
+ };
1047
+ }
1048
+
1049
+ match converted {
1050
+ ConvertedExit::Complete(obj) => {
1051
+ let ReplExecutor { name_map, interns, .. } = executor;
1052
+ repl.global_name_map = name_map;
1053
+ repl.interns = interns;
1054
+ Ok(ReplProgress::Complete { repl, value: obj })
1055
+ }
1056
+ ConvertedExit::FunctionCall {
1057
+ function_name,
1058
+ args,
1059
+ kwargs,
1060
+ call_id,
1061
+ method_call,
1062
+ } => Ok(ReplProgress::FunctionCall(ReplFunctionCall {
1063
+ function_name,
1064
+ args,
1065
+ kwargs,
1066
+ call_id,
1067
+ method_call,
1068
+ snapshot: new_repl_snapshot!(),
1069
+ })),
1070
+ ConvertedExit::OsCall {
1071
+ function,
1072
+ args,
1073
+ kwargs,
1074
+ call_id,
1075
+ } => Ok(ReplProgress::OsCall(ReplOsCall {
1076
+ function,
1077
+ args,
1078
+ kwargs,
1079
+ call_id,
1080
+ snapshot: new_repl_snapshot!(),
1081
+ })),
1082
+ ConvertedExit::ResolveFutures(pending_call_ids) => Ok(ReplProgress::ResolveFutures(ReplResolveFutures {
1083
+ repl,
1084
+ executor,
1085
+ vm_state: vm_state.expect("snapshot should exist for ResolveFutures"),
1086
+ pending_call_ids,
1087
+ })),
1088
+ ConvertedExit::NameLookup {
1089
+ name,
1090
+ namespace_slot,
1091
+ is_global,
1092
+ } => Ok(ReplProgress::NameLookup(ReplNameLookup {
1093
+ name,
1094
+ namespace_slot,
1095
+ is_global,
1096
+ snapshot: new_repl_snapshot!(),
1097
+ })),
1098
+ ConvertedExit::Error(err) => {
1099
+ let error = err.into_python_exception(&executor.interns, &executor.code);
1100
+ // Commit compiler metadata even on runtime errors, matching feed() behavior.
1101
+ // Snippets can create new variables or functions before raising, and those
1102
+ // values may reference FunctionId/StringId values from the new tables.
1103
+ let ReplExecutor { name_map, interns, .. } = executor;
1104
+ repl.global_name_map = name_map;
1105
+ repl.interns = interns;
1106
+ Err(Box::new(ReplStartError { repl, error }))
1107
+ }
1108
+ }
1109
+ }