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.
- package/__tests__/adapter-schema.test.js +2 -0
- package/__tests__/config.test.js +62 -1
- package/__tests__/help-json.test.js +2 -0
- package/__tests__/mcp-adapter.test.js +14 -4
- package/__tests__/mcp-local.test.js +159 -0
- package/__tests__/mcp-stdio-jsonrpc.test.js +105 -0
- package/__tests__/monty-plugin.test.js +121 -0
- package/__tests__/plugin-browser-use-uninstall.test.js +23 -0
- package/__tests__/plugin-browser-use.test.js +77 -0
- package/__tests__/plugins-command.test.js +92 -1
- package/__tests__/plugins-learn.test.js +62 -0
- package/__tests__/plugins-registry.test.js +3 -1
- package/__tests__/resend-plugin.test.js +122 -0
- package/__tests__/skills.test.js +4 -0
- package/cli/adapter-schema.js +3 -2
- package/cli/adapters/mcp.js +22 -3
- package/cli/adapters/process.js +34 -7
- package/cli/config.js +27 -1
- package/cli/help-json.js +2 -2
- package/cli/mcp-diagnostics.js +152 -0
- package/cli/mcp-discovery.js +221 -0
- package/cli/mcp-local.js +267 -25
- package/cli/mcp-stdio-jsonrpc.js +246 -0
- package/cli/plugin-install-guidance.js +25 -0
- package/cli/plugins-command.js +86 -3
- package/cli/plugins-learn.js +177 -0
- package/cli/plugins-manager.js +3 -0
- package/cli/plugins-registry.js +2 -1
- package/cli/skills-mcp.js +102 -0
- package/cli/skills.js +6 -40
- package/cli/supercli.js +7 -2
- package/docs/initial/mcp-local-mode.md +35 -0
- package/docs/mcp-cheatsheet.md +324 -0
- package/docs/plugins.md +7 -0
- package/package.json +1 -1
- package/plugins/browser-use/plugin.json +23 -0
- package/plugins/browser-use/scripts/post-install.js +146 -0
- package/plugins/browser-use/scripts/post-uninstall.js +28 -0
- package/plugins/browser-use/skills/quickstart/SKILL.md +47 -0
- package/plugins/monty/README.md +49 -0
- package/plugins/monty/plugin.json +69 -0
- package/plugins/monty/scripts/post-install.js +73 -0
- package/plugins/monty/scripts/post-uninstall.js +23 -0
- package/plugins/monty/scripts/run-python.js +140 -0
- package/plugins/monty/scripts/setup-monty.js +27 -0
- package/plugins/plugins.json +29 -0
- package/plugins/resend/plugin.json +371 -0
- package/plugins/resend/scripts/post-install.js +59 -0
- package/plugins/resend/scripts/post-uninstall.js +23 -0
- package/plugins/resend/scripts/setup-resend.js +27 -0
- package/plugins/resend/skills/quickstart/SKILL.md +80 -0
- package/ref-monty/.cargo/config.toml +3 -0
- package/ref-monty/.claude/settings.json +60 -0
- package/ref-monty/.claude/skills/fastmod/SKILL.md +22 -0
- package/ref-monty/.claude/skills/python-playground/SKILL.md +47 -0
- package/ref-monty/.codecov.yml +12 -0
- package/ref-monty/.github/actions/build-pgo-wheel/action.yml +72 -0
- package/ref-monty/.github/workflows/ci.yml +776 -0
- package/ref-monty/.github/workflows/codspeed.yml +45 -0
- package/ref-monty/.github/workflows/init-npm-packages.yml +82 -0
- package/ref-monty/.pre-commit-config.yaml +47 -0
- package/ref-monty/.python-version +1 -0
- package/ref-monty/.rustfmt.toml +4 -0
- package/ref-monty/.zed/settings.json +11 -0
- package/ref-monty/CLAUDE.md +535 -0
- package/ref-monty/Cargo.lock +3798 -0
- package/ref-monty/Cargo.toml +87 -0
- package/ref-monty/LICENSE +21 -0
- package/ref-monty/Makefile +216 -0
- package/ref-monty/README.md +430 -0
- package/ref-monty/RELEASING.md +47 -0
- package/ref-monty/crates/fuzz/Cargo.toml +30 -0
- package/ref-monty/crates/fuzz/fuzz_targets/string_input_panic.rs +37 -0
- package/ref-monty/crates/fuzz/fuzz_targets/tokens_input_panic.rs +552 -0
- package/ref-monty/crates/monty/Cargo.toml +68 -0
- package/ref-monty/crates/monty/benches/main.rs +247 -0
- package/ref-monty/crates/monty/build.rs +10 -0
- package/ref-monty/crates/monty/src/args.rs +733 -0
- package/ref-monty/crates/monty/src/asyncio.rs +179 -0
- package/ref-monty/crates/monty/src/builtins/abs.rs +55 -0
- package/ref-monty/crates/monty/src/builtins/all.rs +30 -0
- package/ref-monty/crates/monty/src/builtins/any.rs +30 -0
- package/ref-monty/crates/monty/src/builtins/bin.rs +59 -0
- package/ref-monty/crates/monty/src/builtins/chr.rs +46 -0
- package/ref-monty/crates/monty/src/builtins/divmod.rs +164 -0
- package/ref-monty/crates/monty/src/builtins/enumerate.rs +52 -0
- package/ref-monty/crates/monty/src/builtins/filter.rs +67 -0
- package/ref-monty/crates/monty/src/builtins/getattr.rs +65 -0
- package/ref-monty/crates/monty/src/builtins/hash.rs +28 -0
- package/ref-monty/crates/monty/src/builtins/hex.rs +58 -0
- package/ref-monty/crates/monty/src/builtins/id.rs +24 -0
- package/ref-monty/crates/monty/src/builtins/isinstance.rs +68 -0
- package/ref-monty/crates/monty/src/builtins/len.rs +25 -0
- package/ref-monty/crates/monty/src/builtins/map.rs +98 -0
- package/ref-monty/crates/monty/src/builtins/min_max.rs +113 -0
- package/ref-monty/crates/monty/src/builtins/mod.rs +246 -0
- package/ref-monty/crates/monty/src/builtins/next.rs +21 -0
- package/ref-monty/crates/monty/src/builtins/oct.rs +59 -0
- package/ref-monty/crates/monty/src/builtins/ord.rs +67 -0
- package/ref-monty/crates/monty/src/builtins/pow.rs +365 -0
- package/ref-monty/crates/monty/src/builtins/print.rs +141 -0
- package/ref-monty/crates/monty/src/builtins/repr.rs +16 -0
- package/ref-monty/crates/monty/src/builtins/reversed.rs +28 -0
- package/ref-monty/crates/monty/src/builtins/round.rs +174 -0
- package/ref-monty/crates/monty/src/builtins/sorted.rs +151 -0
- package/ref-monty/crates/monty/src/builtins/sum.rs +66 -0
- package/ref-monty/crates/monty/src/builtins/type_.rs +16 -0
- package/ref-monty/crates/monty/src/builtins/zip.rs +77 -0
- package/ref-monty/crates/monty/src/bytecode/builder.rs +699 -0
- package/ref-monty/crates/monty/src/bytecode/code.rs +310 -0
- package/ref-monty/crates/monty/src/bytecode/compiler.rs +3206 -0
- package/ref-monty/crates/monty/src/bytecode/mod.rs +24 -0
- package/ref-monty/crates/monty/src/bytecode/op.rs +617 -0
- package/ref-monty/crates/monty/src/bytecode/vm/async_exec.rs +1058 -0
- package/ref-monty/crates/monty/src/bytecode/vm/attr.rs +63 -0
- package/ref-monty/crates/monty/src/bytecode/vm/binary.rs +487 -0
- package/ref-monty/crates/monty/src/bytecode/vm/call.rs +767 -0
- package/ref-monty/crates/monty/src/bytecode/vm/collections.rs +741 -0
- package/ref-monty/crates/monty/src/bytecode/vm/compare.rs +147 -0
- package/ref-monty/crates/monty/src/bytecode/vm/exceptions.rs +297 -0
- package/ref-monty/crates/monty/src/bytecode/vm/format.rs +132 -0
- package/ref-monty/crates/monty/src/bytecode/vm/mod.rs +1958 -0
- package/ref-monty/crates/monty/src/bytecode/vm/scheduler.rs +620 -0
- package/ref-monty/crates/monty/src/exception_private.rs +1513 -0
- package/ref-monty/crates/monty/src/exception_public.rs +346 -0
- package/ref-monty/crates/monty/src/expressions.rs +694 -0
- package/ref-monty/crates/monty/src/fstring.rs +854 -0
- package/ref-monty/crates/monty/src/function.rs +119 -0
- package/ref-monty/crates/monty/src/heap.rs +1073 -0
- package/ref-monty/crates/monty/src/heap_data.rs +985 -0
- package/ref-monty/crates/monty/src/heap_traits.rs +312 -0
- package/ref-monty/crates/monty/src/intern.rs +837 -0
- package/ref-monty/crates/monty/src/io.rs +106 -0
- package/ref-monty/crates/monty/src/lib.rs +52 -0
- package/ref-monty/crates/monty/src/modules/asyncio.rs +144 -0
- package/ref-monty/crates/monty/src/modules/math.rs +1453 -0
- package/ref-monty/crates/monty/src/modules/mod.rs +120 -0
- package/ref-monty/crates/monty/src/modules/os.rs +116 -0
- package/ref-monty/crates/monty/src/modules/pathlib.rs +33 -0
- package/ref-monty/crates/monty/src/modules/re.rs +606 -0
- package/ref-monty/crates/monty/src/modules/sys.rs +60 -0
- package/ref-monty/crates/monty/src/modules/typing.rs +70 -0
- package/ref-monty/crates/monty/src/namespace.rs +21 -0
- package/ref-monty/crates/monty/src/object.rs +1040 -0
- package/ref-monty/crates/monty/src/os.rs +215 -0
- package/ref-monty/crates/monty/src/parse.rs +1730 -0
- package/ref-monty/crates/monty/src/prepare.rs +3015 -0
- package/ref-monty/crates/monty/src/repl.rs +1109 -0
- package/ref-monty/crates/monty/src/resource.rs +559 -0
- package/ref-monty/crates/monty/src/run.rs +457 -0
- package/ref-monty/crates/monty/src/run_progress.rs +821 -0
- package/ref-monty/crates/monty/src/signature.rs +651 -0
- package/ref-monty/crates/monty/src/sorting.rs +100 -0
- package/ref-monty/crates/monty/src/types/bytes.rs +2356 -0
- package/ref-monty/crates/monty/src/types/dataclass.rs +345 -0
- package/ref-monty/crates/monty/src/types/dict.rs +879 -0
- package/ref-monty/crates/monty/src/types/dict_view.rs +619 -0
- package/ref-monty/crates/monty/src/types/iter.rs +799 -0
- package/ref-monty/crates/monty/src/types/list.rs +929 -0
- package/ref-monty/crates/monty/src/types/long_int.rs +211 -0
- package/ref-monty/crates/monty/src/types/mod.rs +48 -0
- package/ref-monty/crates/monty/src/types/module.rs +146 -0
- package/ref-monty/crates/monty/src/types/namedtuple.rs +261 -0
- package/ref-monty/crates/monty/src/types/path.rs +596 -0
- package/ref-monty/crates/monty/src/types/property.rs +35 -0
- package/ref-monty/crates/monty/src/types/py_trait.rs +322 -0
- package/ref-monty/crates/monty/src/types/range.rs +285 -0
- package/ref-monty/crates/monty/src/types/re_match.rs +522 -0
- package/ref-monty/crates/monty/src/types/re_pattern.rs +726 -0
- package/ref-monty/crates/monty/src/types/set.rs +1373 -0
- package/ref-monty/crates/monty/src/types/slice.rs +257 -0
- package/ref-monty/crates/monty/src/types/str.rs +2051 -0
- package/ref-monty/crates/monty/src/types/tuple.rs +376 -0
- package/ref-monty/crates/monty/src/types/type.rs +407 -0
- package/ref-monty/crates/monty/src/value.rs +2558 -0
- package/ref-monty/crates/monty/test_cases/args__dict_get_no_args.py +3 -0
- package/ref-monty/crates/monty/test_cases/args__dict_get_too_many.py +3 -0
- package/ref-monty/crates/monty/test_cases/args__dict_items_with_args.py +3 -0
- package/ref-monty/crates/monty/test_cases/args__dict_keys_with_args.py +3 -0
- package/ref-monty/crates/monty/test_cases/args__dict_pop_no_args.py +3 -0
- package/ref-monty/crates/monty/test_cases/args__dict_pop_too_many.py +3 -0
- package/ref-monty/crates/monty/test_cases/args__dict_values_with_args.py +3 -0
- package/ref-monty/crates/monty/test_cases/args__id_too_many.py +2 -0
- package/ref-monty/crates/monty/test_cases/args__len_no_args.py +2 -0
- package/ref-monty/crates/monty/test_cases/args__len_too_many.py +2 -0
- package/ref-monty/crates/monty/test_cases/args__len_type_error_int.py +9 -0
- package/ref-monty/crates/monty/test_cases/args__len_type_error_none.py +9 -0
- package/ref-monty/crates/monty/test_cases/args__list_append_no_args.py +3 -0
- package/ref-monty/crates/monty/test_cases/args__list_append_too_many.py +3 -0
- package/ref-monty/crates/monty/test_cases/args__list_insert_too_few.py +3 -0
- package/ref-monty/crates/monty/test_cases/args__list_insert_too_many.py +3 -0
- package/ref-monty/crates/monty/test_cases/args__repr_no_args.py +2 -0
- package/ref-monty/crates/monty/test_cases/arith__div_zero_float.py +2 -0
- package/ref-monty/crates/monty/test_cases/arith__div_zero_int.py +2 -0
- package/ref-monty/crates/monty/test_cases/arith__floordiv_zero_float.py +2 -0
- package/ref-monty/crates/monty/test_cases/arith__floordiv_zero_int.py +2 -0
- package/ref-monty/crates/monty/test_cases/arith__pow_zero_neg.py +2 -0
- package/ref-monty/crates/monty/test_cases/arith__pow_zero_neg_builtin.py +9 -0
- package/ref-monty/crates/monty/test_cases/assert__expr_fail.py +2 -0
- package/ref-monty/crates/monty/test_cases/assert__fail.py +2 -0
- package/ref-monty/crates/monty/test_cases/assert__fail_msg.py +2 -0
- package/ref-monty/crates/monty/test_cases/assert__fn_fail.py +3 -0
- package/ref-monty/crates/monty/test_cases/assert__ops.py +11 -0
- package/ref-monty/crates/monty/test_cases/async__asyncio_run.py +47 -0
- package/ref-monty/crates/monty/test_cases/async__basic.py +10 -0
- package/ref-monty/crates/monty/test_cases/async__closure.py +14 -0
- package/ref-monty/crates/monty/test_cases/async__double_await_coroutine.py +16 -0
- package/ref-monty/crates/monty/test_cases/async__exception.py +10 -0
- package/ref-monty/crates/monty/test_cases/async__ext_call.py +73 -0
- package/ref-monty/crates/monty/test_cases/async__gather_all.py +85 -0
- package/ref-monty/crates/monty/test_cases/async__nested_await.py +15 -0
- package/ref-monty/crates/monty/test_cases/async__nested_gather_ext.py +37 -0
- package/ref-monty/crates/monty/test_cases/async__not_awaitable.py +10 -0
- package/ref-monty/crates/monty/test_cases/async__not_imported.py +14 -0
- package/ref-monty/crates/monty/test_cases/async__recursion_depth_isolation.py +27 -0
- package/ref-monty/crates/monty/test_cases/async__return_types.py +31 -0
- package/ref-monty/crates/monty/test_cases/async__sequential.py +16 -0
- package/ref-monty/crates/monty/test_cases/async__traceback.py +19 -0
- package/ref-monty/crates/monty/test_cases/async__with_args.py +14 -0
- package/ref-monty/crates/monty/test_cases/attr__get_int_error.py +9 -0
- package/ref-monty/crates/monty/test_cases/attr__get_list_error.py +9 -0
- package/ref-monty/crates/monty/test_cases/attr__set_frozen_nonfield.py +12 -0
- package/ref-monty/crates/monty/test_cases/attr__set_int_error.py +10 -0
- package/ref-monty/crates/monty/test_cases/attr__set_list_error.py +10 -0
- package/ref-monty/crates/monty/test_cases/bench__kitchen_sink.py +68 -0
- package/ref-monty/crates/monty/test_cases/bool__ops.py +20 -0
- package/ref-monty/crates/monty/test_cases/builtin__add_type_error.py +2 -0
- package/ref-monty/crates/monty/test_cases/builtin__filter.py +62 -0
- package/ref-monty/crates/monty/test_cases/builtin__filter_not_iterable.py +11 -0
- package/ref-monty/crates/monty/test_cases/builtin__getattr.py +84 -0
- package/ref-monty/crates/monty/test_cases/builtin__iter_funcs.py +42 -0
- package/ref-monty/crates/monty/test_cases/builtin__iter_next.py +66 -0
- package/ref-monty/crates/monty/test_cases/builtin__map.py +74 -0
- package/ref-monty/crates/monty/test_cases/builtin__map_not_iterable.py +11 -0
- package/ref-monty/crates/monty/test_cases/builtin__math_funcs.py +154 -0
- package/ref-monty/crates/monty/test_cases/builtin__more_iter_funcs.py +148 -0
- package/ref-monty/crates/monty/test_cases/builtin__next_stop_iteration.py +10 -0
- package/ref-monty/crates/monty/test_cases/builtin__print_invalid_kwarg.py +9 -0
- package/ref-monty/crates/monty/test_cases/builtin__print_kwargs.py +12 -0
- package/ref-monty/crates/monty/test_cases/builtin__repr.py +3 -0
- package/ref-monty/crates/monty/test_cases/builtin__string_funcs.py +73 -0
- package/ref-monty/crates/monty/test_cases/bytes__decode_invalid_utf8.py +18 -0
- package/ref-monty/crates/monty/test_cases/bytes__endswith_str_error.py +10 -0
- package/ref-monty/crates/monty/test_cases/bytes__getitem_index_error.py +10 -0
- package/ref-monty/crates/monty/test_cases/bytes__index_start_gt_end.py +10 -0
- package/ref-monty/crates/monty/test_cases/bytes__methods.py +394 -0
- package/ref-monty/crates/monty/test_cases/bytes__negative_count.py +9 -0
- package/ref-monty/crates/monty/test_cases/bytes__ops.py +90 -0
- package/ref-monty/crates/monty/test_cases/bytes__startswith_str_error.py +10 -0
- package/ref-monty/crates/monty/test_cases/call_object.py +3 -0
- package/ref-monty/crates/monty/test_cases/chain_comparison__all.py +79 -0
- package/ref-monty/crates/monty/test_cases/closure__param_shadows_outer.py +81 -0
- package/ref-monty/crates/monty/test_cases/closure__pep448.py +203 -0
- package/ref-monty/crates/monty/test_cases/closure__undefined_nonlocal.py +13 -0
- package/ref-monty/crates/monty/test_cases/compare__mixed_types.py +120 -0
- package/ref-monty/crates/monty/test_cases/comprehension__all.py +208 -0
- package/ref-monty/crates/monty/test_cases/comprehension__scope.py +7 -0
- package/ref-monty/crates/monty/test_cases/comprehension__unbound_local.py +14 -0
- package/ref-monty/crates/monty/test_cases/dataclass__basic.py +238 -0
- package/ref-monty/crates/monty/test_cases/dataclass__call_field_error.py +12 -0
- package/ref-monty/crates/monty/test_cases/dataclass__frozen_set_error.py +12 -0
- package/ref-monty/crates/monty/test_cases/dataclass__get_missing_attr_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/dict__get_unhashable_key.py +3 -0
- package/ref-monty/crates/monty/test_cases/dict__literal_unhashable_key.py +2 -0
- package/ref-monty/crates/monty/test_cases/dict__method_pop_missing_error.py +3 -0
- package/ref-monty/crates/monty/test_cases/dict__methods.py +151 -0
- package/ref-monty/crates/monty/test_cases/dict__ops.py +133 -0
- package/ref-monty/crates/monty/test_cases/dict__pop_unhashable_key.py +4 -0
- package/ref-monty/crates/monty/test_cases/dict__popitem_empty.py +9 -0
- package/ref-monty/crates/monty/test_cases/dict__subscript_missing_key.py +3 -0
- package/ref-monty/crates/monty/test_cases/dict__unhashable_dict_key.py +2 -0
- package/ref-monty/crates/monty/test_cases/dict__unhashable_list_key.py +2 -0
- package/ref-monty/crates/monty/test_cases/dict__unpack_type_error.py +2 -0
- package/ref-monty/crates/monty/test_cases/dict__views.py +165 -0
- package/ref-monty/crates/monty/test_cases/edge__all.py +26 -0
- package/ref-monty/crates/monty/test_cases/edge__float_int_mod.py +2 -0
- package/ref-monty/crates/monty/test_cases/edge__int_float_mod.py +2 -0
- package/ref-monty/crates/monty/test_cases/exc__args.py +16 -0
- package/ref-monty/crates/monty/test_cases/exc__str.py +15 -0
- package/ref-monty/crates/monty/test_cases/execute_ok__all.py +54 -0
- package/ref-monty/crates/monty/test_cases/execute_raise__error_instance_str.py +2 -0
- package/ref-monty/crates/monty/test_cases/execute_raise__error_no_args.py +2 -0
- package/ref-monty/crates/monty/test_cases/execute_raise__error_string_arg.py +2 -0
- package/ref-monty/crates/monty/test_cases/execute_raise__error_string_arg_quotes.py +2 -0
- package/ref-monty/crates/monty/test_cases/execute_raise__error_type.py +2 -0
- package/ref-monty/crates/monty/test_cases/execute_raise__raise_instance_via_var.py +4 -0
- package/ref-monty/crates/monty/test_cases/execute_raise__raise_list.py +2 -0
- package/ref-monty/crates/monty/test_cases/execute_raise__raise_number.py +2 -0
- package/ref-monty/crates/monty/test_cases/execute_raise__raise_type_call_via_var.py +4 -0
- package/ref-monty/crates/monty/test_cases/execute_raise__raise_type_direct.py +3 -0
- package/ref-monty/crates/monty/test_cases/execute_raise__raise_type_via_var.py +4 -0
- package/ref-monty/crates/monty/test_cases/ext_call__arg_side_effect_bug.py +22 -0
- package/ref-monty/crates/monty/test_cases/ext_call__augmented.py +17 -0
- package/ref-monty/crates/monty/test_cases/ext_call__augmented_refcount_bug.py +7 -0
- package/ref-monty/crates/monty/test_cases/ext_call__bare_raise_after_resume.py +34 -0
- package/ref-monty/crates/monty/test_cases/ext_call__basic.py +99 -0
- package/ref-monty/crates/monty/test_cases/ext_call__boolean.py +37 -0
- package/ref-monty/crates/monty/test_cases/ext_call__boolean_side_effect_hang.py +17 -0
- package/ref-monty/crates/monty/test_cases/ext_call__closure_bug.py +16 -0
- package/ref-monty/crates/monty/test_cases/ext_call__comparison.py +26 -0
- package/ref-monty/crates/monty/test_cases/ext_call__deep_call_stack.py +18 -0
- package/ref-monty/crates/monty/test_cases/ext_call__elif.py +171 -0
- package/ref-monty/crates/monty/test_cases/ext_call__exc.py +4 -0
- package/ref-monty/crates/monty/test_cases/ext_call__exc_deep_stack.py +39 -0
- package/ref-monty/crates/monty/test_cases/ext_call__exc_in_function.py +17 -0
- package/ref-monty/crates/monty/test_cases/ext_call__exc_nested_functions.py +31 -0
- package/ref-monty/crates/monty/test_cases/ext_call__ext_exc.py +171 -0
- package/ref-monty/crates/monty/test_cases/ext_call__for.py +114 -0
- package/ref-monty/crates/monty/test_cases/ext_call__fstring.py +12 -0
- package/ref-monty/crates/monty/test_cases/ext_call__if.py +135 -0
- package/ref-monty/crates/monty/test_cases/ext_call__if_condition.py +37 -0
- package/ref-monty/crates/monty/test_cases/ext_call__in_closure.py +14 -0
- package/ref-monty/crates/monty/test_cases/ext_call__in_function.py +40 -0
- package/ref-monty/crates/monty/test_cases/ext_call__in_function_simple.py +7 -0
- package/ref-monty/crates/monty/test_cases/ext_call__literals.py +17 -0
- package/ref-monty/crates/monty/test_cases/ext_call__multi_in_func.py +32 -0
- package/ref-monty/crates/monty/test_cases/ext_call__name_lookup.py +69 -0
- package/ref-monty/crates/monty/test_cases/ext_call__name_lookup_undefined.py +4 -0
- package/ref-monty/crates/monty/test_cases/ext_call__nested_calls.py +14 -0
- package/ref-monty/crates/monty/test_cases/ext_call__recursion_bug.py +19 -0
- package/ref-monty/crates/monty/test_cases/ext_call__return.py +28 -0
- package/ref-monty/crates/monty/test_cases/ext_call__side_effects.py +25 -0
- package/ref-monty/crates/monty/test_cases/ext_call__subscript.py +7 -0
- package/ref-monty/crates/monty/test_cases/ext_call__ternary.py +28 -0
- package/ref-monty/crates/monty/test_cases/ext_call__try.py +280 -0
- package/ref-monty/crates/monty/test_cases/ext_call__try_simple.py +10 -0
- package/ref-monty/crates/monty/test_cases/ext_call__unary.py +13 -0
- package/ref-monty/crates/monty/test_cases/frozenset__ops.py +178 -0
- package/ref-monty/crates/monty/test_cases/fstring__all.py +236 -0
- package/ref-monty/crates/monty/test_cases/fstring__error_eq_align_on_str.py +3 -0
- package/ref-monty/crates/monty/test_cases/fstring__error_float_f_on_str.py +3 -0
- package/ref-monty/crates/monty/test_cases/fstring__error_int_d_on_float.py +3 -0
- package/ref-monty/crates/monty/test_cases/fstring__error_int_d_on_str.py +3 -0
- package/ref-monty/crates/monty/test_cases/fstring__error_invalid_spec.py +4 -0
- package/ref-monty/crates/monty/test_cases/fstring__error_invalid_spec_dynamic.py +4 -0
- package/ref-monty/crates/monty/test_cases/fstring__error_invalid_spec_str.py +4 -0
- package/ref-monty/crates/monty/test_cases/fstring__error_str_s_on_int.py +3 -0
- package/ref-monty/crates/monty/test_cases/function__call_duplicate_kwargs.py +6 -0
- package/ref-monty/crates/monty/test_cases/function__call_unpack.py +42 -0
- package/ref-monty/crates/monty/test_cases/function__defaults.py +117 -0
- package/ref-monty/crates/monty/test_cases/function__err_duplicate_arg.py +7 -0
- package/ref-monty/crates/monty/test_cases/function__err_duplicate_first_arg.py +7 -0
- package/ref-monty/crates/monty/test_cases/function__err_duplicate_kwarg_cleanup.py +9 -0
- package/ref-monty/crates/monty/test_cases/function__err_kwonly_as_positional.py +7 -0
- package/ref-monty/crates/monty/test_cases/function__err_missing_all_posonly.py +7 -0
- package/ref-monty/crates/monty/test_cases/function__err_missing_heap_cleanup.py +9 -0
- package/ref-monty/crates/monty/test_cases/function__err_missing_kwonly.py +7 -0
- package/ref-monty/crates/monty/test_cases/function__err_missing_posonly_with_kwarg.py +7 -0
- package/ref-monty/crates/monty/test_cases/function__err_missing_with_posonly.py +7 -0
- package/ref-monty/crates/monty/test_cases/function__err_posonly_as_kwarg.py +7 -0
- package/ref-monty/crates/monty/test_cases/function__err_posonly_first_as_kwarg.py +7 -0
- package/ref-monty/crates/monty/test_cases/function__err_too_many_posonly.py +7 -0
- package/ref-monty/crates/monty/test_cases/function__err_too_many_with_kwonly.py +7 -0
- package/ref-monty/crates/monty/test_cases/function__err_unexpected_kwarg.py +7 -0
- package/ref-monty/crates/monty/test_cases/function__err_unexpected_kwarg_cleanup.py +9 -0
- package/ref-monty/crates/monty/test_cases/function__err_unexpected_kwarg_quote.py +13 -0
- package/ref-monty/crates/monty/test_cases/function__err_unexpected_kwarg_simple.py +7 -0
- package/ref-monty/crates/monty/test_cases/function__err_unpack_duplicate_arg.py +6 -0
- package/ref-monty/crates/monty/test_cases/function__err_unpack_duplicate_heap.py +8 -0
- package/ref-monty/crates/monty/test_cases/function__err_unpack_int.py +6 -0
- package/ref-monty/crates/monty/test_cases/function__err_unpack_nonstring_key.py +6 -0
- package/ref-monty/crates/monty/test_cases/function__err_unpack_not_mapping.py +6 -0
- package/ref-monty/crates/monty/test_cases/function__kwargs_unpacking.py +173 -0
- package/ref-monty/crates/monty/test_cases/function__ops.py +294 -0
- package/ref-monty/crates/monty/test_cases/function__return_none.py +42 -0
- package/ref-monty/crates/monty/test_cases/function__signatures.py +47 -0
- package/ref-monty/crates/monty/test_cases/function__too_few_args_all.py +6 -0
- package/ref-monty/crates/monty/test_cases/function__too_few_args_one.py +6 -0
- package/ref-monty/crates/monty/test_cases/function__too_few_args_two.py +6 -0
- package/ref-monty/crates/monty/test_cases/function__too_many_args_one.py +6 -0
- package/ref-monty/crates/monty/test_cases/function__too_many_args_two.py +6 -0
- package/ref-monty/crates/monty/test_cases/function__too_many_args_zero.py +6 -0
- package/ref-monty/crates/monty/test_cases/global__error_assigned_before.py +7 -0
- package/ref-monty/crates/monty/test_cases/global__ops.py +163 -0
- package/ref-monty/crates/monty/test_cases/hash__dict_unhashable.py +2 -0
- package/ref-monty/crates/monty/test_cases/hash__list_unhashable.py +2 -0
- package/ref-monty/crates/monty/test_cases/hash__ops.py +153 -0
- package/ref-monty/crates/monty/test_cases/id__bytes_literals_distinct.py +3 -0
- package/ref-monty/crates/monty/test_cases/id__int_copy_distinct.py +5 -0
- package/ref-monty/crates/monty/test_cases/id__is_number_is_number.py +3 -0
- package/ref-monty/crates/monty/test_cases/id__non_overlapping_lifetimes_distinct_types.py +10 -0
- package/ref-monty/crates/monty/test_cases/id__non_overlapping_lifetimes_same_types.py +6 -0
- package/ref-monty/crates/monty/test_cases/id__ops.py +97 -0
- package/ref-monty/crates/monty/test_cases/id__str_literals_same.py +3 -0
- package/ref-monty/crates/monty/test_cases/if__elif_else.py +207 -0
- package/ref-monty/crates/monty/test_cases/if__raise_elif.py +11 -0
- package/ref-monty/crates/monty/test_cases/if__raise_else.py +13 -0
- package/ref-monty/crates/monty/test_cases/if__raise_if.py +9 -0
- package/ref-monty/crates/monty/test_cases/if__raise_in_elif_condition.py +18 -0
- package/ref-monty/crates/monty/test_cases/if__raise_in_if_condition.py +16 -0
- package/ref-monty/crates/monty/test_cases/if_else_expr__all.py +55 -0
- package/ref-monty/crates/monty/test_cases/import__error_cannot_import.py +9 -0
- package/ref-monty/crates/monty/test_cases/import__error_module_not_found.py +9 -0
- package/ref-monty/crates/monty/test_cases/import__local_scope.py +68 -0
- package/ref-monty/crates/monty/test_cases/import__os.py +25 -0
- package/ref-monty/crates/monty/test_cases/import__relative_error.py +9 -0
- package/ref-monty/crates/monty/test_cases/import__relative_no_module_error.py +9 -0
- package/ref-monty/crates/monty/test_cases/import__runtime_error_when_executed.py +14 -0
- package/ref-monty/crates/monty/test_cases/import__star_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/import__sys.py +47 -0
- package/ref-monty/crates/monty/test_cases/import__sys_monty.py +28 -0
- package/ref-monty/crates/monty/test_cases/import__type_checking_guard.py +37 -0
- package/ref-monty/crates/monty/test_cases/import__typing.py +25 -0
- package/ref-monty/crates/monty/test_cases/import__typing_type_ignore.py +4 -0
- package/ref-monty/crates/monty/test_cases/int__bigint.py +467 -0
- package/ref-monty/crates/monty/test_cases/int__bigint_errors.py +260 -0
- package/ref-monty/crates/monty/test_cases/int__ops.py +219 -0
- package/ref-monty/crates/monty/test_cases/int__overflow_division.py +84 -0
- package/ref-monty/crates/monty/test_cases/is_variant__all.py +36 -0
- package/ref-monty/crates/monty/test_cases/isinstance__arg2_list_error.py +2 -0
- package/ref-monty/crates/monty/test_cases/isinstance__arg2_type_error.py +2 -0
- package/ref-monty/crates/monty/test_cases/iter__dict_mutation.py +4 -0
- package/ref-monty/crates/monty/test_cases/iter__for.py +243 -0
- package/ref-monty/crates/monty/test_cases/iter__for_loop_unpacking.py +66 -0
- package/ref-monty/crates/monty/test_cases/iter__generator_expr.py +20 -0
- package/ref-monty/crates/monty/test_cases/iter__generator_expr_type.py +7 -0
- package/ref-monty/crates/monty/test_cases/iter__not_iterable.py +3 -0
- package/ref-monty/crates/monty/test_cases/lambda__all.py +145 -0
- package/ref-monty/crates/monty/test_cases/list__extend_not_iterable.py +7 -0
- package/ref-monty/crates/monty/test_cases/list__getitem_out_of_bounds.py +3 -0
- package/ref-monty/crates/monty/test_cases/list__index_not_found.py +9 -0
- package/ref-monty/crates/monty/test_cases/list__index_start_gt_end.py +10 -0
- package/ref-monty/crates/monty/test_cases/list__ops.py +473 -0
- package/ref-monty/crates/monty/test_cases/list__pop_empty.py +9 -0
- package/ref-monty/crates/monty/test_cases/list__pop_out_of_range.py +9 -0
- package/ref-monty/crates/monty/test_cases/list__pop_type_error.py +9 -0
- package/ref-monty/crates/monty/test_cases/list__remove_not_found.py +9 -0
- package/ref-monty/crates/monty/test_cases/list__setitem_dict_index.py +13 -0
- package/ref-monty/crates/monty/test_cases/list__setitem_huge_int_index.py +13 -0
- package/ref-monty/crates/monty/test_cases/list__setitem_index_error.py +10 -0
- package/ref-monty/crates/monty/test_cases/list__setitem_type_error.py +10 -0
- package/ref-monty/crates/monty/test_cases/list__unpack_type_error.py +2 -0
- package/ref-monty/crates/monty/test_cases/longint__index_error.py +3 -0
- package/ref-monty/crates/monty/test_cases/longint__repeat_error.py +3 -0
- package/ref-monty/crates/monty/test_cases/loop__break_continue.py +113 -0
- package/ref-monty/crates/monty/test_cases/loop__break_finally.py +69 -0
- package/ref-monty/crates/monty/test_cases/loop__break_in_function_error.py +13 -0
- package/ref-monty/crates/monty/test_cases/loop__break_in_if_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/loop__break_nested_except_clears.py +55 -0
- package/ref-monty/crates/monty/test_cases/loop__break_outside_error.py +9 -0
- package/ref-monty/crates/monty/test_cases/loop__continue_finally.py +81 -0
- package/ref-monty/crates/monty/test_cases/loop__continue_in_function_error.py +13 -0
- package/ref-monty/crates/monty/test_cases/loop__continue_in_if_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/loop__continue_nested_except_clears.py +60 -0
- package/ref-monty/crates/monty/test_cases/loop__continue_outside_error.py +9 -0
- package/ref-monty/crates/monty/test_cases/math__acos_domain_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__acosh_domain_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__asin_domain_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__atanh_domain_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__cos_inf_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__cosh_overflow_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__exp_overflow_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__factorial_float_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__factorial_negative_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__floor_inf_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__floor_nan_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__floor_str_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__fmod_inf_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__gamma_neg_int_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__gcd_float_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__isqrt_negative_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__ldexp_overflow_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__log1p_domain_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__log_base1_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__log_zero_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__module.py +1432 -0
- package/ref-monty/crates/monty/test_cases/math__pow_domain_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__sin_inf_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__sqrt_negative_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__tan_inf_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/math__trunc_str_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/method__args_kwargs_unpacking.py +259 -0
- package/ref-monty/crates/monty/test_cases/name_error__unbound_local_func.py +19 -0
- package/ref-monty/crates/monty/test_cases/name_error__unbound_local_module.py +12 -0
- package/ref-monty/crates/monty/test_cases/name_error__undefined_call_chained.py +9 -0
- package/ref-monty/crates/monty/test_cases/name_error__undefined_call_in_expr.py +9 -0
- package/ref-monty/crates/monty/test_cases/name_error__undefined_call_in_function.py +16 -0
- package/ref-monty/crates/monty/test_cases/name_error__undefined_call_with_args.py +9 -0
- package/ref-monty/crates/monty/test_cases/name_error__undefined_global.py +10 -0
- package/ref-monty/crates/monty/test_cases/namedtuple__missing_attr.py +11 -0
- package/ref-monty/crates/monty/test_cases/namedtuple__ops.py +34 -0
- package/ref-monty/crates/monty/test_cases/nonlocal__error_module_level.py +3 -0
- package/ref-monty/crates/monty/test_cases/nonlocal__ops.py +353 -0
- package/ref-monty/crates/monty/test_cases/os__environ.py +40 -0
- package/ref-monty/crates/monty/test_cases/os__getenv_key_list_error.py +5 -0
- package/ref-monty/crates/monty/test_cases/os__getenv_key_type_error.py +5 -0
- package/ref-monty/crates/monty/test_cases/parse_error__complex.py +3 -0
- package/ref-monty/crates/monty/test_cases/pathlib__import.py +11 -0
- package/ref-monty/crates/monty/test_cases/pathlib__os.py +136 -0
- package/ref-monty/crates/monty/test_cases/pathlib__os_read_error.py +12 -0
- package/ref-monty/crates/monty/test_cases/pathlib__pure.py +81 -0
- package/ref-monty/crates/monty/test_cases/pyobject__cycle_dict_self.py +5 -0
- package/ref-monty/crates/monty/test_cases/pyobject__cycle_list_dict.py +6 -0
- package/ref-monty/crates/monty/test_cases/pyobject__cycle_list_self.py +5 -0
- package/ref-monty/crates/monty/test_cases/pyobject__cycle_multiple_refs.py +6 -0
- package/ref-monty/crates/monty/test_cases/range__error_no_args.py +2 -0
- package/ref-monty/crates/monty/test_cases/range__error_step_zero.py +2 -0
- package/ref-monty/crates/monty/test_cases/range__error_too_many_args.py +2 -0
- package/ref-monty/crates/monty/test_cases/range__getitem_index_error.py +10 -0
- package/ref-monty/crates/monty/test_cases/range__ops.py +236 -0
- package/ref-monty/crates/monty/test_cases/re__basic.py +756 -0
- package/ref-monty/crates/monty/test_cases/re__grouping.py +241 -0
- package/ref-monty/crates/monty/test_cases/re__match.py +148 -0
- package/ref-monty/crates/monty/test_cases/recursion__deep_drop.py +26 -0
- package/ref-monty/crates/monty/test_cases/recursion__deep_eq.py +23 -0
- package/ref-monty/crates/monty/test_cases/recursion__deep_hash.py +46 -0
- package/ref-monty/crates/monty/test_cases/recursion__deep_repr.py +12 -0
- package/ref-monty/crates/monty/test_cases/recursion__function_depth.py +13 -0
- package/ref-monty/crates/monty/test_cases/refcount__cycle_mutual_reference.py +18 -0
- package/ref-monty/crates/monty/test_cases/refcount__cycle_self_reference.py +12 -0
- package/ref-monty/crates/monty/test_cases/refcount__dict_basic.py +5 -0
- package/ref-monty/crates/monty/test_cases/refcount__dict_get.py +5 -0
- package/ref-monty/crates/monty/test_cases/refcount__dict_keys_and.py +14 -0
- package/ref-monty/crates/monty/test_cases/refcount__dict_overwrite.py +6 -0
- package/ref-monty/crates/monty/test_cases/refcount__gather_cleanup.py +16 -0
- package/ref-monty/crates/monty/test_cases/refcount__gather_exception.py +18 -0
- package/ref-monty/crates/monty/test_cases/refcount__gather_nested_cancel.py +25 -0
- package/ref-monty/crates/monty/test_cases/refcount__immediate_skipped.py +4 -0
- package/ref-monty/crates/monty/test_cases/refcount__kwargs_unpacking.py +27 -0
- package/ref-monty/crates/monty/test_cases/refcount__list_append_multiple.py +6 -0
- package/ref-monty/crates/monty/test_cases/refcount__list_append_ref.py +5 -0
- package/ref-monty/crates/monty/test_cases/refcount__list_concat.py +5 -0
- package/ref-monty/crates/monty/test_cases/refcount__list_getitem.py +5 -0
- package/ref-monty/crates/monty/test_cases/refcount__list_iadd.py +5 -0
- package/ref-monty/crates/monty/test_cases/refcount__nested_list.py +4 -0
- package/ref-monty/crates/monty/test_cases/refcount__re_pattern_sub_error_paths.py +37 -0
- package/ref-monty/crates/monty/test_cases/refcount__re_search_match.py +34 -0
- package/ref-monty/crates/monty/test_cases/refcount__re_sub_error_paths.py +31 -0
- package/ref-monty/crates/monty/test_cases/refcount__shared_reference.py +4 -0
- package/ref-monty/crates/monty/test_cases/refcount__single_list.py +3 -0
- package/ref-monty/crates/monty/test_cases/repr__cycle_detection.py +24 -0
- package/ref-monty/crates/monty/test_cases/set__ops.py +191 -0
- package/ref-monty/crates/monty/test_cases/set__review_bugs.py +35 -0
- package/ref-monty/crates/monty/test_cases/set__unpack_type_error.py +2 -0
- package/ref-monty/crates/monty/test_cases/slice__invalid_indices.py +2 -0
- package/ref-monty/crates/monty/test_cases/slice__kwargs.py +9 -0
- package/ref-monty/crates/monty/test_cases/slice__no_args.py +9 -0
- package/ref-monty/crates/monty/test_cases/slice__ops.py +149 -0
- package/ref-monty/crates/monty/test_cases/slice__step_zero.py +9 -0
- package/ref-monty/crates/monty/test_cases/slice__step_zero_bytes.py +9 -0
- package/ref-monty/crates/monty/test_cases/slice__step_zero_range.py +9 -0
- package/ref-monty/crates/monty/test_cases/slice__step_zero_str.py +9 -0
- package/ref-monty/crates/monty/test_cases/slice__step_zero_tuple.py +9 -0
- package/ref-monty/crates/monty/test_cases/slice__too_many_args.py +9 -0
- package/ref-monty/crates/monty/test_cases/str__getitem_index_error.py +10 -0
- package/ref-monty/crates/monty/test_cases/str__index_not_found.py +9 -0
- package/ref-monty/crates/monty/test_cases/str__join_no_args.py +9 -0
- package/ref-monty/crates/monty/test_cases/str__join_non_string.py +9 -0
- package/ref-monty/crates/monty/test_cases/str__join_not_iterable.py +9 -0
- package/ref-monty/crates/monty/test_cases/str__join_too_many_args.py +9 -0
- package/ref-monty/crates/monty/test_cases/str__methods.py +327 -0
- package/ref-monty/crates/monty/test_cases/str__ops.py +162 -0
- package/ref-monty/crates/monty/test_cases/str__partition_empty.py +9 -0
- package/ref-monty/crates/monty/test_cases/str__rsplit_empty_sep.py +9 -0
- package/ref-monty/crates/monty/test_cases/str__split_empty_sep.py +9 -0
- package/ref-monty/crates/monty/test_cases/sys__types.py +7 -0
- package/ref-monty/crates/monty/test_cases/traceback__division_error.py +30 -0
- package/ref-monty/crates/monty/test_cases/traceback__index_error.py +17 -0
- package/ref-monty/crates/monty/test_cases/traceback__insert_as_int.py +10 -0
- package/ref-monty/crates/monty/test_cases/traceback__nested_call.py +29 -0
- package/ref-monty/crates/monty/test_cases/traceback__nonlocal_module_scope.py +10 -0
- package/ref-monty/crates/monty/test_cases/traceback__nonlocal_unbound.py +24 -0
- package/ref-monty/crates/monty/test_cases/traceback__range_as_int.py +9 -0
- package/ref-monty/crates/monty/test_cases/traceback__recursion_error.py +23 -0
- package/ref-monty/crates/monty/test_cases/traceback__set_mutation.py +11 -0
- package/ref-monty/crates/monty/test_cases/traceback__undefined_attr_call.py +16 -0
- package/ref-monty/crates/monty/test_cases/traceback__undefined_call.py +16 -0
- package/ref-monty/crates/monty/test_cases/traceback__undefined_raise.py +16 -0
- package/ref-monty/crates/monty/test_cases/try_except__all.py +472 -0
- package/ref-monty/crates/monty/test_cases/try_except__bare_raise_no_context.py +2 -0
- package/ref-monty/crates/monty/test_cases/try_except__invalid_type.py +5 -0
- package/ref-monty/crates/monty/test_cases/tuple__getitem_out_of_bounds.py +3 -0
- package/ref-monty/crates/monty/test_cases/tuple__index_not_found.py +9 -0
- package/ref-monty/crates/monty/test_cases/tuple__index_start_gt_end.py +10 -0
- package/ref-monty/crates/monty/test_cases/tuple__methods.py +19 -0
- package/ref-monty/crates/monty/test_cases/tuple__ops.py +133 -0
- package/ref-monty/crates/monty/test_cases/tuple__unpack_type_error.py +2 -0
- package/ref-monty/crates/monty/test_cases/type__builtin_attr_error.py +9 -0
- package/ref-monty/crates/monty/test_cases/type__bytes_negative.py +2 -0
- package/ref-monty/crates/monty/test_cases/type__cell_not_builtin.py +9 -0
- package/ref-monty/crates/monty/test_cases/type__exception_attr_error.py +11 -0
- package/ref-monty/crates/monty/test_cases/type__float_conversion_error.py +2 -0
- package/ref-monty/crates/monty/test_cases/type__float_repr_both_quotes.py +9 -0
- package/ref-monty/crates/monty/test_cases/type__float_repr_newline.py +9 -0
- package/ref-monty/crates/monty/test_cases/type__float_repr_single_quote.py +9 -0
- package/ref-monty/crates/monty/test_cases/type__int_conversion_error.py +2 -0
- package/ref-monty/crates/monty/test_cases/type__list_not_iterable.py +2 -0
- package/ref-monty/crates/monty/test_cases/type__non_builtin_name_error.py +9 -0
- package/ref-monty/crates/monty/test_cases/type__ops.py +200 -0
- package/ref-monty/crates/monty/test_cases/type__shadow_exc.py +3 -0
- package/ref-monty/crates/monty/test_cases/type__shadow_int.py +9 -0
- package/ref-monty/crates/monty/test_cases/type__shadow_len.py +3 -0
- package/ref-monty/crates/monty/test_cases/type__tuple_not_iterable.py +2 -0
- package/ref-monty/crates/monty/test_cases/type_error__int_add_list.py +2 -0
- package/ref-monty/crates/monty/test_cases/type_error__int_div_str.py +2 -0
- package/ref-monty/crates/monty/test_cases/type_error__int_floordiv_str.py +2 -0
- package/ref-monty/crates/monty/test_cases/type_error__int_iadd_str.py +3 -0
- package/ref-monty/crates/monty/test_cases/type_error__int_mod_str.py +2 -0
- package/ref-monty/crates/monty/test_cases/type_error__int_pow_str.py +2 -0
- package/ref-monty/crates/monty/test_cases/type_error__int_sub_str.py +2 -0
- package/ref-monty/crates/monty/test_cases/type_error__list_add_int.py +2 -0
- package/ref-monty/crates/monty/test_cases/type_error__list_add_str.py +2 -0
- package/ref-monty/crates/monty/test_cases/type_error__list_iadd_int.py +6 -0
- package/ref-monty/crates/monty/test_cases/type_error__str_add_int.py +2 -0
- package/ref-monty/crates/monty/test_cases/type_error__str_iadd_int.py +3 -0
- package/ref-monty/crates/monty/test_cases/type_error__unary_invert_str.py +3 -0
- package/ref-monty/crates/monty/test_cases/type_error__unary_minus_str.py +4 -0
- package/ref-monty/crates/monty/test_cases/type_error__unary_neg_str.py +3 -0
- package/ref-monty/crates/monty/test_cases/type_error__unary_plus_str.py +4 -0
- package/ref-monty/crates/monty/test_cases/typing__types.py +24 -0
- package/ref-monty/crates/monty/test_cases/unpack__nested.py +48 -0
- package/ref-monty/crates/monty/test_cases/unpack__non_sequence.py +9 -0
- package/ref-monty/crates/monty/test_cases/unpack__not_enough.py +9 -0
- package/ref-monty/crates/monty/test_cases/unpack__ops.py +153 -0
- package/ref-monty/crates/monty/test_cases/unpack__star_not_enough.py +9 -0
- package/ref-monty/crates/monty/test_cases/unpack__too_many.py +9 -0
- package/ref-monty/crates/monty/test_cases/version__cpython.py +4 -0
- package/ref-monty/crates/monty/test_cases/walrus__all.py +178 -0
- package/ref-monty/crates/monty/test_cases/while__all.py +206 -0
- package/ref-monty/crates/monty/tests/asyncio.rs +764 -0
- package/ref-monty/crates/monty/tests/binary_serde.rs +185 -0
- package/ref-monty/crates/monty/tests/bytecode_limits.rs +248 -0
- package/ref-monty/crates/monty/tests/datatest_runner.rs +2029 -0
- package/ref-monty/crates/monty/tests/inputs.rs +420 -0
- package/ref-monty/crates/monty/tests/json_serde.rs +250 -0
- package/ref-monty/crates/monty/tests/main.rs +71 -0
- package/ref-monty/crates/monty/tests/math_module.rs +114 -0
- package/ref-monty/crates/monty/tests/name_lookup.rs +482 -0
- package/ref-monty/crates/monty/tests/os_tests.rs +459 -0
- package/ref-monty/crates/monty/tests/parse_errors.rs +441 -0
- package/ref-monty/crates/monty/tests/print_writer.rs +238 -0
- package/ref-monty/crates/monty/tests/py_object.rs +121 -0
- package/ref-monty/crates/monty/tests/regex.rs +90 -0
- package/ref-monty/crates/monty/tests/repl.rs +344 -0
- package/ref-monty/crates/monty/tests/resource_limits.rs +1826 -0
- package/ref-monty/crates/monty/tests/try_from.rs +167 -0
- package/ref-monty/crates/monty-cli/Cargo.toml +25 -0
- package/ref-monty/crates/monty-cli/src/main.rs +541 -0
- package/ref-monty/crates/monty-js/.cargo/config.toml +2 -0
- package/ref-monty/crates/monty-js/.prettierignore +8 -0
- package/ref-monty/crates/monty-js/Cargo.toml +32 -0
- package/ref-monty/crates/monty-js/README.md +207 -0
- package/ref-monty/crates/monty-js/__test__/async.spec.ts +350 -0
- package/ref-monty/crates/monty-js/__test__/basic.spec.ts +114 -0
- package/ref-monty/crates/monty-js/__test__/exceptions.spec.ts +427 -0
- package/ref-monty/crates/monty-js/__test__/external.spec.ts +354 -0
- package/ref-monty/crates/monty-js/__test__/inputs.spec.ts +143 -0
- package/ref-monty/crates/monty-js/__test__/limits.spec.ts +162 -0
- package/ref-monty/crates/monty-js/__test__/package.json +3 -0
- package/ref-monty/crates/monty-js/__test__/print.spec.ts +229 -0
- package/ref-monty/crates/monty-js/__test__/repl.spec.ts +34 -0
- package/ref-monty/crates/monty-js/__test__/serialize.spec.ts +205 -0
- package/ref-monty/crates/monty-js/__test__/start.spec.ts +443 -0
- package/ref-monty/crates/monty-js/__test__/type_check.spec.ts +147 -0
- package/ref-monty/crates/monty-js/__test__/types.spec.ts +319 -0
- package/ref-monty/crates/monty-js/build.rs +61 -0
- package/ref-monty/crates/monty-js/index-header.d.ts +3 -0
- package/ref-monty/crates/monty-js/package-lock.json +4694 -0
- package/ref-monty/crates/monty-js/package.json +100 -0
- package/ref-monty/crates/monty-js/scripts/smoke-test.sh +69 -0
- package/ref-monty/crates/monty-js/smoke-test/package.json +17 -0
- package/ref-monty/crates/monty-js/smoke-test/test.ts +171 -0
- package/ref-monty/crates/monty-js/smoke-test/tsconfig.json +11 -0
- package/ref-monty/crates/monty-js/src/convert.rs +648 -0
- package/ref-monty/crates/monty-js/src/exceptions.rs +293 -0
- package/ref-monty/crates/monty-js/src/lib.rs +41 -0
- package/ref-monty/crates/monty-js/src/limits.rs +53 -0
- package/ref-monty/crates/monty-js/src/monty_cls.rs +1407 -0
- package/ref-monty/crates/monty-js/tsconfig.json +17 -0
- package/ref-monty/crates/monty-js/wrapper.ts +701 -0
- package/ref-monty/crates/monty-python/Cargo.toml +38 -0
- package/ref-monty/crates/monty-python/README.md +134 -0
- package/ref-monty/crates/monty-python/build.rs +4 -0
- package/ref-monty/crates/monty-python/example.py +40 -0
- package/ref-monty/crates/monty-python/exercise.py +46 -0
- package/ref-monty/crates/monty-python/pyproject.toml +57 -0
- package/ref-monty/crates/monty-python/python/pydantic_monty/__init__.py +281 -0
- package/ref-monty/crates/monty-python/python/pydantic_monty/_monty.pyi +677 -0
- package/ref-monty/crates/monty-python/python/pydantic_monty/os_access.py +933 -0
- package/ref-monty/crates/monty-python/python/pydantic_monty/py.typed +0 -0
- package/ref-monty/crates/monty-python/src/convert.rs +273 -0
- package/ref-monty/crates/monty-python/src/dataclass.rs +461 -0
- package/ref-monty/crates/monty-python/src/exceptions.rs +557 -0
- package/ref-monty/crates/monty-python/src/external.rs +165 -0
- package/ref-monty/crates/monty-python/src/lib.rs +77 -0
- package/ref-monty/crates/monty-python/src/limits.rs +142 -0
- package/ref-monty/crates/monty-python/src/monty_cls.rs +1650 -0
- package/ref-monty/crates/monty-python/src/repl.rs +470 -0
- package/ref-monty/crates/monty-python/src/serialization.rs +761 -0
- package/ref-monty/crates/monty-python/tests/test_async.py +1201 -0
- package/ref-monty/crates/monty-python/tests/test_basic.py +66 -0
- package/ref-monty/crates/monty-python/tests/test_dataclasses.py +971 -0
- package/ref-monty/crates/monty-python/tests/test_exceptions.py +361 -0
- package/ref-monty/crates/monty-python/tests/test_external.py +367 -0
- package/ref-monty/crates/monty-python/tests/test_inputs.py +126 -0
- package/ref-monty/crates/monty-python/tests/test_limits.py +257 -0
- package/ref-monty/crates/monty-python/tests/test_os_access.py +1286 -0
- package/ref-monty/crates/monty-python/tests/test_os_access_compat.py +731 -0
- package/ref-monty/crates/monty-python/tests/test_os_access_raw.py +483 -0
- package/ref-monty/crates/monty-python/tests/test_os_calls.py +819 -0
- package/ref-monty/crates/monty-python/tests/test_print.py +208 -0
- package/ref-monty/crates/monty-python/tests/test_re.py +170 -0
- package/ref-monty/crates/monty-python/tests/test_readme_examples.py +20 -0
- package/ref-monty/crates/monty-python/tests/test_repl.py +749 -0
- package/ref-monty/crates/monty-python/tests/test_serialize.py +284 -0
- package/ref-monty/crates/monty-python/tests/test_start.py +346 -0
- package/ref-monty/crates/monty-python/tests/test_threading.py +163 -0
- package/ref-monty/crates/monty-python/tests/test_type_check.py +344 -0
- package/ref-monty/crates/monty-python/tests/test_types.py +553 -0
- package/ref-monty/crates/monty-type-checking/Cargo.toml +32 -0
- package/ref-monty/crates/monty-type-checking/src/db.rs +116 -0
- package/ref-monty/crates/monty-type-checking/src/lib.rs +4 -0
- package/ref-monty/crates/monty-type-checking/src/type_check.rs +280 -0
- package/ref-monty/crates/monty-type-checking/tests/bad_types.py +109 -0
- package/ref-monty/crates/monty-type-checking/tests/bad_types_output.txt +21 -0
- package/ref-monty/crates/monty-type-checking/tests/good_types.py +475 -0
- package/ref-monty/crates/monty-type-checking/tests/main.rs +205 -0
- package/ref-monty/crates/monty-type-checking/tests/reveal_types.py +56 -0
- package/ref-monty/crates/monty-type-checking/tests/reveal_types_output.txt +41 -0
- package/ref-monty/crates/monty-typeshed/Cargo.toml +29 -0
- package/ref-monty/crates/monty-typeshed/README.md +11 -0
- package/ref-monty/crates/monty-typeshed/build.rs +101 -0
- package/ref-monty/crates/monty-typeshed/custom/README.md +1 -0
- package/ref-monty/crates/monty-typeshed/custom/asyncio.pyi +138 -0
- package/ref-monty/crates/monty-typeshed/custom/os.pyi +87 -0
- package/ref-monty/crates/monty-typeshed/custom/sys.pyi +33 -0
- package/ref-monty/crates/monty-typeshed/src/lib.rs +56 -0
- package/ref-monty/crates/monty-typeshed/update.py +321 -0
- package/ref-monty/crates/monty-typeshed/vendor/typeshed/source_commit.txt +1 -0
- package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/VERSIONS +20 -0
- package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/_collections_abc.pyi +105 -0
- package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/_typeshed/__init__.pyi +394 -0
- package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/asyncio.pyi +138 -0
- package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/builtins.pyi +1434 -0
- package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/collections/__init__.pyi +527 -0
- package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/collections/abc.pyi +2 -0
- package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/dataclasses.pyi +502 -0
- package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/enum.pyi +376 -0
- package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/math.pyi +149 -0
- package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/os.pyi +87 -0
- package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/pathlib/__init__.pyi +395 -0
- package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/pathlib/types.pyi +8 -0
- package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/re.pyi +337 -0
- package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/sys.pyi +33 -0
- package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/types.pyi +741 -0
- package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/typing.pyi +1217 -0
- package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/typing_extensions.pyi +716 -0
- package/ref-monty/docs/usage-guide.md +117 -0
- package/ref-monty/examples/README.md +3 -0
- package/ref-monty/examples/expense_analysis/README.md +3 -0
- package/ref-monty/examples/expense_analysis/data.py +124 -0
- package/ref-monty/examples/expense_analysis/main.py +115 -0
- package/ref-monty/examples/sql_playground/README.md +20 -0
- package/ref-monty/examples/sql_playground/external_functions.py +129 -0
- package/ref-monty/examples/sql_playground/main.py +81 -0
- package/ref-monty/examples/sql_playground/sandbox_code.py +82 -0
- package/ref-monty/examples/sql_playground/type_stubs.pyi +14 -0
- package/ref-monty/examples/web_scraper/README.md +15 -0
- package/ref-monty/examples/web_scraper/browser.py +56 -0
- package/ref-monty/examples/web_scraper/example_code.py +59 -0
- package/ref-monty/examples/web_scraper/external_functions.py +324 -0
- package/ref-monty/examples/web_scraper/main.py +193 -0
- package/ref-monty/examples/web_scraper/sub_agent.py +79 -0
- package/ref-monty/monty-npm.md +235 -0
- package/ref-monty/pyproject.toml +162 -0
- package/ref-monty/scripts/check_imports.py +91 -0
- package/ref-monty/scripts/codecov_diff.py +412 -0
- package/ref-monty/scripts/complete_tests.py +146 -0
- package/ref-monty/scripts/flamegraph_to_text.py +208 -0
- package/ref-monty/scripts/iter_test_methods.py +540 -0
- package/ref-monty/scripts/run_traceback.py +180 -0
- package/ref-monty/scripts/startup_performance.py +130 -0
- package/ref-monty/uv.lock +1779 -0
- package/temp_resend_cli/repo/.github/scripts/pr-title-check.js +34 -0
- package/temp_resend_cli/repo/.github/workflows/ci.yml +67 -0
- package/temp_resend_cli/repo/.github/workflows/post-release.yml +51 -0
- package/temp_resend_cli/repo/.github/workflows/pr-title-check.yml +13 -0
- package/temp_resend_cli/repo/.github/workflows/release.yml +175 -0
- package/temp_resend_cli/repo/.github/workflows/test-install-unix.yml +34 -0
- package/temp_resend_cli/repo/.github/workflows/test-install-windows.yml +48 -0
- package/temp_resend_cli/repo/CHANGELOG.md +31 -0
- package/temp_resend_cli/repo/LICENSE +21 -0
- package/temp_resend_cli/repo/README.md +450 -0
- package/temp_resend_cli/repo/biome.json +36 -0
- package/temp_resend_cli/repo/install.ps1 +141 -0
- package/temp_resend_cli/repo/install.sh +301 -0
- package/temp_resend_cli/repo/package.json +61 -0
- package/temp_resend_cli/repo/pnpm-lock.yaml +2439 -0
- package/temp_resend_cli/repo/renovate.json +4 -0
- package/temp_resend_cli/repo/src/cli.ts +98 -0
- package/temp_resend_cli/repo/src/commands/api-keys/create.ts +114 -0
- package/temp_resend_cli/repo/src/commands/api-keys/delete.ts +47 -0
- package/temp_resend_cli/repo/src/commands/api-keys/index.ts +26 -0
- package/temp_resend_cli/repo/src/commands/api-keys/list.ts +35 -0
- package/temp_resend_cli/repo/src/commands/api-keys/utils.ts +8 -0
- package/temp_resend_cli/repo/src/commands/auth/index.ts +20 -0
- package/temp_resend_cli/repo/src/commands/auth/login.ts +234 -0
- package/temp_resend_cli/repo/src/commands/auth/logout.ts +105 -0
- package/temp_resend_cli/repo/src/commands/broadcasts/create.ts +196 -0
- package/temp_resend_cli/repo/src/commands/broadcasts/delete.ts +46 -0
- package/temp_resend_cli/repo/src/commands/broadcasts/get.ts +59 -0
- package/temp_resend_cli/repo/src/commands/broadcasts/index.ts +43 -0
- package/temp_resend_cli/repo/src/commands/broadcasts/list.ts +60 -0
- package/temp_resend_cli/repo/src/commands/broadcasts/send.ts +56 -0
- package/temp_resend_cli/repo/src/commands/broadcasts/update.ts +95 -0
- package/temp_resend_cli/repo/src/commands/broadcasts/utils.ts +35 -0
- package/temp_resend_cli/repo/src/commands/contact-properties/create.ts +118 -0
- package/temp_resend_cli/repo/src/commands/contact-properties/delete.ts +48 -0
- package/temp_resend_cli/repo/src/commands/contact-properties/get.ts +46 -0
- package/temp_resend_cli/repo/src/commands/contact-properties/index.ts +48 -0
- package/temp_resend_cli/repo/src/commands/contact-properties/list.ts +68 -0
- package/temp_resend_cli/repo/src/commands/contact-properties/update.ts +88 -0
- package/temp_resend_cli/repo/src/commands/contact-properties/utils.ts +17 -0
- package/temp_resend_cli/repo/src/commands/contacts/add-segment.ts +78 -0
- package/temp_resend_cli/repo/src/commands/contacts/create.ts +122 -0
- package/temp_resend_cli/repo/src/commands/contacts/delete.ts +49 -0
- package/temp_resend_cli/repo/src/commands/contacts/get.ts +53 -0
- package/temp_resend_cli/repo/src/commands/contacts/index.ts +58 -0
- package/temp_resend_cli/repo/src/commands/contacts/list.ts +57 -0
- package/temp_resend_cli/repo/src/commands/contacts/remove-segment.ts +48 -0
- package/temp_resend_cli/repo/src/commands/contacts/segments.ts +39 -0
- package/temp_resend_cli/repo/src/commands/contacts/topics.ts +45 -0
- package/temp_resend_cli/repo/src/commands/contacts/update-topics.ts +90 -0
- package/temp_resend_cli/repo/src/commands/contacts/update.ts +77 -0
- package/temp_resend_cli/repo/src/commands/contacts/utils.ts +119 -0
- package/temp_resend_cli/repo/src/commands/doctor.ts +216 -0
- package/temp_resend_cli/repo/src/commands/domains/create.ts +83 -0
- package/temp_resend_cli/repo/src/commands/domains/delete.ts +42 -0
- package/temp_resend_cli/repo/src/commands/domains/get.ts +47 -0
- package/temp_resend_cli/repo/src/commands/domains/index.ts +35 -0
- package/temp_resend_cli/repo/src/commands/domains/list.ts +53 -0
- package/temp_resend_cli/repo/src/commands/domains/update.ts +75 -0
- package/temp_resend_cli/repo/src/commands/domains/utils.ts +44 -0
- package/temp_resend_cli/repo/src/commands/domains/verify.ts +38 -0
- package/temp_resend_cli/repo/src/commands/emails/batch.ts +140 -0
- package/temp_resend_cli/repo/src/commands/emails/get.ts +44 -0
- package/temp_resend_cli/repo/src/commands/emails/index.ts +30 -0
- package/temp_resend_cli/repo/src/commands/emails/list.ts +84 -0
- package/temp_resend_cli/repo/src/commands/emails/receiving/attachment.ts +55 -0
- package/temp_resend_cli/repo/src/commands/emails/receiving/attachments.ts +68 -0
- package/temp_resend_cli/repo/src/commands/emails/receiving/get.ts +58 -0
- package/temp_resend_cli/repo/src/commands/emails/receiving/index.ts +28 -0
- package/temp_resend_cli/repo/src/commands/emails/receiving/list.ts +59 -0
- package/temp_resend_cli/repo/src/commands/emails/receiving/utils.ts +38 -0
- package/temp_resend_cli/repo/src/commands/emails/send.ts +189 -0
- package/temp_resend_cli/repo/src/commands/open.ts +27 -0
- package/temp_resend_cli/repo/src/commands/segments/create.ts +50 -0
- package/temp_resend_cli/repo/src/commands/segments/delete.ts +47 -0
- package/temp_resend_cli/repo/src/commands/segments/get.ts +38 -0
- package/temp_resend_cli/repo/src/commands/segments/index.ts +36 -0
- package/temp_resend_cli/repo/src/commands/segments/list.ts +58 -0
- package/temp_resend_cli/repo/src/commands/segments/utils.ts +7 -0
- package/temp_resend_cli/repo/src/commands/teams/index.ts +10 -0
- package/temp_resend_cli/repo/src/commands/teams/list.ts +35 -0
- package/temp_resend_cli/repo/src/commands/teams/remove.ts +86 -0
- package/temp_resend_cli/repo/src/commands/teams/switch.ts +76 -0
- package/temp_resend_cli/repo/src/commands/topics/create.ts +73 -0
- package/temp_resend_cli/repo/src/commands/topics/delete.ts +47 -0
- package/temp_resend_cli/repo/src/commands/topics/get.ts +42 -0
- package/temp_resend_cli/repo/src/commands/topics/index.ts +42 -0
- package/temp_resend_cli/repo/src/commands/topics/list.ts +34 -0
- package/temp_resend_cli/repo/src/commands/topics/update.ts +59 -0
- package/temp_resend_cli/repo/src/commands/topics/utils.ts +16 -0
- package/temp_resend_cli/repo/src/commands/webhooks/create.ts +128 -0
- package/temp_resend_cli/repo/src/commands/webhooks/delete.ts +49 -0
- package/temp_resend_cli/repo/src/commands/webhooks/get.ts +42 -0
- package/temp_resend_cli/repo/src/commands/webhooks/index.ts +42 -0
- package/temp_resend_cli/repo/src/commands/webhooks/list.ts +55 -0
- package/temp_resend_cli/repo/src/commands/webhooks/listen.ts +379 -0
- package/temp_resend_cli/repo/src/commands/webhooks/update.ts +83 -0
- package/temp_resend_cli/repo/src/commands/webhooks/utils.ts +36 -0
- package/temp_resend_cli/repo/src/commands/whoami.ts +71 -0
- package/temp_resend_cli/repo/src/lib/actions.ts +157 -0
- package/temp_resend_cli/repo/src/lib/client.ts +37 -0
- package/temp_resend_cli/repo/src/lib/config.ts +217 -0
- package/temp_resend_cli/repo/src/lib/files.ts +15 -0
- package/temp_resend_cli/repo/src/lib/help-text.ts +38 -0
- package/temp_resend_cli/repo/src/lib/output.ts +56 -0
- package/temp_resend_cli/repo/src/lib/pagination.ts +36 -0
- package/temp_resend_cli/repo/src/lib/prompts.ts +149 -0
- package/temp_resend_cli/repo/src/lib/spinner.ts +100 -0
- package/temp_resend_cli/repo/src/lib/table.ts +57 -0
- package/temp_resend_cli/repo/src/lib/tty.ts +28 -0
- package/temp_resend_cli/repo/src/lib/update-check.ts +169 -0
- package/temp_resend_cli/repo/src/lib/version.ts +4 -0
- package/temp_resend_cli/repo/tests/commands/api-keys/create.test.ts +196 -0
- package/temp_resend_cli/repo/tests/commands/api-keys/delete.test.ts +157 -0
- package/temp_resend_cli/repo/tests/commands/api-keys/list.test.ts +134 -0
- package/temp_resend_cli/repo/tests/commands/auth/login.test.ts +153 -0
- package/temp_resend_cli/repo/tests/commands/auth/logout.test.ts +153 -0
- package/temp_resend_cli/repo/tests/commands/broadcasts/create.test.ts +454 -0
- package/temp_resend_cli/repo/tests/commands/broadcasts/delete.test.ts +183 -0
- package/temp_resend_cli/repo/tests/commands/broadcasts/get.test.ts +147 -0
- package/temp_resend_cli/repo/tests/commands/broadcasts/list.test.ts +199 -0
- package/temp_resend_cli/repo/tests/commands/broadcasts/send.test.ts +162 -0
- package/temp_resend_cli/repo/tests/commands/broadcasts/update.test.ts +288 -0
- package/temp_resend_cli/repo/tests/commands/contact-properties/create.test.ts +251 -0
- package/temp_resend_cli/repo/tests/commands/contact-properties/delete.test.ts +184 -0
- package/temp_resend_cli/repo/tests/commands/contact-properties/get.test.ts +145 -0
- package/temp_resend_cli/repo/tests/commands/contact-properties/list.test.ts +181 -0
- package/temp_resend_cli/repo/tests/commands/contact-properties/update.test.ts +217 -0
- package/temp_resend_cli/repo/tests/commands/contacts/add-segment.test.ts +189 -0
- package/temp_resend_cli/repo/tests/commands/contacts/create.test.ts +271 -0
- package/temp_resend_cli/repo/tests/commands/contacts/delete.test.ts +193 -0
- package/temp_resend_cli/repo/tests/commands/contacts/get.test.ts +149 -0
- package/temp_resend_cli/repo/tests/commands/contacts/list.test.ts +176 -0
- package/temp_resend_cli/repo/tests/commands/contacts/remove-segment.test.ts +167 -0
- package/temp_resend_cli/repo/tests/commands/contacts/segments.test.ts +168 -0
- package/temp_resend_cli/repo/tests/commands/contacts/topics.test.ts +164 -0
- package/temp_resend_cli/repo/tests/commands/contacts/update-topics.test.ts +248 -0
- package/temp_resend_cli/repo/tests/commands/contacts/update.test.ts +206 -0
- package/temp_resend_cli/repo/tests/commands/doctor.test.ts +164 -0
- package/temp_resend_cli/repo/tests/commands/domains/create.test.ts +193 -0
- package/temp_resend_cli/repo/tests/commands/domains/delete.test.ts +157 -0
- package/temp_resend_cli/repo/tests/commands/domains/get.test.ts +138 -0
- package/temp_resend_cli/repo/tests/commands/domains/list.test.ts +165 -0
- package/temp_resend_cli/repo/tests/commands/domains/update.test.ts +224 -0
- package/temp_resend_cli/repo/tests/commands/domains/verify.test.ts +118 -0
- package/temp_resend_cli/repo/tests/commands/emails/batch.test.ts +324 -0
- package/temp_resend_cli/repo/tests/commands/emails/get.test.ts +132 -0
- package/temp_resend_cli/repo/tests/commands/emails/receiving/attachment.test.ts +141 -0
- package/temp_resend_cli/repo/tests/commands/emails/receiving/attachments.test.ts +169 -0
- package/temp_resend_cli/repo/tests/commands/emails/receiving/get.test.ts +141 -0
- package/temp_resend_cli/repo/tests/commands/emails/receiving/list.test.ts +182 -0
- package/temp_resend_cli/repo/tests/commands/emails/send.test.ts +312 -0
- package/temp_resend_cli/repo/tests/commands/segments/create.test.ts +164 -0
- package/temp_resend_cli/repo/tests/commands/segments/delete.test.ts +183 -0
- package/temp_resend_cli/repo/tests/commands/segments/get.test.ts +138 -0
- package/temp_resend_cli/repo/tests/commands/segments/list.test.ts +174 -0
- package/temp_resend_cli/repo/tests/commands/teams/list.test.ts +62 -0
- package/temp_resend_cli/repo/tests/commands/teams/remove.test.ts +110 -0
- package/temp_resend_cli/repo/tests/commands/teams/switch.test.ts +103 -0
- package/temp_resend_cli/repo/tests/commands/topics/create.test.ts +192 -0
- package/temp_resend_cli/repo/tests/commands/topics/delete.test.ts +157 -0
- package/temp_resend_cli/repo/tests/commands/topics/get.test.ts +126 -0
- package/temp_resend_cli/repo/tests/commands/topics/list.test.ts +125 -0
- package/temp_resend_cli/repo/tests/commands/topics/update.test.ts +178 -0
- package/temp_resend_cli/repo/tests/commands/webhooks/create.test.ts +225 -0
- package/temp_resend_cli/repo/tests/commands/webhooks/delete.test.ts +157 -0
- package/temp_resend_cli/repo/tests/commands/webhooks/get.test.ts +126 -0
- package/temp_resend_cli/repo/tests/commands/webhooks/list.test.ts +178 -0
- package/temp_resend_cli/repo/tests/commands/webhooks/update.test.ts +207 -0
- package/temp_resend_cli/repo/tests/commands/whoami.test.ts +98 -0
- package/temp_resend_cli/repo/tests/e2e/smoke.test.ts +93 -0
- package/temp_resend_cli/repo/tests/helpers.ts +86 -0
- package/temp_resend_cli/repo/tests/lib/client.test.ts +71 -0
- package/temp_resend_cli/repo/tests/lib/config.test.ts +451 -0
- package/temp_resend_cli/repo/tests/lib/files.test.ts +73 -0
- package/temp_resend_cli/repo/tests/lib/help-text.test.ts +97 -0
- package/temp_resend_cli/repo/tests/lib/output.test.ts +136 -0
- package/temp_resend_cli/repo/tests/lib/prompts.test.ts +185 -0
- package/temp_resend_cli/repo/tests/lib/spinner.test.ts +166 -0
- package/temp_resend_cli/repo/tests/lib/table.test.ts +63 -0
- package/temp_resend_cli/repo/tests/lib/tty.test.ts +89 -0
- package/temp_resend_cli/repo/tests/lib/update-check.test.ts +179 -0
- package/temp_resend_cli/repo/tsconfig.json +14 -0
- package/temp_resend_cli/repo/vitest.config.e2e.ts +8 -0
- package/temp_resend_cli/repo/vitest.config.ts +10 -0
- package/tests/test-mcp-browser-use-smoke.sh +28 -56
- package/tests/test-monty-smoke.sh +32 -0
- 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
|
+
}
|