superacli 1.1.6 → 1.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1262) hide show
  1. package/README.md +77 -53
  2. package/__tests__/azd-plugin.test.js +109 -0
  3. package/__tests__/config.test.js +4 -3
  4. package/__tests__/discover.test.js +59 -0
  5. package/__tests__/goose-plugin.test.js +149 -0
  6. package/__tests__/help-json.test.js +2 -0
  7. package/__tests__/openhands-plugin.test.js +106 -0
  8. package/__tests__/plugin-cocoindex-code-uninstall.test.js +19 -0
  9. package/__tests__/plugin-cocoindex-code.test.js +37 -0
  10. package/__tests__/plugin-install-guidance.test.js +81 -0
  11. package/__tests__/plugins-registry.test.js +44 -0
  12. package/__tests__/plugins-store.test.js +40 -5
  13. package/__tests__/process-adapter.test.js +50 -1
  14. package/__tests__/server-app.test.js +1 -0
  15. package/__tests__/server-routes-commands.test.js +20 -2
  16. package/__tests__/server-routes-plugins.test.js +130 -0
  17. package/__tests__/skills.test.js +26 -0
  18. package/__tests__/squirrelscan-plugin.test.js +129 -0
  19. package/__tests__/uipath-plugin.test.js +104 -0
  20. package/__tests__/uipathcli-plugin.test.js +95 -0
  21. package/cli/adapters/mcp.js +2 -0
  22. package/cli/adapters/process.js +49 -2
  23. package/cli/config.js +240 -3
  24. package/cli/discover.js +157 -0
  25. package/cli/help-json.js +16 -1
  26. package/cli/plugin-install-guidance.js +92 -37
  27. package/cli/plugins-manager.js +1 -0
  28. package/cli/plugins-registry.js +74 -8
  29. package/cli/plugins-store.js +78 -17
  30. package/cli/skills-mcp.js +1 -1
  31. package/cli/skills.js +39 -2
  32. package/cli/supercli.js +87 -11
  33. package/docs/feature-gaps.md +8 -8
  34. package/docs/features/azd-uipath-plugins.md +43 -0
  35. package/docs/features/server-plugins.md +62 -0
  36. package/docs/features/skills.md +9 -5
  37. package/docs/{supported-harnesses.md → plugins-available.md} +4 -3
  38. package/docs/{plugin-harness-guide.md → plugins-how-to.md} +1 -1
  39. package/docs/plugins.md +26 -20
  40. package/docs/server-plugins-usage-guide.md +182 -0
  41. package/docs/skills-catalog.md +12 -10
  42. package/package.json +1 -1
  43. package/plugins/agent-browser/README.md +69 -0
  44. package/plugins/agent-browser/plugin.json +111 -0
  45. package/plugins/agent-browser/skills/quickstart/SKILL.md +66 -0
  46. package/plugins/aider/README.md +53 -0
  47. package/plugins/aider/plugin.json +105 -0
  48. package/plugins/aider/scripts/aider-wrapper.js +243 -0
  49. package/plugins/aider/scripts/setup-aider.js +37 -0
  50. package/plugins/aider/skills/dry-run-review.md +24 -0
  51. package/plugins/aider/skills/model-and-provider.md +24 -0
  52. package/plugins/aider/skills/one-shot-edits.md +30 -0
  53. package/plugins/aider/skills/quickstart/SKILL.md +51 -0
  54. package/plugins/azd/README.md +28 -0
  55. package/plugins/azd/plugin.json +87 -0
  56. package/plugins/azd/skills/quickstart/SKILL.md +41 -0
  57. package/plugins/blogwatcher/README.md +3 -3
  58. package/plugins/boxlite/Dockerfile +9 -0
  59. package/plugins/boxlite/README.md +62 -0
  60. package/plugins/boxlite/plugin.json +201 -0
  61. package/plugins/boxlite/scripts/run-boxlite.js +106 -0
  62. package/plugins/boxlite/skills/quickstart/SKILL.md +40 -0
  63. package/plugins/cass/plugin.json +150 -0
  64. package/plugins/cass/scripts/setup-cass.js +47 -0
  65. package/plugins/cass/skills/quickstart/SKILL.md +46 -0
  66. package/plugins/clever/README.md +46 -0
  67. package/plugins/clever/plugin.json +119 -0
  68. package/plugins/clever/scripts/setup-clever.js +28 -0
  69. package/plugins/clever/skills/auth-and-profile.md +29 -0
  70. package/plugins/clever/skills/passthrough-safety.md +21 -0
  71. package/plugins/clever/skills/quickstart/SKILL.md +45 -0
  72. package/plugins/clever/skills/resource-inventory.md +24 -0
  73. package/plugins/clix/README.md +4 -4
  74. package/plugins/cocoindex-code/README.md +64 -0
  75. package/plugins/cocoindex-code/plugin.json +81 -0
  76. package/plugins/cocoindex-code/scripts/__pycache__/query.cpython-310.pyc +0 -0
  77. package/plugins/cocoindex-code/scripts/__pycache__/query.cpython-311.pyc +0 -0
  78. package/plugins/cocoindex-code/scripts/post-install.js +61 -0
  79. package/plugins/cocoindex-code/scripts/post-uninstall.js +25 -0
  80. package/plugins/cocoindex-code/scripts/query.py +88 -0
  81. package/plugins/cocoindex-code/scripts/run-query.js +50 -0
  82. package/plugins/cocoindex-code/skills/quickstart/SKILL.md +73 -0
  83. package/plugins/copilot/README.md +24 -0
  84. package/plugins/copilot/plugin.json +80 -0
  85. package/plugins/copilot/skills/quickstart/SKILL.md +44 -0
  86. package/plugins/gemini/README.md +24 -0
  87. package/plugins/gemini/plugin.json +98 -0
  88. package/plugins/gemini/skills/quickstart/SKILL.md +44 -0
  89. package/plugins/gifcap/plugin.json +119 -0
  90. package/plugins/gifcap/scripts/setup-gifcap.js +44 -0
  91. package/plugins/gifcap/skills/quickstart/SKILL.md +34 -0
  92. package/plugins/gifcap/test-record-quiet.gif +0 -0
  93. package/plugins/gifcap/test-record.gif +0 -0
  94. package/plugins/goose/README.md +36 -0
  95. package/plugins/goose/plugin.json +183 -0
  96. package/plugins/goose/skills/quickstart/SKILL.md +44 -0
  97. package/plugins/json-server/README.md +58 -0
  98. package/plugins/json-server/plugin.json +113 -0
  99. package/plugins/json-server/skills/quickstart/SKILL.md +57 -0
  100. package/plugins/lightpanda/README.md +145 -0
  101. package/plugins/lightpanda/package-lock.json +1375 -0
  102. package/plugins/lightpanda/package.json +12 -0
  103. package/plugins/lightpanda/plugin.json +116 -0
  104. package/plugins/lightpanda/scripts/lightpanda-contacts.js +494 -0
  105. package/plugins/lightpanda/scripts/lightpanda-generic-extract.js +403 -0
  106. package/plugins/lightpanda/scripts/lightpanda-wrapper.js +480 -0
  107. package/plugins/lightpanda/scripts/setup-lightpanda.js +39 -0
  108. package/plugins/lightpanda/skills/contact-discovery.md +51 -0
  109. package/plugins/lightpanda/skills/generic-extraction.md +66 -0
  110. package/plugins/lightpanda/skills/quickstart/SKILL.md +103 -0
  111. package/plugins/lightpanda/skills/resilient-navigation.md +42 -0
  112. package/plugins/monty/README.md +2 -2
  113. package/plugins/nullclaw/README.md +3 -3
  114. package/plugins/offline-ai/README.md +23 -0
  115. package/plugins/offline-ai/plugin.json +82 -0
  116. package/plugins/offline-ai/skills/quickstart/SKILL.md +43 -0
  117. package/plugins/openhands/README.md +25 -0
  118. package/plugins/openhands/plugin.json +116 -0
  119. package/plugins/openhands/skills/quickstart/SKILL.md +26 -0
  120. package/plugins/plandex/README.md +25 -0
  121. package/plugins/plandex/plugin.json +130 -0
  122. package/plugins/plandex/skills/quickstart/SKILL.md +50 -0
  123. package/plugins/plugins.json +188 -0
  124. package/plugins/squirrelscan/Dockerfile +5 -0
  125. package/plugins/squirrelscan/README.md +47 -0
  126. package/plugins/squirrelscan/plugin.json +493 -0
  127. package/plugins/squirrelscan/scripts/post-install.js +33 -0
  128. package/plugins/squirrelscan/scripts/post-uninstall.js +25 -0
  129. package/plugins/squirrelscan/scripts/run-squirrel.js +73 -0
  130. package/plugins/squirrelscan/skills/audit-workflow/SKILL.md +33 -0
  131. package/plugins/squirrelscan/skills/publish-report/SKILL.md +33 -0
  132. package/plugins/squirrelscan/skills/quickstart/SKILL.md +41 -0
  133. package/plugins/uipath/README.md +27 -0
  134. package/plugins/uipath/plugin.json +86 -0
  135. package/plugins/uipath/skills/quickstart/SKILL.md +47 -0
  136. package/plugins/uipathcli/README.md +28 -0
  137. package/plugins/uipathcli/plugin.json +120 -0
  138. package/plugins/uipathcli/scripts/run-uipath-cli.js +49 -0
  139. package/plugins/uipathcli/skills/quickstart/SKILL.md +22 -0
  140. package/plugins/xurl/README.md +4 -4
  141. package/server/app.js +5 -2
  142. package/server/public/app.js +3 -0
  143. package/server/routes/commands.js +95 -12
  144. package/server/routes/plugins.js +262 -0
  145. package/server/services/pluginsService.js +303 -0
  146. package/server/views/command-edit.ejs +196 -14
  147. package/server/views/partials/head.ejs +1 -0
  148. package/server/views/plugins.ejs +264 -0
  149. package/tests/test-plugins-registry.js +30 -0
  150. package/.beads/.br_history/issues.20260308_200823_636718328.jsonl +0 -20
  151. package/.beads/.br_history/issues.20260308_200823_636718328.jsonl.meta.json +0 -1
  152. package/.beads/.br_history/issues.20260308_200827_033159453.jsonl +0 -21
  153. package/.beads/.br_history/issues.20260308_200827_033159453.jsonl.meta.json +0 -1
  154. package/.beads/.br_history/issues.20260308_200829_595900053.jsonl +0 -22
  155. package/.beads/.br_history/issues.20260308_200829_595900053.jsonl.meta.json +0 -1
  156. package/.beads/.br_history/issues.20260308_200834_079930100.jsonl +0 -23
  157. package/.beads/.br_history/issues.20260308_200834_079930100.jsonl.meta.json +0 -1
  158. package/.beads/.br_history/issues.20260308_200858_370924996.jsonl +0 -24
  159. package/.beads/.br_history/issues.20260308_200858_370924996.jsonl.meta.json +0 -1
  160. package/.beads/.br_history/issues.20260308_201031_019730855.jsonl +0 -24
  161. package/.beads/.br_history/issues.20260308_201031_019730855.jsonl.meta.json +0 -1
  162. package/.beads/.br_history/issues.20260308_201031_578974884.jsonl +0 -24
  163. package/.beads/.br_history/issues.20260308_201031_578974884.jsonl.meta.json +0 -1
  164. package/.beads/.br_history/issues.20260308_201054_780345548.jsonl +0 -24
  165. package/.beads/.br_history/issues.20260308_201054_780345548.jsonl.meta.json +0 -1
  166. package/.beads/.br_history/issues.20260308_201054_896980019.jsonl +0 -24
  167. package/.beads/.br_history/issues.20260308_201054_896980019.jsonl.meta.json +0 -1
  168. package/.beads/.br_history/issues.20260308_201128_599819688.jsonl +0 -24
  169. package/.beads/.br_history/issues.20260308_201128_599819688.jsonl.meta.json +0 -1
  170. package/.beads/.br_history/issues.20260308_201128_710221699.jsonl +0 -24
  171. package/.beads/.br_history/issues.20260308_201128_710221699.jsonl.meta.json +0 -1
  172. package/.beads/.br_history/issues.20260308_201204_745649213.jsonl +0 -24
  173. package/.beads/.br_history/issues.20260308_201204_745649213.jsonl.meta.json +0 -1
  174. package/.beads/.br_history/issues.20260308_201338_908436144.jsonl +0 -24
  175. package/.beads/.br_history/issues.20260308_201338_908436144.jsonl.meta.json +0 -1
  176. package/.beads/.br_history/issues.20260308_201344_734860714.jsonl +0 -25
  177. package/.beads/.br_history/issues.20260308_201344_734860714.jsonl.meta.json +0 -1
  178. package/.beads/.br_history/issues.20260308_201630_819282295.jsonl +0 -25
  179. package/.beads/.br_history/issues.20260308_201630_819282295.jsonl.meta.json +0 -1
  180. package/.beads/.br_history/issues.20260308_203538_054279699.jsonl +0 -25
  181. package/.beads/.br_history/issues.20260308_203538_054279699.jsonl.meta.json +0 -1
  182. package/.beads/.br_history/issues.20260308_203547_597113070.jsonl +0 -26
  183. package/.beads/.br_history/issues.20260308_203547_597113070.jsonl.meta.json +0 -1
  184. package/.beads/.br_history/issues.20260308_203547_775139216.jsonl +0 -27
  185. package/.beads/.br_history/issues.20260308_203547_775139216.jsonl.meta.json +0 -1
  186. package/.beads/.br_history/issues.20260308_203547_950724773.jsonl +0 -28
  187. package/.beads/.br_history/issues.20260308_203547_950724773.jsonl.meta.json +0 -1
  188. package/.beads/.br_history/issues.20260308_203548_107684523.jsonl +0 -29
  189. package/.beads/.br_history/issues.20260308_203548_107684523.jsonl.meta.json +0 -1
  190. package/.beads/.br_history/issues.20260308_203548_310389993.jsonl +0 -30
  191. package/.beads/.br_history/issues.20260308_203548_310389993.jsonl.meta.json +0 -1
  192. package/.beads/.br_history/issues.20260308_203825_953337320.jsonl +0 -31
  193. package/.beads/.br_history/issues.20260308_203825_953337320.jsonl.meta.json +0 -1
  194. package/.beads/.br_history/issues.20260308_204056_071377736.jsonl +0 -32
  195. package/.beads/.br_history/issues.20260308_204056_071377736.jsonl.meta.json +0 -1
  196. package/.beads/.br_history/issues.20260308_205141_517616844.jsonl +0 -32
  197. package/.beads/.br_history/issues.20260308_205141_517616844.jsonl.meta.json +0 -1
  198. package/.beads/.br_history/issues.20260308_205141_648994024.jsonl +0 -32
  199. package/.beads/.br_history/issues.20260308_205141_648994024.jsonl.meta.json +0 -1
  200. package/.beads/.br_history/issues.20260308_205141_867598036.jsonl +0 -32
  201. package/.beads/.br_history/issues.20260308_205141_867598036.jsonl.meta.json +0 -1
  202. package/.beads/.br_history/issues.20260308_205142_094157355.jsonl +0 -32
  203. package/.beads/.br_history/issues.20260308_205142_094157355.jsonl.meta.json +0 -1
  204. package/.beads/.br_history/issues.20260308_205142_327315677.jsonl +0 -32
  205. package/.beads/.br_history/issues.20260308_205142_327315677.jsonl.meta.json +0 -1
  206. package/.beads/.br_history/issues.20260308_205142_545563822.jsonl +0 -32
  207. package/.beads/.br_history/issues.20260308_205142_545563822.jsonl.meta.json +0 -1
  208. package/.beads/.br_history/issues.20260308_205213_061989333.jsonl +0 -32
  209. package/.beads/.br_history/issues.20260308_205213_061989333.jsonl.meta.json +0 -1
  210. package/.beads/.br_history/issues.20260308_205213_181103364.jsonl +0 -32
  211. package/.beads/.br_history/issues.20260308_205213_181103364.jsonl.meta.json +0 -1
  212. package/.beads/.br_history/issues.20260308_205213_408872234.jsonl +0 -32
  213. package/.beads/.br_history/issues.20260308_205213_408872234.jsonl.meta.json +0 -1
  214. package/.beads/.br_history/issues.20260308_205213_616681652.jsonl +0 -32
  215. package/.beads/.br_history/issues.20260308_205213_616681652.jsonl.meta.json +0 -1
  216. package/.beads/.br_history/issues.20260308_205213_821507069.jsonl +0 -32
  217. package/.beads/.br_history/issues.20260308_205213_821507069.jsonl.meta.json +0 -1
  218. package/.beads/.br_history/issues.20260308_205214_026661112.jsonl +0 -32
  219. package/.beads/.br_history/issues.20260308_205214_026661112.jsonl.meta.json +0 -1
  220. package/.beads/.br_history/issues.20260308_205454_955250554.jsonl +0 -32
  221. package/.beads/.br_history/issues.20260308_205454_955250554.jsonl.meta.json +0 -1
  222. package/.beads/.br_history/issues.20260308_205556_337800392.jsonl +0 -33
  223. package/.beads/.br_history/issues.20260308_205556_337800392.jsonl.meta.json +0 -1
  224. package/.beads/.br_history/issues.20260308_205824_274686694.jsonl +0 -33
  225. package/.beads/.br_history/issues.20260308_205824_274686694.jsonl.meta.json +0 -1
  226. package/.beads/.br_history/issues.20260308_210240_583768328.jsonl +0 -34
  227. package/.beads/.br_history/issues.20260308_210240_583768328.jsonl.meta.json +0 -1
  228. package/.beads/.br_history/issues.20260308_212223_641541494.jsonl +0 -34
  229. package/.beads/.br_history/issues.20260308_212223_641541494.jsonl.meta.json +0 -1
  230. package/.beads/.br_history/issues.20260308_212227_735550996.jsonl +0 -35
  231. package/.beads/.br_history/issues.20260308_212227_735550996.jsonl.meta.json +0 -1
  232. package/.beads/.br_history/issues.20260308_212232_547298548.jsonl +0 -36
  233. package/.beads/.br_history/issues.20260308_212232_547298548.jsonl.meta.json +0 -1
  234. package/.beads/.br_history/issues.20260308_212528_843628125.jsonl +0 -37
  235. package/.beads/.br_history/issues.20260308_212528_843628125.jsonl.meta.json +0 -1
  236. package/.beads/.br_history/issues.20260308_212529_094530502.jsonl +0 -38
  237. package/.beads/.br_history/issues.20260308_212529_094530502.jsonl.meta.json +0 -1
  238. package/.beads/.br_history/issues.20260308_212529_331000853.jsonl +0 -39
  239. package/.beads/.br_history/issues.20260308_212529_331000853.jsonl.meta.json +0 -1
  240. package/.beads/.br_history/issues.20260308_212529_587925652.jsonl +0 -40
  241. package/.beads/.br_history/issues.20260308_212529_587925652.jsonl.meta.json +0 -1
  242. package/.beads/.br_history/issues.20260308_212804_927764103.jsonl +0 -41
  243. package/.beads/.br_history/issues.20260308_212804_927764103.jsonl.meta.json +0 -1
  244. package/.beads/.br_history/issues.20260308_212805_153673453.jsonl +0 -42
  245. package/.beads/.br_history/issues.20260308_212805_153673453.jsonl.meta.json +0 -1
  246. package/.beads/.br_history/issues.20260308_212805_415982363.jsonl +0 -43
  247. package/.beads/.br_history/issues.20260308_212805_415982363.jsonl.meta.json +0 -1
  248. package/.beads/.br_history/issues.20260308_212805_657497741.jsonl +0 -44
  249. package/.beads/.br_history/issues.20260308_212805_657497741.jsonl.meta.json +0 -1
  250. package/.beads/.br_history/issues.20260308_212805_952838724.jsonl +0 -45
  251. package/.beads/.br_history/issues.20260308_212805_952838724.jsonl.meta.json +0 -1
  252. package/.beads/.br_history/issues.20260308_212806_325433779.jsonl +0 -46
  253. package/.beads/.br_history/issues.20260308_212806_325433779.jsonl.meta.json +0 -1
  254. package/.beads/.br_history/issues.20260308_212806_584685598.jsonl +0 -47
  255. package/.beads/.br_history/issues.20260308_212806_584685598.jsonl.meta.json +0 -1
  256. package/.beads/.br_history/issues.20260308_212806_827817208.jsonl +0 -48
  257. package/.beads/.br_history/issues.20260308_212806_827817208.jsonl.meta.json +0 -1
  258. package/.beads/.br_history/issues.20260308_212807_111320451.jsonl +0 -49
  259. package/.beads/.br_history/issues.20260308_212807_111320451.jsonl.meta.json +0 -1
  260. package/.beads/.br_history/issues.20260308_212807_409545536.jsonl +0 -50
  261. package/.beads/.br_history/issues.20260308_212807_409545536.jsonl.meta.json +0 -1
  262. package/.beads/.br_history/issues.20260308_212807_625063294.jsonl +0 -51
  263. package/.beads/.br_history/issues.20260308_212807_625063294.jsonl.meta.json +0 -1
  264. package/.beads/.br_history/issues.20260308_212807_843906551.jsonl +0 -52
  265. package/.beads/.br_history/issues.20260308_212807_843906551.jsonl.meta.json +0 -1
  266. package/.beads/.br_history/issues.20260308_212808_100304073.jsonl +0 -53
  267. package/.beads/.br_history/issues.20260308_212808_100304073.jsonl.meta.json +0 -1
  268. package/.beads/.br_history/issues.20260308_212808_324723976.jsonl +0 -54
  269. package/.beads/.br_history/issues.20260308_212808_324723976.jsonl.meta.json +0 -1
  270. package/.beads/.br_history/issues.20260308_212808_557513104.jsonl +0 -55
  271. package/.beads/.br_history/issues.20260308_212808_557513104.jsonl.meta.json +0 -1
  272. package/.beads/.br_history/issues.20260308_212808_788048322.jsonl +0 -56
  273. package/.beads/.br_history/issues.20260308_212808_788048322.jsonl.meta.json +0 -1
  274. package/.beads/.br_history/issues.20260308_213702_613249728.jsonl +0 -57
  275. package/.beads/.br_history/issues.20260308_213702_613249728.jsonl.meta.json +0 -1
  276. package/.beads/.br_history/issues.20260308_213715_115792063.jsonl +0 -57
  277. package/.beads/.br_history/issues.20260308_213715_115792063.jsonl.meta.json +0 -1
  278. package/.beads/.br_history/issues.20260308_213715_462220666.jsonl +0 -57
  279. package/.beads/.br_history/issues.20260308_213715_462220666.jsonl.meta.json +0 -1
  280. package/.beads/.br_history/issues.20260308_213727_191258923.jsonl +0 -57
  281. package/.beads/.br_history/issues.20260308_213727_191258923.jsonl.meta.json +0 -1
  282. package/.beads/.br_history/issues.20260308_213727_684383652.jsonl +0 -57
  283. package/.beads/.br_history/issues.20260308_213727_684383652.jsonl.meta.json +0 -1
  284. package/.beads/.br_history/issues.20260308_213735_751882991.jsonl +0 -57
  285. package/.beads/.br_history/issues.20260308_213735_751882991.jsonl.meta.json +0 -1
  286. package/.beads/.br_history/issues.20260308_222052_279844960.jsonl +0 -57
  287. package/.beads/.br_history/issues.20260308_222052_279844960.jsonl.meta.json +0 -1
  288. package/.beads/.br_history/issues.20260308_222056_873282114.jsonl +0 -57
  289. package/.beads/.br_history/issues.20260308_222056_873282114.jsonl.meta.json +0 -1
  290. package/.beads/.br_history/issues.20260308_222103_402410761.jsonl +0 -57
  291. package/.beads/.br_history/issues.20260308_222103_402410761.jsonl.meta.json +0 -1
  292. package/.beads/.br_history/issues.20260308_235202_180577215.jsonl +0 -57
  293. package/.beads/.br_history/issues.20260308_235202_180577215.jsonl.meta.json +0 -1
  294. package/.beads/.br_history/issues.20260308_235202_387414163.jsonl +0 -57
  295. package/.beads/.br_history/issues.20260308_235202_387414163.jsonl.meta.json +0 -1
  296. package/.beads/.br_history/issues.20260308_235202_564422794.jsonl +0 -57
  297. package/.beads/.br_history/issues.20260308_235202_564422794.jsonl.meta.json +0 -1
  298. package/.beads/.br_history/issues.20260308_235202_742600597.jsonl +0 -57
  299. package/.beads/.br_history/issues.20260308_235202_742600597.jsonl.meta.json +0 -1
  300. package/.beads/.br_history/issues.20260308_235208_133360069.jsonl +0 -57
  301. package/.beads/.br_history/issues.20260308_235208_133360069.jsonl.meta.json +0 -1
  302. package/.beads/.br_history/issues.20260308_235505_473406307.jsonl +0 -57
  303. package/.beads/.br_history/issues.20260308_235505_473406307.jsonl.meta.json +0 -1
  304. package/.beads/.br_history/issues.20260308_235505_662360489.jsonl +0 -57
  305. package/.beads/.br_history/issues.20260308_235505_662360489.jsonl.meta.json +0 -1
  306. package/.beads/.br_history/issues.20260308_235505_843935624.jsonl +0 -57
  307. package/.beads/.br_history/issues.20260308_235505_843935624.jsonl.meta.json +0 -1
  308. package/.beads/.br_history/issues.20260308_235506_044530221.jsonl +0 -57
  309. package/.beads/.br_history/issues.20260308_235506_044530221.jsonl.meta.json +0 -1
  310. package/.beads/.br_history/issues.20260309_002618_115728731.jsonl +0 -57
  311. package/.beads/.br_history/issues.20260309_002618_115728731.jsonl.meta.json +0 -1
  312. package/.beads/.br_history/issues.20260309_003748_878174586.jsonl +0 -57
  313. package/.beads/.br_history/issues.20260309_003748_878174586.jsonl.meta.json +0 -1
  314. package/.beads/.br_history/issues.20260309_004057_868755623.jsonl +0 -57
  315. package/.beads/.br_history/issues.20260309_004057_868755623.jsonl.meta.json +0 -1
  316. package/.beads/.br_history/issues.20260309_004058_512842163.jsonl +0 -57
  317. package/.beads/.br_history/issues.20260309_004058_512842163.jsonl.meta.json +0 -1
  318. package/.beads/.br_history/issues.20260309_004058_994445226.jsonl +0 -57
  319. package/.beads/.br_history/issues.20260309_004058_994445226.jsonl.meta.json +0 -1
  320. package/.beads/.br_history/issues.20260309_004059_475988596.jsonl +0 -57
  321. package/.beads/.br_history/issues.20260309_004059_475988596.jsonl.meta.json +0 -1
  322. package/.beads/.br_history/issues.20260309_161902_566857851.jsonl +0 -57
  323. package/.beads/.br_history/issues.20260309_161902_566857851.jsonl.meta.json +0 -1
  324. package/.beads/.br_history/issues.20260309_170512_277017739.jsonl +0 -57
  325. package/.beads/.br_history/issues.20260309_170512_277017739.jsonl.meta.json +0 -1
  326. package/.beads/.br_history/issues.20260309_170512_477876921.jsonl +0 -57
  327. package/.beads/.br_history/issues.20260309_170512_477876921.jsonl.meta.json +0 -1
  328. package/.beads/.br_history/issues.20260309_170512_664382701.jsonl +0 -57
  329. package/.beads/.br_history/issues.20260309_170512_664382701.jsonl.meta.json +0 -1
  330. package/.beads/.br_history/issues.20260309_170512_859400333.jsonl +0 -57
  331. package/.beads/.br_history/issues.20260309_170512_859400333.jsonl.meta.json +0 -1
  332. package/.beads/.br_history/issues.20260309_212326_082771164.jsonl +0 -57
  333. package/.beads/.br_history/issues.20260309_212326_082771164.jsonl.meta.json +0 -1
  334. package/.beads/.br_history/issues.20260309_212326_245619716.jsonl +0 -58
  335. package/.beads/.br_history/issues.20260309_212326_245619716.jsonl.meta.json +0 -1
  336. package/.beads/.br_history/issues.20260309_212326_403198317.jsonl +0 -59
  337. package/.beads/.br_history/issues.20260309_212326_403198317.jsonl.meta.json +0 -1
  338. package/.beads/.br_history/issues.20260309_212332_539197678.jsonl +0 -60
  339. package/.beads/.br_history/issues.20260309_212332_539197678.jsonl.meta.json +0 -1
  340. package/.beads/.br_history/issues.20260309_212332_731373599.jsonl +0 -60
  341. package/.beads/.br_history/issues.20260309_212332_731373599.jsonl.meta.json +0 -1
  342. package/.beads/.br_history/issues.20260309_212332_928710953.jsonl +0 -60
  343. package/.beads/.br_history/issues.20260309_212332_928710953.jsonl.meta.json +0 -1
  344. package/.beads/.br_history/issues.20260309_213021_341505240.jsonl +0 -60
  345. package/.beads/.br_history/issues.20260309_213021_341505240.jsonl.meta.json +0 -1
  346. package/.beads/.br_history/issues.20260309_213022_023136934.jsonl +0 -60
  347. package/.beads/.br_history/issues.20260309_213022_023136934.jsonl.meta.json +0 -1
  348. package/.beads/.br_history/issues.20260309_213022_400050719.jsonl +0 -60
  349. package/.beads/.br_history/issues.20260309_213022_400050719.jsonl.meta.json +0 -1
  350. package/.beads/config.yaml +0 -4
  351. package/.beads/issues.jsonl +0 -60
  352. package/.beads/metadata.json +0 -4
  353. package/docs/mcp-cheatsheet.md +0 -324
  354. package/docs/visual-overview.md +0 -21
  355. package/ref-monty/.cargo/config.toml +0 -3
  356. package/ref-monty/.claude/settings.json +0 -60
  357. package/ref-monty/.claude/skills/fastmod/SKILL.md +0 -22
  358. package/ref-monty/.claude/skills/python-playground/SKILL.md +0 -47
  359. package/ref-monty/.codecov.yml +0 -12
  360. package/ref-monty/.github/actions/build-pgo-wheel/action.yml +0 -72
  361. package/ref-monty/.github/workflows/ci.yml +0 -776
  362. package/ref-monty/.github/workflows/codspeed.yml +0 -45
  363. package/ref-monty/.github/workflows/init-npm-packages.yml +0 -82
  364. package/ref-monty/.pre-commit-config.yaml +0 -47
  365. package/ref-monty/.python-version +0 -1
  366. package/ref-monty/.rustfmt.toml +0 -4
  367. package/ref-monty/.zed/settings.json +0 -11
  368. package/ref-monty/CLAUDE.md +0 -535
  369. package/ref-monty/Cargo.lock +0 -3798
  370. package/ref-monty/Cargo.toml +0 -87
  371. package/ref-monty/LICENSE +0 -21
  372. package/ref-monty/Makefile +0 -216
  373. package/ref-monty/README.md +0 -430
  374. package/ref-monty/RELEASING.md +0 -47
  375. package/ref-monty/crates/fuzz/Cargo.toml +0 -30
  376. package/ref-monty/crates/fuzz/fuzz_targets/string_input_panic.rs +0 -37
  377. package/ref-monty/crates/fuzz/fuzz_targets/tokens_input_panic.rs +0 -552
  378. package/ref-monty/crates/monty/Cargo.toml +0 -68
  379. package/ref-monty/crates/monty/benches/main.rs +0 -247
  380. package/ref-monty/crates/monty/build.rs +0 -10
  381. package/ref-monty/crates/monty/src/args.rs +0 -733
  382. package/ref-monty/crates/monty/src/asyncio.rs +0 -179
  383. package/ref-monty/crates/monty/src/builtins/abs.rs +0 -55
  384. package/ref-monty/crates/monty/src/builtins/all.rs +0 -30
  385. package/ref-monty/crates/monty/src/builtins/any.rs +0 -30
  386. package/ref-monty/crates/monty/src/builtins/bin.rs +0 -59
  387. package/ref-monty/crates/monty/src/builtins/chr.rs +0 -46
  388. package/ref-monty/crates/monty/src/builtins/divmod.rs +0 -164
  389. package/ref-monty/crates/monty/src/builtins/enumerate.rs +0 -52
  390. package/ref-monty/crates/monty/src/builtins/filter.rs +0 -67
  391. package/ref-monty/crates/monty/src/builtins/getattr.rs +0 -65
  392. package/ref-monty/crates/monty/src/builtins/hash.rs +0 -28
  393. package/ref-monty/crates/monty/src/builtins/hex.rs +0 -58
  394. package/ref-monty/crates/monty/src/builtins/id.rs +0 -24
  395. package/ref-monty/crates/monty/src/builtins/isinstance.rs +0 -68
  396. package/ref-monty/crates/monty/src/builtins/len.rs +0 -25
  397. package/ref-monty/crates/monty/src/builtins/map.rs +0 -98
  398. package/ref-monty/crates/monty/src/builtins/min_max.rs +0 -113
  399. package/ref-monty/crates/monty/src/builtins/mod.rs +0 -246
  400. package/ref-monty/crates/monty/src/builtins/next.rs +0 -21
  401. package/ref-monty/crates/monty/src/builtins/oct.rs +0 -59
  402. package/ref-monty/crates/monty/src/builtins/ord.rs +0 -67
  403. package/ref-monty/crates/monty/src/builtins/pow.rs +0 -365
  404. package/ref-monty/crates/monty/src/builtins/print.rs +0 -141
  405. package/ref-monty/crates/monty/src/builtins/repr.rs +0 -16
  406. package/ref-monty/crates/monty/src/builtins/reversed.rs +0 -28
  407. package/ref-monty/crates/monty/src/builtins/round.rs +0 -174
  408. package/ref-monty/crates/monty/src/builtins/sorted.rs +0 -151
  409. package/ref-monty/crates/monty/src/builtins/sum.rs +0 -66
  410. package/ref-monty/crates/monty/src/builtins/type_.rs +0 -16
  411. package/ref-monty/crates/monty/src/builtins/zip.rs +0 -77
  412. package/ref-monty/crates/monty/src/bytecode/builder.rs +0 -699
  413. package/ref-monty/crates/monty/src/bytecode/code.rs +0 -310
  414. package/ref-monty/crates/monty/src/bytecode/compiler.rs +0 -3206
  415. package/ref-monty/crates/monty/src/bytecode/mod.rs +0 -24
  416. package/ref-monty/crates/monty/src/bytecode/op.rs +0 -617
  417. package/ref-monty/crates/monty/src/bytecode/vm/async_exec.rs +0 -1058
  418. package/ref-monty/crates/monty/src/bytecode/vm/attr.rs +0 -63
  419. package/ref-monty/crates/monty/src/bytecode/vm/binary.rs +0 -487
  420. package/ref-monty/crates/monty/src/bytecode/vm/call.rs +0 -767
  421. package/ref-monty/crates/monty/src/bytecode/vm/collections.rs +0 -741
  422. package/ref-monty/crates/monty/src/bytecode/vm/compare.rs +0 -147
  423. package/ref-monty/crates/monty/src/bytecode/vm/exceptions.rs +0 -297
  424. package/ref-monty/crates/monty/src/bytecode/vm/format.rs +0 -132
  425. package/ref-monty/crates/monty/src/bytecode/vm/mod.rs +0 -1958
  426. package/ref-monty/crates/monty/src/bytecode/vm/scheduler.rs +0 -620
  427. package/ref-monty/crates/monty/src/exception_private.rs +0 -1513
  428. package/ref-monty/crates/monty/src/exception_public.rs +0 -346
  429. package/ref-monty/crates/monty/src/expressions.rs +0 -694
  430. package/ref-monty/crates/monty/src/fstring.rs +0 -854
  431. package/ref-monty/crates/monty/src/function.rs +0 -119
  432. package/ref-monty/crates/monty/src/heap.rs +0 -1073
  433. package/ref-monty/crates/monty/src/heap_data.rs +0 -985
  434. package/ref-monty/crates/monty/src/heap_traits.rs +0 -312
  435. package/ref-monty/crates/monty/src/intern.rs +0 -837
  436. package/ref-monty/crates/monty/src/io.rs +0 -106
  437. package/ref-monty/crates/monty/src/lib.rs +0 -52
  438. package/ref-monty/crates/monty/src/modules/asyncio.rs +0 -144
  439. package/ref-monty/crates/monty/src/modules/math.rs +0 -1453
  440. package/ref-monty/crates/monty/src/modules/mod.rs +0 -120
  441. package/ref-monty/crates/monty/src/modules/os.rs +0 -116
  442. package/ref-monty/crates/monty/src/modules/pathlib.rs +0 -33
  443. package/ref-monty/crates/monty/src/modules/re.rs +0 -606
  444. package/ref-monty/crates/monty/src/modules/sys.rs +0 -60
  445. package/ref-monty/crates/monty/src/modules/typing.rs +0 -70
  446. package/ref-monty/crates/monty/src/namespace.rs +0 -21
  447. package/ref-monty/crates/monty/src/object.rs +0 -1040
  448. package/ref-monty/crates/monty/src/os.rs +0 -215
  449. package/ref-monty/crates/monty/src/parse.rs +0 -1730
  450. package/ref-monty/crates/monty/src/prepare.rs +0 -3015
  451. package/ref-monty/crates/monty/src/repl.rs +0 -1109
  452. package/ref-monty/crates/monty/src/resource.rs +0 -559
  453. package/ref-monty/crates/monty/src/run.rs +0 -457
  454. package/ref-monty/crates/monty/src/run_progress.rs +0 -821
  455. package/ref-monty/crates/monty/src/signature.rs +0 -651
  456. package/ref-monty/crates/monty/src/sorting.rs +0 -100
  457. package/ref-monty/crates/monty/src/types/bytes.rs +0 -2356
  458. package/ref-monty/crates/monty/src/types/dataclass.rs +0 -345
  459. package/ref-monty/crates/monty/src/types/dict.rs +0 -879
  460. package/ref-monty/crates/monty/src/types/dict_view.rs +0 -619
  461. package/ref-monty/crates/monty/src/types/iter.rs +0 -799
  462. package/ref-monty/crates/monty/src/types/list.rs +0 -929
  463. package/ref-monty/crates/monty/src/types/long_int.rs +0 -211
  464. package/ref-monty/crates/monty/src/types/mod.rs +0 -48
  465. package/ref-monty/crates/monty/src/types/module.rs +0 -146
  466. package/ref-monty/crates/monty/src/types/namedtuple.rs +0 -261
  467. package/ref-monty/crates/monty/src/types/path.rs +0 -596
  468. package/ref-monty/crates/monty/src/types/property.rs +0 -35
  469. package/ref-monty/crates/monty/src/types/py_trait.rs +0 -322
  470. package/ref-monty/crates/monty/src/types/range.rs +0 -285
  471. package/ref-monty/crates/monty/src/types/re_match.rs +0 -522
  472. package/ref-monty/crates/monty/src/types/re_pattern.rs +0 -726
  473. package/ref-monty/crates/monty/src/types/set.rs +0 -1373
  474. package/ref-monty/crates/monty/src/types/slice.rs +0 -257
  475. package/ref-monty/crates/monty/src/types/str.rs +0 -2051
  476. package/ref-monty/crates/monty/src/types/tuple.rs +0 -376
  477. package/ref-monty/crates/monty/src/types/type.rs +0 -407
  478. package/ref-monty/crates/monty/src/value.rs +0 -2558
  479. package/ref-monty/crates/monty/test_cases/args__dict_get_no_args.py +0 -3
  480. package/ref-monty/crates/monty/test_cases/args__dict_get_too_many.py +0 -3
  481. package/ref-monty/crates/monty/test_cases/args__dict_items_with_args.py +0 -3
  482. package/ref-monty/crates/monty/test_cases/args__dict_keys_with_args.py +0 -3
  483. package/ref-monty/crates/monty/test_cases/args__dict_pop_no_args.py +0 -3
  484. package/ref-monty/crates/monty/test_cases/args__dict_pop_too_many.py +0 -3
  485. package/ref-monty/crates/monty/test_cases/args__dict_values_with_args.py +0 -3
  486. package/ref-monty/crates/monty/test_cases/args__id_too_many.py +0 -2
  487. package/ref-monty/crates/monty/test_cases/args__len_no_args.py +0 -2
  488. package/ref-monty/crates/monty/test_cases/args__len_too_many.py +0 -2
  489. package/ref-monty/crates/monty/test_cases/args__len_type_error_int.py +0 -9
  490. package/ref-monty/crates/monty/test_cases/args__len_type_error_none.py +0 -9
  491. package/ref-monty/crates/monty/test_cases/args__list_append_no_args.py +0 -3
  492. package/ref-monty/crates/monty/test_cases/args__list_append_too_many.py +0 -3
  493. package/ref-monty/crates/monty/test_cases/args__list_insert_too_few.py +0 -3
  494. package/ref-monty/crates/monty/test_cases/args__list_insert_too_many.py +0 -3
  495. package/ref-monty/crates/monty/test_cases/args__repr_no_args.py +0 -2
  496. package/ref-monty/crates/monty/test_cases/arith__div_zero_float.py +0 -2
  497. package/ref-monty/crates/monty/test_cases/arith__div_zero_int.py +0 -2
  498. package/ref-monty/crates/monty/test_cases/arith__floordiv_zero_float.py +0 -2
  499. package/ref-monty/crates/monty/test_cases/arith__floordiv_zero_int.py +0 -2
  500. package/ref-monty/crates/monty/test_cases/arith__pow_zero_neg.py +0 -2
  501. package/ref-monty/crates/monty/test_cases/arith__pow_zero_neg_builtin.py +0 -9
  502. package/ref-monty/crates/monty/test_cases/assert__expr_fail.py +0 -2
  503. package/ref-monty/crates/monty/test_cases/assert__fail.py +0 -2
  504. package/ref-monty/crates/monty/test_cases/assert__fail_msg.py +0 -2
  505. package/ref-monty/crates/monty/test_cases/assert__fn_fail.py +0 -3
  506. package/ref-monty/crates/monty/test_cases/assert__ops.py +0 -11
  507. package/ref-monty/crates/monty/test_cases/async__asyncio_run.py +0 -47
  508. package/ref-monty/crates/monty/test_cases/async__basic.py +0 -10
  509. package/ref-monty/crates/monty/test_cases/async__closure.py +0 -14
  510. package/ref-monty/crates/monty/test_cases/async__double_await_coroutine.py +0 -16
  511. package/ref-monty/crates/monty/test_cases/async__exception.py +0 -10
  512. package/ref-monty/crates/monty/test_cases/async__ext_call.py +0 -73
  513. package/ref-monty/crates/monty/test_cases/async__gather_all.py +0 -85
  514. package/ref-monty/crates/monty/test_cases/async__nested_await.py +0 -15
  515. package/ref-monty/crates/monty/test_cases/async__nested_gather_ext.py +0 -37
  516. package/ref-monty/crates/monty/test_cases/async__not_awaitable.py +0 -10
  517. package/ref-monty/crates/monty/test_cases/async__not_imported.py +0 -14
  518. package/ref-monty/crates/monty/test_cases/async__recursion_depth_isolation.py +0 -27
  519. package/ref-monty/crates/monty/test_cases/async__return_types.py +0 -31
  520. package/ref-monty/crates/monty/test_cases/async__sequential.py +0 -16
  521. package/ref-monty/crates/monty/test_cases/async__traceback.py +0 -19
  522. package/ref-monty/crates/monty/test_cases/async__with_args.py +0 -14
  523. package/ref-monty/crates/monty/test_cases/attr__get_int_error.py +0 -9
  524. package/ref-monty/crates/monty/test_cases/attr__get_list_error.py +0 -9
  525. package/ref-monty/crates/monty/test_cases/attr__set_frozen_nonfield.py +0 -12
  526. package/ref-monty/crates/monty/test_cases/attr__set_int_error.py +0 -10
  527. package/ref-monty/crates/monty/test_cases/attr__set_list_error.py +0 -10
  528. package/ref-monty/crates/monty/test_cases/bench__kitchen_sink.py +0 -68
  529. package/ref-monty/crates/monty/test_cases/bool__ops.py +0 -20
  530. package/ref-monty/crates/monty/test_cases/builtin__add_type_error.py +0 -2
  531. package/ref-monty/crates/monty/test_cases/builtin__filter.py +0 -62
  532. package/ref-monty/crates/monty/test_cases/builtin__filter_not_iterable.py +0 -11
  533. package/ref-monty/crates/monty/test_cases/builtin__getattr.py +0 -84
  534. package/ref-monty/crates/monty/test_cases/builtin__iter_funcs.py +0 -42
  535. package/ref-monty/crates/monty/test_cases/builtin__iter_next.py +0 -66
  536. package/ref-monty/crates/monty/test_cases/builtin__map.py +0 -74
  537. package/ref-monty/crates/monty/test_cases/builtin__map_not_iterable.py +0 -11
  538. package/ref-monty/crates/monty/test_cases/builtin__math_funcs.py +0 -154
  539. package/ref-monty/crates/monty/test_cases/builtin__more_iter_funcs.py +0 -148
  540. package/ref-monty/crates/monty/test_cases/builtin__next_stop_iteration.py +0 -10
  541. package/ref-monty/crates/monty/test_cases/builtin__print_invalid_kwarg.py +0 -9
  542. package/ref-monty/crates/monty/test_cases/builtin__print_kwargs.py +0 -12
  543. package/ref-monty/crates/monty/test_cases/builtin__repr.py +0 -3
  544. package/ref-monty/crates/monty/test_cases/builtin__string_funcs.py +0 -73
  545. package/ref-monty/crates/monty/test_cases/bytes__decode_invalid_utf8.py +0 -18
  546. package/ref-monty/crates/monty/test_cases/bytes__endswith_str_error.py +0 -10
  547. package/ref-monty/crates/monty/test_cases/bytes__getitem_index_error.py +0 -10
  548. package/ref-monty/crates/monty/test_cases/bytes__index_start_gt_end.py +0 -10
  549. package/ref-monty/crates/monty/test_cases/bytes__methods.py +0 -394
  550. package/ref-monty/crates/monty/test_cases/bytes__negative_count.py +0 -9
  551. package/ref-monty/crates/monty/test_cases/bytes__ops.py +0 -90
  552. package/ref-monty/crates/monty/test_cases/bytes__startswith_str_error.py +0 -10
  553. package/ref-monty/crates/monty/test_cases/call_object.py +0 -3
  554. package/ref-monty/crates/monty/test_cases/chain_comparison__all.py +0 -79
  555. package/ref-monty/crates/monty/test_cases/closure__param_shadows_outer.py +0 -81
  556. package/ref-monty/crates/monty/test_cases/closure__pep448.py +0 -203
  557. package/ref-monty/crates/monty/test_cases/closure__undefined_nonlocal.py +0 -13
  558. package/ref-monty/crates/monty/test_cases/compare__mixed_types.py +0 -120
  559. package/ref-monty/crates/monty/test_cases/comprehension__all.py +0 -208
  560. package/ref-monty/crates/monty/test_cases/comprehension__scope.py +0 -7
  561. package/ref-monty/crates/monty/test_cases/comprehension__unbound_local.py +0 -14
  562. package/ref-monty/crates/monty/test_cases/dataclass__basic.py +0 -238
  563. package/ref-monty/crates/monty/test_cases/dataclass__call_field_error.py +0 -12
  564. package/ref-monty/crates/monty/test_cases/dataclass__frozen_set_error.py +0 -12
  565. package/ref-monty/crates/monty/test_cases/dataclass__get_missing_attr_error.py +0 -11
  566. package/ref-monty/crates/monty/test_cases/dict__get_unhashable_key.py +0 -3
  567. package/ref-monty/crates/monty/test_cases/dict__literal_unhashable_key.py +0 -2
  568. package/ref-monty/crates/monty/test_cases/dict__method_pop_missing_error.py +0 -3
  569. package/ref-monty/crates/monty/test_cases/dict__methods.py +0 -151
  570. package/ref-monty/crates/monty/test_cases/dict__ops.py +0 -133
  571. package/ref-monty/crates/monty/test_cases/dict__pop_unhashable_key.py +0 -4
  572. package/ref-monty/crates/monty/test_cases/dict__popitem_empty.py +0 -9
  573. package/ref-monty/crates/monty/test_cases/dict__subscript_missing_key.py +0 -3
  574. package/ref-monty/crates/monty/test_cases/dict__unhashable_dict_key.py +0 -2
  575. package/ref-monty/crates/monty/test_cases/dict__unhashable_list_key.py +0 -2
  576. package/ref-monty/crates/monty/test_cases/dict__unpack_type_error.py +0 -2
  577. package/ref-monty/crates/monty/test_cases/dict__views.py +0 -165
  578. package/ref-monty/crates/monty/test_cases/edge__all.py +0 -26
  579. package/ref-monty/crates/monty/test_cases/edge__float_int_mod.py +0 -2
  580. package/ref-monty/crates/monty/test_cases/edge__int_float_mod.py +0 -2
  581. package/ref-monty/crates/monty/test_cases/exc__args.py +0 -16
  582. package/ref-monty/crates/monty/test_cases/exc__str.py +0 -15
  583. package/ref-monty/crates/monty/test_cases/execute_ok__all.py +0 -54
  584. package/ref-monty/crates/monty/test_cases/execute_raise__error_instance_str.py +0 -2
  585. package/ref-monty/crates/monty/test_cases/execute_raise__error_no_args.py +0 -2
  586. package/ref-monty/crates/monty/test_cases/execute_raise__error_string_arg.py +0 -2
  587. package/ref-monty/crates/monty/test_cases/execute_raise__error_string_arg_quotes.py +0 -2
  588. package/ref-monty/crates/monty/test_cases/execute_raise__error_type.py +0 -2
  589. package/ref-monty/crates/monty/test_cases/execute_raise__raise_instance_via_var.py +0 -4
  590. package/ref-monty/crates/monty/test_cases/execute_raise__raise_list.py +0 -2
  591. package/ref-monty/crates/monty/test_cases/execute_raise__raise_number.py +0 -2
  592. package/ref-monty/crates/monty/test_cases/execute_raise__raise_type_call_via_var.py +0 -4
  593. package/ref-monty/crates/monty/test_cases/execute_raise__raise_type_direct.py +0 -3
  594. package/ref-monty/crates/monty/test_cases/execute_raise__raise_type_via_var.py +0 -4
  595. package/ref-monty/crates/monty/test_cases/ext_call__arg_side_effect_bug.py +0 -22
  596. package/ref-monty/crates/monty/test_cases/ext_call__augmented.py +0 -17
  597. package/ref-monty/crates/monty/test_cases/ext_call__augmented_refcount_bug.py +0 -7
  598. package/ref-monty/crates/monty/test_cases/ext_call__bare_raise_after_resume.py +0 -34
  599. package/ref-monty/crates/monty/test_cases/ext_call__basic.py +0 -99
  600. package/ref-monty/crates/monty/test_cases/ext_call__boolean.py +0 -37
  601. package/ref-monty/crates/monty/test_cases/ext_call__boolean_side_effect_hang.py +0 -17
  602. package/ref-monty/crates/monty/test_cases/ext_call__closure_bug.py +0 -16
  603. package/ref-monty/crates/monty/test_cases/ext_call__comparison.py +0 -26
  604. package/ref-monty/crates/monty/test_cases/ext_call__deep_call_stack.py +0 -18
  605. package/ref-monty/crates/monty/test_cases/ext_call__elif.py +0 -171
  606. package/ref-monty/crates/monty/test_cases/ext_call__exc.py +0 -4
  607. package/ref-monty/crates/monty/test_cases/ext_call__exc_deep_stack.py +0 -39
  608. package/ref-monty/crates/monty/test_cases/ext_call__exc_in_function.py +0 -17
  609. package/ref-monty/crates/monty/test_cases/ext_call__exc_nested_functions.py +0 -31
  610. package/ref-monty/crates/monty/test_cases/ext_call__ext_exc.py +0 -171
  611. package/ref-monty/crates/monty/test_cases/ext_call__for.py +0 -114
  612. package/ref-monty/crates/monty/test_cases/ext_call__fstring.py +0 -12
  613. package/ref-monty/crates/monty/test_cases/ext_call__if.py +0 -135
  614. package/ref-monty/crates/monty/test_cases/ext_call__if_condition.py +0 -37
  615. package/ref-monty/crates/monty/test_cases/ext_call__in_closure.py +0 -14
  616. package/ref-monty/crates/monty/test_cases/ext_call__in_function.py +0 -40
  617. package/ref-monty/crates/monty/test_cases/ext_call__in_function_simple.py +0 -7
  618. package/ref-monty/crates/monty/test_cases/ext_call__literals.py +0 -17
  619. package/ref-monty/crates/monty/test_cases/ext_call__multi_in_func.py +0 -32
  620. package/ref-monty/crates/monty/test_cases/ext_call__name_lookup.py +0 -69
  621. package/ref-monty/crates/monty/test_cases/ext_call__name_lookup_undefined.py +0 -4
  622. package/ref-monty/crates/monty/test_cases/ext_call__nested_calls.py +0 -14
  623. package/ref-monty/crates/monty/test_cases/ext_call__recursion_bug.py +0 -19
  624. package/ref-monty/crates/monty/test_cases/ext_call__return.py +0 -28
  625. package/ref-monty/crates/monty/test_cases/ext_call__side_effects.py +0 -25
  626. package/ref-monty/crates/monty/test_cases/ext_call__subscript.py +0 -7
  627. package/ref-monty/crates/monty/test_cases/ext_call__ternary.py +0 -28
  628. package/ref-monty/crates/monty/test_cases/ext_call__try.py +0 -280
  629. package/ref-monty/crates/monty/test_cases/ext_call__try_simple.py +0 -10
  630. package/ref-monty/crates/monty/test_cases/ext_call__unary.py +0 -13
  631. package/ref-monty/crates/monty/test_cases/frozenset__ops.py +0 -178
  632. package/ref-monty/crates/monty/test_cases/fstring__all.py +0 -236
  633. package/ref-monty/crates/monty/test_cases/fstring__error_eq_align_on_str.py +0 -3
  634. package/ref-monty/crates/monty/test_cases/fstring__error_float_f_on_str.py +0 -3
  635. package/ref-monty/crates/monty/test_cases/fstring__error_int_d_on_float.py +0 -3
  636. package/ref-monty/crates/monty/test_cases/fstring__error_int_d_on_str.py +0 -3
  637. package/ref-monty/crates/monty/test_cases/fstring__error_invalid_spec.py +0 -4
  638. package/ref-monty/crates/monty/test_cases/fstring__error_invalid_spec_dynamic.py +0 -4
  639. package/ref-monty/crates/monty/test_cases/fstring__error_invalid_spec_str.py +0 -4
  640. package/ref-monty/crates/monty/test_cases/fstring__error_str_s_on_int.py +0 -3
  641. package/ref-monty/crates/monty/test_cases/function__call_duplicate_kwargs.py +0 -6
  642. package/ref-monty/crates/monty/test_cases/function__call_unpack.py +0 -42
  643. package/ref-monty/crates/monty/test_cases/function__defaults.py +0 -117
  644. package/ref-monty/crates/monty/test_cases/function__err_duplicate_arg.py +0 -7
  645. package/ref-monty/crates/monty/test_cases/function__err_duplicate_first_arg.py +0 -7
  646. package/ref-monty/crates/monty/test_cases/function__err_duplicate_kwarg_cleanup.py +0 -9
  647. package/ref-monty/crates/monty/test_cases/function__err_kwonly_as_positional.py +0 -7
  648. package/ref-monty/crates/monty/test_cases/function__err_missing_all_posonly.py +0 -7
  649. package/ref-monty/crates/monty/test_cases/function__err_missing_heap_cleanup.py +0 -9
  650. package/ref-monty/crates/monty/test_cases/function__err_missing_kwonly.py +0 -7
  651. package/ref-monty/crates/monty/test_cases/function__err_missing_posonly_with_kwarg.py +0 -7
  652. package/ref-monty/crates/monty/test_cases/function__err_missing_with_posonly.py +0 -7
  653. package/ref-monty/crates/monty/test_cases/function__err_posonly_as_kwarg.py +0 -7
  654. package/ref-monty/crates/monty/test_cases/function__err_posonly_first_as_kwarg.py +0 -7
  655. package/ref-monty/crates/monty/test_cases/function__err_too_many_posonly.py +0 -7
  656. package/ref-monty/crates/monty/test_cases/function__err_too_many_with_kwonly.py +0 -7
  657. package/ref-monty/crates/monty/test_cases/function__err_unexpected_kwarg.py +0 -7
  658. package/ref-monty/crates/monty/test_cases/function__err_unexpected_kwarg_cleanup.py +0 -9
  659. package/ref-monty/crates/monty/test_cases/function__err_unexpected_kwarg_quote.py +0 -13
  660. package/ref-monty/crates/monty/test_cases/function__err_unexpected_kwarg_simple.py +0 -7
  661. package/ref-monty/crates/monty/test_cases/function__err_unpack_duplicate_arg.py +0 -6
  662. package/ref-monty/crates/monty/test_cases/function__err_unpack_duplicate_heap.py +0 -8
  663. package/ref-monty/crates/monty/test_cases/function__err_unpack_int.py +0 -6
  664. package/ref-monty/crates/monty/test_cases/function__err_unpack_nonstring_key.py +0 -6
  665. package/ref-monty/crates/monty/test_cases/function__err_unpack_not_mapping.py +0 -6
  666. package/ref-monty/crates/monty/test_cases/function__kwargs_unpacking.py +0 -173
  667. package/ref-monty/crates/monty/test_cases/function__ops.py +0 -294
  668. package/ref-monty/crates/monty/test_cases/function__return_none.py +0 -42
  669. package/ref-monty/crates/monty/test_cases/function__signatures.py +0 -47
  670. package/ref-monty/crates/monty/test_cases/function__too_few_args_all.py +0 -6
  671. package/ref-monty/crates/monty/test_cases/function__too_few_args_one.py +0 -6
  672. package/ref-monty/crates/monty/test_cases/function__too_few_args_two.py +0 -6
  673. package/ref-monty/crates/monty/test_cases/function__too_many_args_one.py +0 -6
  674. package/ref-monty/crates/monty/test_cases/function__too_many_args_two.py +0 -6
  675. package/ref-monty/crates/monty/test_cases/function__too_many_args_zero.py +0 -6
  676. package/ref-monty/crates/monty/test_cases/global__error_assigned_before.py +0 -7
  677. package/ref-monty/crates/monty/test_cases/global__ops.py +0 -163
  678. package/ref-monty/crates/monty/test_cases/hash__dict_unhashable.py +0 -2
  679. package/ref-monty/crates/monty/test_cases/hash__list_unhashable.py +0 -2
  680. package/ref-monty/crates/monty/test_cases/hash__ops.py +0 -153
  681. package/ref-monty/crates/monty/test_cases/id__bytes_literals_distinct.py +0 -3
  682. package/ref-monty/crates/monty/test_cases/id__int_copy_distinct.py +0 -5
  683. package/ref-monty/crates/monty/test_cases/id__is_number_is_number.py +0 -3
  684. package/ref-monty/crates/monty/test_cases/id__non_overlapping_lifetimes_distinct_types.py +0 -10
  685. package/ref-monty/crates/monty/test_cases/id__non_overlapping_lifetimes_same_types.py +0 -6
  686. package/ref-monty/crates/monty/test_cases/id__ops.py +0 -97
  687. package/ref-monty/crates/monty/test_cases/id__str_literals_same.py +0 -3
  688. package/ref-monty/crates/monty/test_cases/if__elif_else.py +0 -207
  689. package/ref-monty/crates/monty/test_cases/if__raise_elif.py +0 -11
  690. package/ref-monty/crates/monty/test_cases/if__raise_else.py +0 -13
  691. package/ref-monty/crates/monty/test_cases/if__raise_if.py +0 -9
  692. package/ref-monty/crates/monty/test_cases/if__raise_in_elif_condition.py +0 -18
  693. package/ref-monty/crates/monty/test_cases/if__raise_in_if_condition.py +0 -16
  694. package/ref-monty/crates/monty/test_cases/if_else_expr__all.py +0 -55
  695. package/ref-monty/crates/monty/test_cases/import__error_cannot_import.py +0 -9
  696. package/ref-monty/crates/monty/test_cases/import__error_module_not_found.py +0 -9
  697. package/ref-monty/crates/monty/test_cases/import__local_scope.py +0 -68
  698. package/ref-monty/crates/monty/test_cases/import__os.py +0 -25
  699. package/ref-monty/crates/monty/test_cases/import__relative_error.py +0 -9
  700. package/ref-monty/crates/monty/test_cases/import__relative_no_module_error.py +0 -9
  701. package/ref-monty/crates/monty/test_cases/import__runtime_error_when_executed.py +0 -14
  702. package/ref-monty/crates/monty/test_cases/import__star_error.py +0 -11
  703. package/ref-monty/crates/monty/test_cases/import__sys.py +0 -47
  704. package/ref-monty/crates/monty/test_cases/import__sys_monty.py +0 -28
  705. package/ref-monty/crates/monty/test_cases/import__type_checking_guard.py +0 -37
  706. package/ref-monty/crates/monty/test_cases/import__typing.py +0 -25
  707. package/ref-monty/crates/monty/test_cases/import__typing_type_ignore.py +0 -4
  708. package/ref-monty/crates/monty/test_cases/int__bigint.py +0 -467
  709. package/ref-monty/crates/monty/test_cases/int__bigint_errors.py +0 -260
  710. package/ref-monty/crates/monty/test_cases/int__ops.py +0 -219
  711. package/ref-monty/crates/monty/test_cases/int__overflow_division.py +0 -84
  712. package/ref-monty/crates/monty/test_cases/is_variant__all.py +0 -36
  713. package/ref-monty/crates/monty/test_cases/isinstance__arg2_list_error.py +0 -2
  714. package/ref-monty/crates/monty/test_cases/isinstance__arg2_type_error.py +0 -2
  715. package/ref-monty/crates/monty/test_cases/iter__dict_mutation.py +0 -4
  716. package/ref-monty/crates/monty/test_cases/iter__for.py +0 -243
  717. package/ref-monty/crates/monty/test_cases/iter__for_loop_unpacking.py +0 -66
  718. package/ref-monty/crates/monty/test_cases/iter__generator_expr.py +0 -20
  719. package/ref-monty/crates/monty/test_cases/iter__generator_expr_type.py +0 -7
  720. package/ref-monty/crates/monty/test_cases/iter__not_iterable.py +0 -3
  721. package/ref-monty/crates/monty/test_cases/lambda__all.py +0 -145
  722. package/ref-monty/crates/monty/test_cases/list__extend_not_iterable.py +0 -7
  723. package/ref-monty/crates/monty/test_cases/list__getitem_out_of_bounds.py +0 -3
  724. package/ref-monty/crates/monty/test_cases/list__index_not_found.py +0 -9
  725. package/ref-monty/crates/monty/test_cases/list__index_start_gt_end.py +0 -10
  726. package/ref-monty/crates/monty/test_cases/list__ops.py +0 -473
  727. package/ref-monty/crates/monty/test_cases/list__pop_empty.py +0 -9
  728. package/ref-monty/crates/monty/test_cases/list__pop_out_of_range.py +0 -9
  729. package/ref-monty/crates/monty/test_cases/list__pop_type_error.py +0 -9
  730. package/ref-monty/crates/monty/test_cases/list__remove_not_found.py +0 -9
  731. package/ref-monty/crates/monty/test_cases/list__setitem_dict_index.py +0 -13
  732. package/ref-monty/crates/monty/test_cases/list__setitem_huge_int_index.py +0 -13
  733. package/ref-monty/crates/monty/test_cases/list__setitem_index_error.py +0 -10
  734. package/ref-monty/crates/monty/test_cases/list__setitem_type_error.py +0 -10
  735. package/ref-monty/crates/monty/test_cases/list__unpack_type_error.py +0 -2
  736. package/ref-monty/crates/monty/test_cases/longint__index_error.py +0 -3
  737. package/ref-monty/crates/monty/test_cases/longint__repeat_error.py +0 -3
  738. package/ref-monty/crates/monty/test_cases/loop__break_continue.py +0 -113
  739. package/ref-monty/crates/monty/test_cases/loop__break_finally.py +0 -69
  740. package/ref-monty/crates/monty/test_cases/loop__break_in_function_error.py +0 -13
  741. package/ref-monty/crates/monty/test_cases/loop__break_in_if_error.py +0 -11
  742. package/ref-monty/crates/monty/test_cases/loop__break_nested_except_clears.py +0 -55
  743. package/ref-monty/crates/monty/test_cases/loop__break_outside_error.py +0 -9
  744. package/ref-monty/crates/monty/test_cases/loop__continue_finally.py +0 -81
  745. package/ref-monty/crates/monty/test_cases/loop__continue_in_function_error.py +0 -13
  746. package/ref-monty/crates/monty/test_cases/loop__continue_in_if_error.py +0 -11
  747. package/ref-monty/crates/monty/test_cases/loop__continue_nested_except_clears.py +0 -60
  748. package/ref-monty/crates/monty/test_cases/loop__continue_outside_error.py +0 -9
  749. package/ref-monty/crates/monty/test_cases/math__acos_domain_error.py +0 -11
  750. package/ref-monty/crates/monty/test_cases/math__acosh_domain_error.py +0 -11
  751. package/ref-monty/crates/monty/test_cases/math__asin_domain_error.py +0 -11
  752. package/ref-monty/crates/monty/test_cases/math__atanh_domain_error.py +0 -11
  753. package/ref-monty/crates/monty/test_cases/math__cos_inf_error.py +0 -11
  754. package/ref-monty/crates/monty/test_cases/math__cosh_overflow_error.py +0 -11
  755. package/ref-monty/crates/monty/test_cases/math__exp_overflow_error.py +0 -11
  756. package/ref-monty/crates/monty/test_cases/math__factorial_float_error.py +0 -11
  757. package/ref-monty/crates/monty/test_cases/math__factorial_negative_error.py +0 -11
  758. package/ref-monty/crates/monty/test_cases/math__floor_inf_error.py +0 -11
  759. package/ref-monty/crates/monty/test_cases/math__floor_nan_error.py +0 -11
  760. package/ref-monty/crates/monty/test_cases/math__floor_str_error.py +0 -11
  761. package/ref-monty/crates/monty/test_cases/math__fmod_inf_error.py +0 -11
  762. package/ref-monty/crates/monty/test_cases/math__gamma_neg_int_error.py +0 -11
  763. package/ref-monty/crates/monty/test_cases/math__gcd_float_error.py +0 -11
  764. package/ref-monty/crates/monty/test_cases/math__isqrt_negative_error.py +0 -11
  765. package/ref-monty/crates/monty/test_cases/math__ldexp_overflow_error.py +0 -11
  766. package/ref-monty/crates/monty/test_cases/math__log1p_domain_error.py +0 -11
  767. package/ref-monty/crates/monty/test_cases/math__log_base1_error.py +0 -11
  768. package/ref-monty/crates/monty/test_cases/math__log_zero_error.py +0 -11
  769. package/ref-monty/crates/monty/test_cases/math__module.py +0 -1432
  770. package/ref-monty/crates/monty/test_cases/math__pow_domain_error.py +0 -11
  771. package/ref-monty/crates/monty/test_cases/math__sin_inf_error.py +0 -11
  772. package/ref-monty/crates/monty/test_cases/math__sqrt_negative_error.py +0 -11
  773. package/ref-monty/crates/monty/test_cases/math__tan_inf_error.py +0 -11
  774. package/ref-monty/crates/monty/test_cases/math__trunc_str_error.py +0 -11
  775. package/ref-monty/crates/monty/test_cases/method__args_kwargs_unpacking.py +0 -259
  776. package/ref-monty/crates/monty/test_cases/name_error__unbound_local_func.py +0 -19
  777. package/ref-monty/crates/monty/test_cases/name_error__unbound_local_module.py +0 -12
  778. package/ref-monty/crates/monty/test_cases/name_error__undefined_call_chained.py +0 -9
  779. package/ref-monty/crates/monty/test_cases/name_error__undefined_call_in_expr.py +0 -9
  780. package/ref-monty/crates/monty/test_cases/name_error__undefined_call_in_function.py +0 -16
  781. package/ref-monty/crates/monty/test_cases/name_error__undefined_call_with_args.py +0 -9
  782. package/ref-monty/crates/monty/test_cases/name_error__undefined_global.py +0 -10
  783. package/ref-monty/crates/monty/test_cases/namedtuple__missing_attr.py +0 -11
  784. package/ref-monty/crates/monty/test_cases/namedtuple__ops.py +0 -34
  785. package/ref-monty/crates/monty/test_cases/nonlocal__error_module_level.py +0 -3
  786. package/ref-monty/crates/monty/test_cases/nonlocal__ops.py +0 -353
  787. package/ref-monty/crates/monty/test_cases/os__environ.py +0 -40
  788. package/ref-monty/crates/monty/test_cases/os__getenv_key_list_error.py +0 -5
  789. package/ref-monty/crates/monty/test_cases/os__getenv_key_type_error.py +0 -5
  790. package/ref-monty/crates/monty/test_cases/parse_error__complex.py +0 -3
  791. package/ref-monty/crates/monty/test_cases/pathlib__import.py +0 -11
  792. package/ref-monty/crates/monty/test_cases/pathlib__os.py +0 -136
  793. package/ref-monty/crates/monty/test_cases/pathlib__os_read_error.py +0 -12
  794. package/ref-monty/crates/monty/test_cases/pathlib__pure.py +0 -81
  795. package/ref-monty/crates/monty/test_cases/pyobject__cycle_dict_self.py +0 -5
  796. package/ref-monty/crates/monty/test_cases/pyobject__cycle_list_dict.py +0 -6
  797. package/ref-monty/crates/monty/test_cases/pyobject__cycle_list_self.py +0 -5
  798. package/ref-monty/crates/monty/test_cases/pyobject__cycle_multiple_refs.py +0 -6
  799. package/ref-monty/crates/monty/test_cases/range__error_no_args.py +0 -2
  800. package/ref-monty/crates/monty/test_cases/range__error_step_zero.py +0 -2
  801. package/ref-monty/crates/monty/test_cases/range__error_too_many_args.py +0 -2
  802. package/ref-monty/crates/monty/test_cases/range__getitem_index_error.py +0 -10
  803. package/ref-monty/crates/monty/test_cases/range__ops.py +0 -236
  804. package/ref-monty/crates/monty/test_cases/re__basic.py +0 -756
  805. package/ref-monty/crates/monty/test_cases/re__grouping.py +0 -241
  806. package/ref-monty/crates/monty/test_cases/re__match.py +0 -148
  807. package/ref-monty/crates/monty/test_cases/recursion__deep_drop.py +0 -26
  808. package/ref-monty/crates/monty/test_cases/recursion__deep_eq.py +0 -23
  809. package/ref-monty/crates/monty/test_cases/recursion__deep_hash.py +0 -46
  810. package/ref-monty/crates/monty/test_cases/recursion__deep_repr.py +0 -12
  811. package/ref-monty/crates/monty/test_cases/recursion__function_depth.py +0 -13
  812. package/ref-monty/crates/monty/test_cases/refcount__cycle_mutual_reference.py +0 -18
  813. package/ref-monty/crates/monty/test_cases/refcount__cycle_self_reference.py +0 -12
  814. package/ref-monty/crates/monty/test_cases/refcount__dict_basic.py +0 -5
  815. package/ref-monty/crates/monty/test_cases/refcount__dict_get.py +0 -5
  816. package/ref-monty/crates/monty/test_cases/refcount__dict_keys_and.py +0 -14
  817. package/ref-monty/crates/monty/test_cases/refcount__dict_overwrite.py +0 -6
  818. package/ref-monty/crates/monty/test_cases/refcount__gather_cleanup.py +0 -16
  819. package/ref-monty/crates/monty/test_cases/refcount__gather_exception.py +0 -18
  820. package/ref-monty/crates/monty/test_cases/refcount__gather_nested_cancel.py +0 -25
  821. package/ref-monty/crates/monty/test_cases/refcount__immediate_skipped.py +0 -4
  822. package/ref-monty/crates/monty/test_cases/refcount__kwargs_unpacking.py +0 -27
  823. package/ref-monty/crates/monty/test_cases/refcount__list_append_multiple.py +0 -6
  824. package/ref-monty/crates/monty/test_cases/refcount__list_append_ref.py +0 -5
  825. package/ref-monty/crates/monty/test_cases/refcount__list_concat.py +0 -5
  826. package/ref-monty/crates/monty/test_cases/refcount__list_getitem.py +0 -5
  827. package/ref-monty/crates/monty/test_cases/refcount__list_iadd.py +0 -5
  828. package/ref-monty/crates/monty/test_cases/refcount__nested_list.py +0 -4
  829. package/ref-monty/crates/monty/test_cases/refcount__re_pattern_sub_error_paths.py +0 -37
  830. package/ref-monty/crates/monty/test_cases/refcount__re_search_match.py +0 -34
  831. package/ref-monty/crates/monty/test_cases/refcount__re_sub_error_paths.py +0 -31
  832. package/ref-monty/crates/monty/test_cases/refcount__shared_reference.py +0 -4
  833. package/ref-monty/crates/monty/test_cases/refcount__single_list.py +0 -3
  834. package/ref-monty/crates/monty/test_cases/repr__cycle_detection.py +0 -24
  835. package/ref-monty/crates/monty/test_cases/set__ops.py +0 -191
  836. package/ref-monty/crates/monty/test_cases/set__review_bugs.py +0 -35
  837. package/ref-monty/crates/monty/test_cases/set__unpack_type_error.py +0 -2
  838. package/ref-monty/crates/monty/test_cases/slice__invalid_indices.py +0 -2
  839. package/ref-monty/crates/monty/test_cases/slice__kwargs.py +0 -9
  840. package/ref-monty/crates/monty/test_cases/slice__no_args.py +0 -9
  841. package/ref-monty/crates/monty/test_cases/slice__ops.py +0 -149
  842. package/ref-monty/crates/monty/test_cases/slice__step_zero.py +0 -9
  843. package/ref-monty/crates/monty/test_cases/slice__step_zero_bytes.py +0 -9
  844. package/ref-monty/crates/monty/test_cases/slice__step_zero_range.py +0 -9
  845. package/ref-monty/crates/monty/test_cases/slice__step_zero_str.py +0 -9
  846. package/ref-monty/crates/monty/test_cases/slice__step_zero_tuple.py +0 -9
  847. package/ref-monty/crates/monty/test_cases/slice__too_many_args.py +0 -9
  848. package/ref-monty/crates/monty/test_cases/str__getitem_index_error.py +0 -10
  849. package/ref-monty/crates/monty/test_cases/str__index_not_found.py +0 -9
  850. package/ref-monty/crates/monty/test_cases/str__join_no_args.py +0 -9
  851. package/ref-monty/crates/monty/test_cases/str__join_non_string.py +0 -9
  852. package/ref-monty/crates/monty/test_cases/str__join_not_iterable.py +0 -9
  853. package/ref-monty/crates/monty/test_cases/str__join_too_many_args.py +0 -9
  854. package/ref-monty/crates/monty/test_cases/str__methods.py +0 -327
  855. package/ref-monty/crates/monty/test_cases/str__ops.py +0 -162
  856. package/ref-monty/crates/monty/test_cases/str__partition_empty.py +0 -9
  857. package/ref-monty/crates/monty/test_cases/str__rsplit_empty_sep.py +0 -9
  858. package/ref-monty/crates/monty/test_cases/str__split_empty_sep.py +0 -9
  859. package/ref-monty/crates/monty/test_cases/sys__types.py +0 -7
  860. package/ref-monty/crates/monty/test_cases/traceback__division_error.py +0 -30
  861. package/ref-monty/crates/monty/test_cases/traceback__index_error.py +0 -17
  862. package/ref-monty/crates/monty/test_cases/traceback__insert_as_int.py +0 -10
  863. package/ref-monty/crates/monty/test_cases/traceback__nested_call.py +0 -29
  864. package/ref-monty/crates/monty/test_cases/traceback__nonlocal_module_scope.py +0 -10
  865. package/ref-monty/crates/monty/test_cases/traceback__nonlocal_unbound.py +0 -24
  866. package/ref-monty/crates/monty/test_cases/traceback__range_as_int.py +0 -9
  867. package/ref-monty/crates/monty/test_cases/traceback__recursion_error.py +0 -23
  868. package/ref-monty/crates/monty/test_cases/traceback__set_mutation.py +0 -11
  869. package/ref-monty/crates/monty/test_cases/traceback__undefined_attr_call.py +0 -16
  870. package/ref-monty/crates/monty/test_cases/traceback__undefined_call.py +0 -16
  871. package/ref-monty/crates/monty/test_cases/traceback__undefined_raise.py +0 -16
  872. package/ref-monty/crates/monty/test_cases/try_except__all.py +0 -472
  873. package/ref-monty/crates/monty/test_cases/try_except__bare_raise_no_context.py +0 -2
  874. package/ref-monty/crates/monty/test_cases/try_except__invalid_type.py +0 -5
  875. package/ref-monty/crates/monty/test_cases/tuple__getitem_out_of_bounds.py +0 -3
  876. package/ref-monty/crates/monty/test_cases/tuple__index_not_found.py +0 -9
  877. package/ref-monty/crates/monty/test_cases/tuple__index_start_gt_end.py +0 -10
  878. package/ref-monty/crates/monty/test_cases/tuple__methods.py +0 -19
  879. package/ref-monty/crates/monty/test_cases/tuple__ops.py +0 -133
  880. package/ref-monty/crates/monty/test_cases/tuple__unpack_type_error.py +0 -2
  881. package/ref-monty/crates/monty/test_cases/type__builtin_attr_error.py +0 -9
  882. package/ref-monty/crates/monty/test_cases/type__bytes_negative.py +0 -2
  883. package/ref-monty/crates/monty/test_cases/type__cell_not_builtin.py +0 -9
  884. package/ref-monty/crates/monty/test_cases/type__exception_attr_error.py +0 -11
  885. package/ref-monty/crates/monty/test_cases/type__float_conversion_error.py +0 -2
  886. package/ref-monty/crates/monty/test_cases/type__float_repr_both_quotes.py +0 -9
  887. package/ref-monty/crates/monty/test_cases/type__float_repr_newline.py +0 -9
  888. package/ref-monty/crates/monty/test_cases/type__float_repr_single_quote.py +0 -9
  889. package/ref-monty/crates/monty/test_cases/type__int_conversion_error.py +0 -2
  890. package/ref-monty/crates/monty/test_cases/type__list_not_iterable.py +0 -2
  891. package/ref-monty/crates/monty/test_cases/type__non_builtin_name_error.py +0 -9
  892. package/ref-monty/crates/monty/test_cases/type__ops.py +0 -200
  893. package/ref-monty/crates/monty/test_cases/type__shadow_exc.py +0 -3
  894. package/ref-monty/crates/monty/test_cases/type__shadow_int.py +0 -9
  895. package/ref-monty/crates/monty/test_cases/type__shadow_len.py +0 -3
  896. package/ref-monty/crates/monty/test_cases/type__tuple_not_iterable.py +0 -2
  897. package/ref-monty/crates/monty/test_cases/type_error__int_add_list.py +0 -2
  898. package/ref-monty/crates/monty/test_cases/type_error__int_div_str.py +0 -2
  899. package/ref-monty/crates/monty/test_cases/type_error__int_floordiv_str.py +0 -2
  900. package/ref-monty/crates/monty/test_cases/type_error__int_iadd_str.py +0 -3
  901. package/ref-monty/crates/monty/test_cases/type_error__int_mod_str.py +0 -2
  902. package/ref-monty/crates/monty/test_cases/type_error__int_pow_str.py +0 -2
  903. package/ref-monty/crates/monty/test_cases/type_error__int_sub_str.py +0 -2
  904. package/ref-monty/crates/monty/test_cases/type_error__list_add_int.py +0 -2
  905. package/ref-monty/crates/monty/test_cases/type_error__list_add_str.py +0 -2
  906. package/ref-monty/crates/monty/test_cases/type_error__list_iadd_int.py +0 -6
  907. package/ref-monty/crates/monty/test_cases/type_error__str_add_int.py +0 -2
  908. package/ref-monty/crates/monty/test_cases/type_error__str_iadd_int.py +0 -3
  909. package/ref-monty/crates/monty/test_cases/type_error__unary_invert_str.py +0 -3
  910. package/ref-monty/crates/monty/test_cases/type_error__unary_minus_str.py +0 -4
  911. package/ref-monty/crates/monty/test_cases/type_error__unary_neg_str.py +0 -3
  912. package/ref-monty/crates/monty/test_cases/type_error__unary_plus_str.py +0 -4
  913. package/ref-monty/crates/monty/test_cases/typing__types.py +0 -24
  914. package/ref-monty/crates/monty/test_cases/unpack__nested.py +0 -48
  915. package/ref-monty/crates/monty/test_cases/unpack__non_sequence.py +0 -9
  916. package/ref-monty/crates/monty/test_cases/unpack__not_enough.py +0 -9
  917. package/ref-monty/crates/monty/test_cases/unpack__ops.py +0 -153
  918. package/ref-monty/crates/monty/test_cases/unpack__star_not_enough.py +0 -9
  919. package/ref-monty/crates/monty/test_cases/unpack__too_many.py +0 -9
  920. package/ref-monty/crates/monty/test_cases/version__cpython.py +0 -4
  921. package/ref-monty/crates/monty/test_cases/walrus__all.py +0 -178
  922. package/ref-monty/crates/monty/test_cases/while__all.py +0 -206
  923. package/ref-monty/crates/monty/tests/asyncio.rs +0 -764
  924. package/ref-monty/crates/monty/tests/binary_serde.rs +0 -185
  925. package/ref-monty/crates/monty/tests/bytecode_limits.rs +0 -248
  926. package/ref-monty/crates/monty/tests/datatest_runner.rs +0 -2029
  927. package/ref-monty/crates/monty/tests/inputs.rs +0 -420
  928. package/ref-monty/crates/monty/tests/json_serde.rs +0 -250
  929. package/ref-monty/crates/monty/tests/main.rs +0 -71
  930. package/ref-monty/crates/monty/tests/math_module.rs +0 -114
  931. package/ref-monty/crates/monty/tests/name_lookup.rs +0 -482
  932. package/ref-monty/crates/monty/tests/os_tests.rs +0 -459
  933. package/ref-monty/crates/monty/tests/parse_errors.rs +0 -441
  934. package/ref-monty/crates/monty/tests/print_writer.rs +0 -238
  935. package/ref-monty/crates/monty/tests/py_object.rs +0 -121
  936. package/ref-monty/crates/monty/tests/regex.rs +0 -90
  937. package/ref-monty/crates/monty/tests/repl.rs +0 -344
  938. package/ref-monty/crates/monty/tests/resource_limits.rs +0 -1826
  939. package/ref-monty/crates/monty/tests/try_from.rs +0 -167
  940. package/ref-monty/crates/monty-cli/Cargo.toml +0 -25
  941. package/ref-monty/crates/monty-cli/src/main.rs +0 -541
  942. package/ref-monty/crates/monty-js/.cargo/config.toml +0 -2
  943. package/ref-monty/crates/monty-js/.prettierignore +0 -8
  944. package/ref-monty/crates/monty-js/Cargo.toml +0 -32
  945. package/ref-monty/crates/monty-js/README.md +0 -207
  946. package/ref-monty/crates/monty-js/__test__/async.spec.ts +0 -350
  947. package/ref-monty/crates/monty-js/__test__/basic.spec.ts +0 -114
  948. package/ref-monty/crates/monty-js/__test__/exceptions.spec.ts +0 -427
  949. package/ref-monty/crates/monty-js/__test__/external.spec.ts +0 -354
  950. package/ref-monty/crates/monty-js/__test__/inputs.spec.ts +0 -143
  951. package/ref-monty/crates/monty-js/__test__/limits.spec.ts +0 -162
  952. package/ref-monty/crates/monty-js/__test__/package.json +0 -3
  953. package/ref-monty/crates/monty-js/__test__/print.spec.ts +0 -229
  954. package/ref-monty/crates/monty-js/__test__/repl.spec.ts +0 -34
  955. package/ref-monty/crates/monty-js/__test__/serialize.spec.ts +0 -205
  956. package/ref-monty/crates/monty-js/__test__/start.spec.ts +0 -443
  957. package/ref-monty/crates/monty-js/__test__/type_check.spec.ts +0 -147
  958. package/ref-monty/crates/monty-js/__test__/types.spec.ts +0 -319
  959. package/ref-monty/crates/monty-js/build.rs +0 -61
  960. package/ref-monty/crates/monty-js/index-header.d.ts +0 -3
  961. package/ref-monty/crates/monty-js/package-lock.json +0 -4694
  962. package/ref-monty/crates/monty-js/package.json +0 -100
  963. package/ref-monty/crates/monty-js/scripts/smoke-test.sh +0 -69
  964. package/ref-monty/crates/monty-js/smoke-test/package.json +0 -17
  965. package/ref-monty/crates/monty-js/smoke-test/test.ts +0 -171
  966. package/ref-monty/crates/monty-js/smoke-test/tsconfig.json +0 -11
  967. package/ref-monty/crates/monty-js/src/convert.rs +0 -648
  968. package/ref-monty/crates/monty-js/src/exceptions.rs +0 -293
  969. package/ref-monty/crates/monty-js/src/lib.rs +0 -41
  970. package/ref-monty/crates/monty-js/src/limits.rs +0 -53
  971. package/ref-monty/crates/monty-js/src/monty_cls.rs +0 -1407
  972. package/ref-monty/crates/monty-js/tsconfig.json +0 -17
  973. package/ref-monty/crates/monty-js/wrapper.ts +0 -701
  974. package/ref-monty/crates/monty-python/Cargo.toml +0 -38
  975. package/ref-monty/crates/monty-python/README.md +0 -134
  976. package/ref-monty/crates/monty-python/build.rs +0 -4
  977. package/ref-monty/crates/monty-python/example.py +0 -40
  978. package/ref-monty/crates/monty-python/exercise.py +0 -46
  979. package/ref-monty/crates/monty-python/pyproject.toml +0 -57
  980. package/ref-monty/crates/monty-python/python/pydantic_monty/__init__.py +0 -281
  981. package/ref-monty/crates/monty-python/python/pydantic_monty/_monty.pyi +0 -677
  982. package/ref-monty/crates/monty-python/python/pydantic_monty/os_access.py +0 -933
  983. package/ref-monty/crates/monty-python/python/pydantic_monty/py.typed +0 -0
  984. package/ref-monty/crates/monty-python/src/convert.rs +0 -273
  985. package/ref-monty/crates/monty-python/src/dataclass.rs +0 -461
  986. package/ref-monty/crates/monty-python/src/exceptions.rs +0 -557
  987. package/ref-monty/crates/monty-python/src/external.rs +0 -165
  988. package/ref-monty/crates/monty-python/src/lib.rs +0 -77
  989. package/ref-monty/crates/monty-python/src/limits.rs +0 -142
  990. package/ref-monty/crates/monty-python/src/monty_cls.rs +0 -1650
  991. package/ref-monty/crates/monty-python/src/repl.rs +0 -470
  992. package/ref-monty/crates/monty-python/src/serialization.rs +0 -761
  993. package/ref-monty/crates/monty-python/tests/test_async.py +0 -1201
  994. package/ref-monty/crates/monty-python/tests/test_basic.py +0 -66
  995. package/ref-monty/crates/monty-python/tests/test_dataclasses.py +0 -971
  996. package/ref-monty/crates/monty-python/tests/test_exceptions.py +0 -361
  997. package/ref-monty/crates/monty-python/tests/test_external.py +0 -367
  998. package/ref-monty/crates/monty-python/tests/test_inputs.py +0 -126
  999. package/ref-monty/crates/monty-python/tests/test_limits.py +0 -257
  1000. package/ref-monty/crates/monty-python/tests/test_os_access.py +0 -1286
  1001. package/ref-monty/crates/monty-python/tests/test_os_access_compat.py +0 -731
  1002. package/ref-monty/crates/monty-python/tests/test_os_access_raw.py +0 -483
  1003. package/ref-monty/crates/monty-python/tests/test_os_calls.py +0 -819
  1004. package/ref-monty/crates/monty-python/tests/test_print.py +0 -208
  1005. package/ref-monty/crates/monty-python/tests/test_re.py +0 -170
  1006. package/ref-monty/crates/monty-python/tests/test_readme_examples.py +0 -20
  1007. package/ref-monty/crates/monty-python/tests/test_repl.py +0 -749
  1008. package/ref-monty/crates/monty-python/tests/test_serialize.py +0 -284
  1009. package/ref-monty/crates/monty-python/tests/test_start.py +0 -346
  1010. package/ref-monty/crates/monty-python/tests/test_threading.py +0 -163
  1011. package/ref-monty/crates/monty-python/tests/test_type_check.py +0 -344
  1012. package/ref-monty/crates/monty-python/tests/test_types.py +0 -553
  1013. package/ref-monty/crates/monty-type-checking/Cargo.toml +0 -32
  1014. package/ref-monty/crates/monty-type-checking/src/db.rs +0 -116
  1015. package/ref-monty/crates/monty-type-checking/src/lib.rs +0 -4
  1016. package/ref-monty/crates/monty-type-checking/src/type_check.rs +0 -280
  1017. package/ref-monty/crates/monty-type-checking/tests/bad_types.py +0 -109
  1018. package/ref-monty/crates/monty-type-checking/tests/bad_types_output.txt +0 -21
  1019. package/ref-monty/crates/monty-type-checking/tests/good_types.py +0 -475
  1020. package/ref-monty/crates/monty-type-checking/tests/main.rs +0 -205
  1021. package/ref-monty/crates/monty-type-checking/tests/reveal_types.py +0 -56
  1022. package/ref-monty/crates/monty-type-checking/tests/reveal_types_output.txt +0 -41
  1023. package/ref-monty/crates/monty-typeshed/Cargo.toml +0 -29
  1024. package/ref-monty/crates/monty-typeshed/README.md +0 -11
  1025. package/ref-monty/crates/monty-typeshed/build.rs +0 -101
  1026. package/ref-monty/crates/monty-typeshed/custom/README.md +0 -1
  1027. package/ref-monty/crates/monty-typeshed/custom/asyncio.pyi +0 -138
  1028. package/ref-monty/crates/monty-typeshed/custom/os.pyi +0 -87
  1029. package/ref-monty/crates/monty-typeshed/custom/sys.pyi +0 -33
  1030. package/ref-monty/crates/monty-typeshed/src/lib.rs +0 -56
  1031. package/ref-monty/crates/monty-typeshed/update.py +0 -321
  1032. package/ref-monty/crates/monty-typeshed/vendor/typeshed/source_commit.txt +0 -1
  1033. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/VERSIONS +0 -20
  1034. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/_collections_abc.pyi +0 -105
  1035. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/_typeshed/__init__.pyi +0 -394
  1036. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/asyncio.pyi +0 -138
  1037. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/builtins.pyi +0 -1434
  1038. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/collections/__init__.pyi +0 -527
  1039. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/collections/abc.pyi +0 -2
  1040. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/dataclasses.pyi +0 -502
  1041. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/enum.pyi +0 -376
  1042. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/math.pyi +0 -149
  1043. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/os.pyi +0 -87
  1044. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/pathlib/__init__.pyi +0 -395
  1045. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/pathlib/types.pyi +0 -8
  1046. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/re.pyi +0 -337
  1047. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/sys.pyi +0 -33
  1048. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/types.pyi +0 -741
  1049. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/typing.pyi +0 -1217
  1050. package/ref-monty/crates/monty-typeshed/vendor/typeshed/stdlib/typing_extensions.pyi +0 -716
  1051. package/ref-monty/docs/usage-guide.md +0 -117
  1052. package/ref-monty/examples/README.md +0 -3
  1053. package/ref-monty/examples/expense_analysis/README.md +0 -3
  1054. package/ref-monty/examples/expense_analysis/data.py +0 -124
  1055. package/ref-monty/examples/expense_analysis/main.py +0 -115
  1056. package/ref-monty/examples/sql_playground/README.md +0 -20
  1057. package/ref-monty/examples/sql_playground/external_functions.py +0 -129
  1058. package/ref-monty/examples/sql_playground/main.py +0 -81
  1059. package/ref-monty/examples/sql_playground/sandbox_code.py +0 -82
  1060. package/ref-monty/examples/sql_playground/type_stubs.pyi +0 -14
  1061. package/ref-monty/examples/web_scraper/README.md +0 -15
  1062. package/ref-monty/examples/web_scraper/browser.py +0 -56
  1063. package/ref-monty/examples/web_scraper/example_code.py +0 -59
  1064. package/ref-monty/examples/web_scraper/external_functions.py +0 -324
  1065. package/ref-monty/examples/web_scraper/main.py +0 -193
  1066. package/ref-monty/examples/web_scraper/sub_agent.py +0 -79
  1067. package/ref-monty/monty-npm.md +0 -235
  1068. package/ref-monty/pyproject.toml +0 -162
  1069. package/ref-monty/scripts/check_imports.py +0 -91
  1070. package/ref-monty/scripts/codecov_diff.py +0 -412
  1071. package/ref-monty/scripts/complete_tests.py +0 -146
  1072. package/ref-monty/scripts/flamegraph_to_text.py +0 -208
  1073. package/ref-monty/scripts/iter_test_methods.py +0 -540
  1074. package/ref-monty/scripts/run_traceback.py +0 -180
  1075. package/ref-monty/scripts/startup_performance.py +0 -130
  1076. package/ref-monty/uv.lock +0 -1779
  1077. package/temp_resend_cli/repo/.github/scripts/pr-title-check.js +0 -34
  1078. package/temp_resend_cli/repo/.github/workflows/ci.yml +0 -67
  1079. package/temp_resend_cli/repo/.github/workflows/post-release.yml +0 -51
  1080. package/temp_resend_cli/repo/.github/workflows/pr-title-check.yml +0 -13
  1081. package/temp_resend_cli/repo/.github/workflows/release.yml +0 -175
  1082. package/temp_resend_cli/repo/.github/workflows/test-install-unix.yml +0 -34
  1083. package/temp_resend_cli/repo/.github/workflows/test-install-windows.yml +0 -48
  1084. package/temp_resend_cli/repo/CHANGELOG.md +0 -31
  1085. package/temp_resend_cli/repo/LICENSE +0 -21
  1086. package/temp_resend_cli/repo/README.md +0 -450
  1087. package/temp_resend_cli/repo/biome.json +0 -36
  1088. package/temp_resend_cli/repo/install.ps1 +0 -141
  1089. package/temp_resend_cli/repo/install.sh +0 -301
  1090. package/temp_resend_cli/repo/package.json +0 -61
  1091. package/temp_resend_cli/repo/pnpm-lock.yaml +0 -2439
  1092. package/temp_resend_cli/repo/renovate.json +0 -4
  1093. package/temp_resend_cli/repo/src/cli.ts +0 -98
  1094. package/temp_resend_cli/repo/src/commands/api-keys/create.ts +0 -114
  1095. package/temp_resend_cli/repo/src/commands/api-keys/delete.ts +0 -47
  1096. package/temp_resend_cli/repo/src/commands/api-keys/index.ts +0 -26
  1097. package/temp_resend_cli/repo/src/commands/api-keys/list.ts +0 -35
  1098. package/temp_resend_cli/repo/src/commands/api-keys/utils.ts +0 -8
  1099. package/temp_resend_cli/repo/src/commands/auth/index.ts +0 -20
  1100. package/temp_resend_cli/repo/src/commands/auth/login.ts +0 -234
  1101. package/temp_resend_cli/repo/src/commands/auth/logout.ts +0 -105
  1102. package/temp_resend_cli/repo/src/commands/broadcasts/create.ts +0 -196
  1103. package/temp_resend_cli/repo/src/commands/broadcasts/delete.ts +0 -46
  1104. package/temp_resend_cli/repo/src/commands/broadcasts/get.ts +0 -59
  1105. package/temp_resend_cli/repo/src/commands/broadcasts/index.ts +0 -43
  1106. package/temp_resend_cli/repo/src/commands/broadcasts/list.ts +0 -60
  1107. package/temp_resend_cli/repo/src/commands/broadcasts/send.ts +0 -56
  1108. package/temp_resend_cli/repo/src/commands/broadcasts/update.ts +0 -95
  1109. package/temp_resend_cli/repo/src/commands/broadcasts/utils.ts +0 -35
  1110. package/temp_resend_cli/repo/src/commands/contact-properties/create.ts +0 -118
  1111. package/temp_resend_cli/repo/src/commands/contact-properties/delete.ts +0 -48
  1112. package/temp_resend_cli/repo/src/commands/contact-properties/get.ts +0 -46
  1113. package/temp_resend_cli/repo/src/commands/contact-properties/index.ts +0 -48
  1114. package/temp_resend_cli/repo/src/commands/contact-properties/list.ts +0 -68
  1115. package/temp_resend_cli/repo/src/commands/contact-properties/update.ts +0 -88
  1116. package/temp_resend_cli/repo/src/commands/contact-properties/utils.ts +0 -17
  1117. package/temp_resend_cli/repo/src/commands/contacts/add-segment.ts +0 -78
  1118. package/temp_resend_cli/repo/src/commands/contacts/create.ts +0 -122
  1119. package/temp_resend_cli/repo/src/commands/contacts/delete.ts +0 -49
  1120. package/temp_resend_cli/repo/src/commands/contacts/get.ts +0 -53
  1121. package/temp_resend_cli/repo/src/commands/contacts/index.ts +0 -58
  1122. package/temp_resend_cli/repo/src/commands/contacts/list.ts +0 -57
  1123. package/temp_resend_cli/repo/src/commands/contacts/remove-segment.ts +0 -48
  1124. package/temp_resend_cli/repo/src/commands/contacts/segments.ts +0 -39
  1125. package/temp_resend_cli/repo/src/commands/contacts/topics.ts +0 -45
  1126. package/temp_resend_cli/repo/src/commands/contacts/update-topics.ts +0 -90
  1127. package/temp_resend_cli/repo/src/commands/contacts/update.ts +0 -77
  1128. package/temp_resend_cli/repo/src/commands/contacts/utils.ts +0 -119
  1129. package/temp_resend_cli/repo/src/commands/doctor.ts +0 -216
  1130. package/temp_resend_cli/repo/src/commands/domains/create.ts +0 -83
  1131. package/temp_resend_cli/repo/src/commands/domains/delete.ts +0 -42
  1132. package/temp_resend_cli/repo/src/commands/domains/get.ts +0 -47
  1133. package/temp_resend_cli/repo/src/commands/domains/index.ts +0 -35
  1134. package/temp_resend_cli/repo/src/commands/domains/list.ts +0 -53
  1135. package/temp_resend_cli/repo/src/commands/domains/update.ts +0 -75
  1136. package/temp_resend_cli/repo/src/commands/domains/utils.ts +0 -44
  1137. package/temp_resend_cli/repo/src/commands/domains/verify.ts +0 -38
  1138. package/temp_resend_cli/repo/src/commands/emails/batch.ts +0 -140
  1139. package/temp_resend_cli/repo/src/commands/emails/get.ts +0 -44
  1140. package/temp_resend_cli/repo/src/commands/emails/index.ts +0 -30
  1141. package/temp_resend_cli/repo/src/commands/emails/list.ts +0 -84
  1142. package/temp_resend_cli/repo/src/commands/emails/receiving/attachment.ts +0 -55
  1143. package/temp_resend_cli/repo/src/commands/emails/receiving/attachments.ts +0 -68
  1144. package/temp_resend_cli/repo/src/commands/emails/receiving/get.ts +0 -58
  1145. package/temp_resend_cli/repo/src/commands/emails/receiving/index.ts +0 -28
  1146. package/temp_resend_cli/repo/src/commands/emails/receiving/list.ts +0 -59
  1147. package/temp_resend_cli/repo/src/commands/emails/receiving/utils.ts +0 -38
  1148. package/temp_resend_cli/repo/src/commands/emails/send.ts +0 -189
  1149. package/temp_resend_cli/repo/src/commands/open.ts +0 -27
  1150. package/temp_resend_cli/repo/src/commands/segments/create.ts +0 -50
  1151. package/temp_resend_cli/repo/src/commands/segments/delete.ts +0 -47
  1152. package/temp_resend_cli/repo/src/commands/segments/get.ts +0 -38
  1153. package/temp_resend_cli/repo/src/commands/segments/index.ts +0 -36
  1154. package/temp_resend_cli/repo/src/commands/segments/list.ts +0 -58
  1155. package/temp_resend_cli/repo/src/commands/segments/utils.ts +0 -7
  1156. package/temp_resend_cli/repo/src/commands/teams/index.ts +0 -10
  1157. package/temp_resend_cli/repo/src/commands/teams/list.ts +0 -35
  1158. package/temp_resend_cli/repo/src/commands/teams/remove.ts +0 -86
  1159. package/temp_resend_cli/repo/src/commands/teams/switch.ts +0 -76
  1160. package/temp_resend_cli/repo/src/commands/topics/create.ts +0 -73
  1161. package/temp_resend_cli/repo/src/commands/topics/delete.ts +0 -47
  1162. package/temp_resend_cli/repo/src/commands/topics/get.ts +0 -42
  1163. package/temp_resend_cli/repo/src/commands/topics/index.ts +0 -42
  1164. package/temp_resend_cli/repo/src/commands/topics/list.ts +0 -34
  1165. package/temp_resend_cli/repo/src/commands/topics/update.ts +0 -59
  1166. package/temp_resend_cli/repo/src/commands/topics/utils.ts +0 -16
  1167. package/temp_resend_cli/repo/src/commands/webhooks/create.ts +0 -128
  1168. package/temp_resend_cli/repo/src/commands/webhooks/delete.ts +0 -49
  1169. package/temp_resend_cli/repo/src/commands/webhooks/get.ts +0 -42
  1170. package/temp_resend_cli/repo/src/commands/webhooks/index.ts +0 -42
  1171. package/temp_resend_cli/repo/src/commands/webhooks/list.ts +0 -55
  1172. package/temp_resend_cli/repo/src/commands/webhooks/listen.ts +0 -379
  1173. package/temp_resend_cli/repo/src/commands/webhooks/update.ts +0 -83
  1174. package/temp_resend_cli/repo/src/commands/webhooks/utils.ts +0 -36
  1175. package/temp_resend_cli/repo/src/commands/whoami.ts +0 -71
  1176. package/temp_resend_cli/repo/src/lib/actions.ts +0 -157
  1177. package/temp_resend_cli/repo/src/lib/client.ts +0 -37
  1178. package/temp_resend_cli/repo/src/lib/config.ts +0 -217
  1179. package/temp_resend_cli/repo/src/lib/files.ts +0 -15
  1180. package/temp_resend_cli/repo/src/lib/help-text.ts +0 -38
  1181. package/temp_resend_cli/repo/src/lib/output.ts +0 -56
  1182. package/temp_resend_cli/repo/src/lib/pagination.ts +0 -36
  1183. package/temp_resend_cli/repo/src/lib/prompts.ts +0 -149
  1184. package/temp_resend_cli/repo/src/lib/spinner.ts +0 -100
  1185. package/temp_resend_cli/repo/src/lib/table.ts +0 -57
  1186. package/temp_resend_cli/repo/src/lib/tty.ts +0 -28
  1187. package/temp_resend_cli/repo/src/lib/update-check.ts +0 -169
  1188. package/temp_resend_cli/repo/src/lib/version.ts +0 -4
  1189. package/temp_resend_cli/repo/tests/commands/api-keys/create.test.ts +0 -196
  1190. package/temp_resend_cli/repo/tests/commands/api-keys/delete.test.ts +0 -157
  1191. package/temp_resend_cli/repo/tests/commands/api-keys/list.test.ts +0 -134
  1192. package/temp_resend_cli/repo/tests/commands/auth/login.test.ts +0 -153
  1193. package/temp_resend_cli/repo/tests/commands/auth/logout.test.ts +0 -153
  1194. package/temp_resend_cli/repo/tests/commands/broadcasts/create.test.ts +0 -454
  1195. package/temp_resend_cli/repo/tests/commands/broadcasts/delete.test.ts +0 -183
  1196. package/temp_resend_cli/repo/tests/commands/broadcasts/get.test.ts +0 -147
  1197. package/temp_resend_cli/repo/tests/commands/broadcasts/list.test.ts +0 -199
  1198. package/temp_resend_cli/repo/tests/commands/broadcasts/send.test.ts +0 -162
  1199. package/temp_resend_cli/repo/tests/commands/broadcasts/update.test.ts +0 -288
  1200. package/temp_resend_cli/repo/tests/commands/contact-properties/create.test.ts +0 -251
  1201. package/temp_resend_cli/repo/tests/commands/contact-properties/delete.test.ts +0 -184
  1202. package/temp_resend_cli/repo/tests/commands/contact-properties/get.test.ts +0 -145
  1203. package/temp_resend_cli/repo/tests/commands/contact-properties/list.test.ts +0 -181
  1204. package/temp_resend_cli/repo/tests/commands/contact-properties/update.test.ts +0 -217
  1205. package/temp_resend_cli/repo/tests/commands/contacts/add-segment.test.ts +0 -189
  1206. package/temp_resend_cli/repo/tests/commands/contacts/create.test.ts +0 -271
  1207. package/temp_resend_cli/repo/tests/commands/contacts/delete.test.ts +0 -193
  1208. package/temp_resend_cli/repo/tests/commands/contacts/get.test.ts +0 -149
  1209. package/temp_resend_cli/repo/tests/commands/contacts/list.test.ts +0 -176
  1210. package/temp_resend_cli/repo/tests/commands/contacts/remove-segment.test.ts +0 -167
  1211. package/temp_resend_cli/repo/tests/commands/contacts/segments.test.ts +0 -168
  1212. package/temp_resend_cli/repo/tests/commands/contacts/topics.test.ts +0 -164
  1213. package/temp_resend_cli/repo/tests/commands/contacts/update-topics.test.ts +0 -248
  1214. package/temp_resend_cli/repo/tests/commands/contacts/update.test.ts +0 -206
  1215. package/temp_resend_cli/repo/tests/commands/doctor.test.ts +0 -164
  1216. package/temp_resend_cli/repo/tests/commands/domains/create.test.ts +0 -193
  1217. package/temp_resend_cli/repo/tests/commands/domains/delete.test.ts +0 -157
  1218. package/temp_resend_cli/repo/tests/commands/domains/get.test.ts +0 -138
  1219. package/temp_resend_cli/repo/tests/commands/domains/list.test.ts +0 -165
  1220. package/temp_resend_cli/repo/tests/commands/domains/update.test.ts +0 -224
  1221. package/temp_resend_cli/repo/tests/commands/domains/verify.test.ts +0 -118
  1222. package/temp_resend_cli/repo/tests/commands/emails/batch.test.ts +0 -324
  1223. package/temp_resend_cli/repo/tests/commands/emails/get.test.ts +0 -132
  1224. package/temp_resend_cli/repo/tests/commands/emails/receiving/attachment.test.ts +0 -141
  1225. package/temp_resend_cli/repo/tests/commands/emails/receiving/attachments.test.ts +0 -169
  1226. package/temp_resend_cli/repo/tests/commands/emails/receiving/get.test.ts +0 -141
  1227. package/temp_resend_cli/repo/tests/commands/emails/receiving/list.test.ts +0 -182
  1228. package/temp_resend_cli/repo/tests/commands/emails/send.test.ts +0 -312
  1229. package/temp_resend_cli/repo/tests/commands/segments/create.test.ts +0 -164
  1230. package/temp_resend_cli/repo/tests/commands/segments/delete.test.ts +0 -183
  1231. package/temp_resend_cli/repo/tests/commands/segments/get.test.ts +0 -138
  1232. package/temp_resend_cli/repo/tests/commands/segments/list.test.ts +0 -174
  1233. package/temp_resend_cli/repo/tests/commands/teams/list.test.ts +0 -62
  1234. package/temp_resend_cli/repo/tests/commands/teams/remove.test.ts +0 -110
  1235. package/temp_resend_cli/repo/tests/commands/teams/switch.test.ts +0 -103
  1236. package/temp_resend_cli/repo/tests/commands/topics/create.test.ts +0 -192
  1237. package/temp_resend_cli/repo/tests/commands/topics/delete.test.ts +0 -157
  1238. package/temp_resend_cli/repo/tests/commands/topics/get.test.ts +0 -126
  1239. package/temp_resend_cli/repo/tests/commands/topics/list.test.ts +0 -125
  1240. package/temp_resend_cli/repo/tests/commands/topics/update.test.ts +0 -178
  1241. package/temp_resend_cli/repo/tests/commands/webhooks/create.test.ts +0 -225
  1242. package/temp_resend_cli/repo/tests/commands/webhooks/delete.test.ts +0 -157
  1243. package/temp_resend_cli/repo/tests/commands/webhooks/get.test.ts +0 -126
  1244. package/temp_resend_cli/repo/tests/commands/webhooks/list.test.ts +0 -178
  1245. package/temp_resend_cli/repo/tests/commands/webhooks/update.test.ts +0 -207
  1246. package/temp_resend_cli/repo/tests/commands/whoami.test.ts +0 -98
  1247. package/temp_resend_cli/repo/tests/e2e/smoke.test.ts +0 -93
  1248. package/temp_resend_cli/repo/tests/helpers.ts +0 -86
  1249. package/temp_resend_cli/repo/tests/lib/client.test.ts +0 -71
  1250. package/temp_resend_cli/repo/tests/lib/config.test.ts +0 -451
  1251. package/temp_resend_cli/repo/tests/lib/files.test.ts +0 -73
  1252. package/temp_resend_cli/repo/tests/lib/help-text.test.ts +0 -97
  1253. package/temp_resend_cli/repo/tests/lib/output.test.ts +0 -136
  1254. package/temp_resend_cli/repo/tests/lib/prompts.test.ts +0 -185
  1255. package/temp_resend_cli/repo/tests/lib/spinner.test.ts +0 -166
  1256. package/temp_resend_cli/repo/tests/lib/table.test.ts +0 -63
  1257. package/temp_resend_cli/repo/tests/lib/tty.test.ts +0 -89
  1258. package/temp_resend_cli/repo/tests/lib/update-check.test.ts +0 -179
  1259. package/temp_resend_cli/repo/tsconfig.json +0 -14
  1260. package/temp_resend_cli/repo/vitest.config.e2e.ts +0 -8
  1261. package/temp_resend_cli/repo/vitest.config.ts +0 -10
  1262. /package/docs/{plugin-examples.md → plugins-examples.md} +0 -0
@@ -1,1650 +0,0 @@
1
- use std::{
2
- borrow::Cow,
3
- fmt::Write,
4
- sync::{Mutex, PoisonError},
5
- };
6
-
7
- // Use `::monty` to refer to the external crate (not the pymodule)
8
- use ::monty::{
9
- ExtFunctionResult, FunctionCall, LimitedTracker, MontyException, MontyObject, MontyRun, NameLookupResult,
10
- NoLimitTracker, OsCall, PrintWriter, PrintWriterCallback, ReplFunctionCall, ReplNameLookup, ReplOsCall,
11
- ReplProgress, ReplResolveFutures, ReplStartError, ResolveFutures, ResourceTracker, RunProgress,
12
- };
13
- use monty::{ExcType, NameLookup};
14
- use monty_type_checking::{SourceFile, type_check};
15
- use pyo3::{
16
- IntoPyObjectExt,
17
- exceptions::{PyKeyError, PyRuntimeError, PyTypeError, PyValueError},
18
- intern,
19
- prelude::*,
20
- types::{PyBytes, PyDict, PyList, PyTuple, PyType},
21
- };
22
- use send_wrapper::SendWrapper;
23
-
24
- use crate::{
25
- convert::{get_docstring, monty_to_py, py_to_monty},
26
- dataclass::DcRegistry,
27
- exceptions::{MontyError, MontyTypingError, exc_py_to_monty},
28
- external::{ExternalFunctionRegistry, dispatch_method_call},
29
- limits::{PySignalTracker, extract_limits},
30
- repl::{EitherRepl, FromCoreRepl, PyMontyRepl},
31
- };
32
-
33
- /// A sandboxed Python interpreter instance.
34
- ///
35
- /// Parses and compiles Python code on initialization, then can be run
36
- /// multiple times with different input values. This separates the parsing
37
- /// cost from execution, making repeated runs more efficient.
38
- #[pyclass(name = "Monty", module = "pydantic_monty")]
39
- #[derive(Debug)]
40
- pub struct PyMonty {
41
- /// The compiled code snapshot, ready to execute.
42
- runner: MontyRun,
43
- /// The artificial name of the python code "file"
44
- script_name: String,
45
- /// Names of input variables expected by the code.
46
- input_names: Vec<String>,
47
- /// Registry of dataclass types for reconstructing original types on output.
48
- ///
49
- /// Maps type pointer identity (`u64`) to the original Python type, allowing
50
- /// `isinstance(result, OriginalClass)` to work correctly after round-tripping through Monty.
51
- dc_registry: DcRegistry,
52
- }
53
-
54
- #[pymethods]
55
- impl PyMonty {
56
- /// Creates a new Monty interpreter by parsing the given code.
57
- ///
58
- /// # Arguments
59
- /// * `code` - Python code to execute
60
- /// * `inputs` - List of input variable names available in the code
61
- /// * `type_check` - Whether to perform type checking on the code
62
- /// * `type_check_stubs` - Prefix code to be executed before type checking
63
- /// * `dataclass_registry` - Registry of dataclass types for reconstructing original types on output.
64
- #[new]
65
- #[pyo3(signature = (code, *, script_name="main.py", inputs=None, type_check=false, type_check_stubs=None, dataclass_registry=None))]
66
- fn new(
67
- py: Python<'_>,
68
- code: String,
69
- script_name: &str,
70
- inputs: Option<&Bound<'_, PyList>>,
71
- type_check: bool,
72
- type_check_stubs: Option<&str>,
73
- dataclass_registry: Option<&Bound<'_, PyList>>,
74
- ) -> PyResult<Self> {
75
- let input_names = list_str(inputs, "inputs")?;
76
-
77
- if type_check {
78
- py_type_check(py, &code, script_name, type_check_stubs)?;
79
- }
80
-
81
- // Create the snapshot (parses the code)
82
- let runner = MontyRun::new(code, script_name, input_names.clone()).map_err(|e| MontyError::new_err(py, e))?;
83
-
84
- Ok(Self {
85
- runner,
86
- script_name: script_name.to_string(),
87
- input_names,
88
- dc_registry: DcRegistry::from_list(py, dataclass_registry)?,
89
- })
90
- }
91
-
92
- /// Registers a dataclass type for proper isinstance() support on output.
93
- ///
94
- /// When a dataclass passes through Monty and is returned, it becomes a `MontyDataclass`.
95
- /// By registering the original type, `isinstance(result, OriginalClass)` will return `True`.
96
- ///
97
- /// # Arguments
98
- /// * `cls` - The dataclass type to register
99
- ///
100
- /// # Raises
101
- /// * `TypeError` if the argument is not a dataclass type
102
- fn register_dataclass(&self, cls: &Bound<'_, PyType>) -> PyResult<()> {
103
- self.dc_registry.insert(cls)
104
- }
105
-
106
- /// Performs static type checking on the code.
107
- ///
108
- /// Analyzes the code for type errors without executing it. This uses
109
- /// a subset of Python's type system supported by Monty.
110
- ///
111
- /// # Args
112
- /// * `prefix_code` - Optional prefix to prepend to the code before type checking,
113
- /// e.g. with inputs and external function signatures
114
- ///
115
- /// # Raises
116
- /// * `RuntimeError` if type checking infrastructure fails
117
- /// * `MontyTypingError` if type errors are found
118
- #[pyo3(signature = (prefix_code=None))]
119
- fn type_check(&self, py: Python<'_>, prefix_code: Option<&str>) -> PyResult<()> {
120
- py_type_check(py, self.runner.code(), &self.script_name, prefix_code)
121
- }
122
-
123
- /// Executes the code and returns the result.
124
- ///
125
- /// # Returns
126
- /// The result of the last expression in the code
127
- ///
128
- /// # Raises
129
- /// Various Python exceptions matching what the code would raise
130
- #[pyo3(signature = (*, inputs=None, limits=None, external_functions=None, print_callback=None, os=None))]
131
- fn run(
132
- &self,
133
- py: Python<'_>,
134
- inputs: Option<&Bound<'_, PyDict>>,
135
- limits: Option<&Bound<'_, PyDict>>,
136
- external_functions: Option<&Bound<'_, PyDict>>,
137
- print_callback: Option<&Bound<'_, PyAny>>,
138
- os: Option<&Bound<'_, PyAny>>,
139
- ) -> PyResult<Py<PyAny>> {
140
- // Clone the Arc handle — all clones share the same underlying registry,
141
- // so auto-registrations during execution are visible to all users.
142
- let input_values = self.extract_input_values(inputs, &self.dc_registry)?;
143
-
144
- if let Some(os_callback) = os
145
- && !os_callback.is_callable()
146
- {
147
- let msg = format!("TypeError: '{}' object is not callable", os_callback.get_type().name()?);
148
- return Err(PyTypeError::new_err(msg));
149
- }
150
-
151
- // Build print writer
152
- let mut print_cb;
153
- let print_writer = match print_callback {
154
- Some(cb) => {
155
- print_cb = CallbackStringPrint::new(cb);
156
- PrintWriter::Callback(&mut print_cb)
157
- }
158
- None => PrintWriter::Stdout,
159
- };
160
-
161
- // Run with appropriate tracker type (must branch due to different generic types)
162
- if let Some(limits) = limits {
163
- let tracker = PySignalTracker::new(LimitedTracker::new(extract_limits(limits)?));
164
- self.run_impl(py, input_values, tracker, external_functions, os, print_writer)
165
- } else {
166
- let tracker = PySignalTracker::new(NoLimitTracker);
167
- self.run_impl(py, input_values, tracker, external_functions, os, print_writer)
168
- }
169
- }
170
-
171
- #[pyo3(signature = (*, inputs=None, limits=None, print_callback=None))]
172
- fn start<'py>(
173
- &self,
174
- py: Python<'py>,
175
- inputs: Option<&Bound<'py, PyDict>>,
176
- limits: Option<&Bound<'py, PyDict>>,
177
- print_callback: Option<Bound<'_, PyAny>>,
178
- ) -> PyResult<Bound<'py, PyAny>> {
179
- // Clone the Arc handle — shares the same underlying registry
180
- let dc_registry = self.dc_registry.clone_ref(py);
181
- let input_values = self.extract_input_values(inputs, &dc_registry)?;
182
-
183
- // Build print writer - CallbackStringPrint is Send so GIL can be released
184
- let mut print_cb;
185
- let print_writer = match &print_callback {
186
- Some(cb) => {
187
- print_cb = CallbackStringPrint::new(cb);
188
- PrintWriter::Callback(&mut print_cb)
189
- }
190
- None => PrintWriter::Stdout,
191
- };
192
-
193
- let runner = self.runner.clone();
194
- let print_writer = SendWrapper::new(print_writer);
195
-
196
- // Helper macro to start execution with GIL released
197
- macro_rules! start_impl {
198
- ($tracker:expr) => {{
199
- py.detach(|| runner.start(input_values, $tracker, print_writer.take()))
200
- .map_err(|e| MontyError::new_err(py, e))?
201
- }};
202
- }
203
-
204
- // Branch on limits (different generic types)
205
- let progress = if let Some(limits) = limits {
206
- let tracker = PySignalTracker::new(LimitedTracker::new(extract_limits(limits)?));
207
- EitherProgress::Limited(start_impl!(tracker))
208
- } else {
209
- let tracker = PySignalTracker::new(NoLimitTracker);
210
- EitherProgress::NoLimit(start_impl!(tracker))
211
- };
212
- progress.progress_or_complete(
213
- py,
214
- self.script_name.clone(),
215
- print_callback.map(Bound::unbind),
216
- dc_registry,
217
- )
218
- }
219
-
220
- /// Serializes the Monty instance to a binary format.
221
- ///
222
- /// The serialized data can be stored and later restored with `Monty.load()`.
223
- /// This allows caching parsed code to avoid re-parsing on subsequent runs.
224
- ///
225
- /// # Returns
226
- /// Bytes containing the serialized Monty instance.
227
- ///
228
- /// # Raises
229
- /// `ValueError` if serialization fails.
230
- fn dump<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
231
- let serialized = SerializedMonty {
232
- runner: self.runner.clone(),
233
- script_name: self.script_name.clone(),
234
- input_names: self.input_names.clone(),
235
- };
236
- let bytes = postcard::to_allocvec(&serialized).map_err(|e| PyValueError::new_err(e.to_string()))?;
237
- Ok(PyBytes::new(py, &bytes))
238
- }
239
-
240
- /// Deserializes a Monty instance from binary format.
241
- ///
242
- /// # Arguments
243
- /// * `data` - The serialized Monty data from `dump()`
244
- /// * `dataclass_registry` - Optional list of dataclasses to register
245
- ///
246
- /// # Returns
247
- /// A new Monty instance.
248
- ///
249
- /// # Raises
250
- /// `ValueError` if deserialization fails.
251
- #[staticmethod]
252
- #[pyo3(signature = (data, *, dataclass_registry=None))]
253
- fn load(
254
- py: Python<'_>,
255
- data: &Bound<'_, PyBytes>,
256
- dataclass_registry: Option<&Bound<'_, PyList>>,
257
- ) -> PyResult<Self> {
258
- let bytes = data.as_bytes();
259
- let serialized: SerializedMonty =
260
- postcard::from_bytes(bytes).map_err(|e| PyValueError::new_err(e.to_string()))?;
261
-
262
- Ok(Self {
263
- runner: serialized.runner,
264
- script_name: serialized.script_name,
265
- input_names: serialized.input_names,
266
- dc_registry: DcRegistry::from_list(py, dataclass_registry)?,
267
- })
268
- }
269
-
270
- fn __repr__(&self) -> String {
271
- let lines = self.runner.code().lines().count();
272
- let mut s = format!(
273
- "Monty(<{} line{} of code>, script_name='{}'",
274
- lines,
275
- if lines == 1 { "" } else { "s" },
276
- self.script_name
277
- );
278
- if !self.input_names.is_empty() {
279
- write!(s, ", inputs={:?}", self.input_names).unwrap();
280
- }
281
- s.push(')');
282
- s
283
- }
284
- }
285
-
286
- fn py_type_check(py: Python<'_>, code: &str, script_name: &str, type_stubs: Option<&str>) -> PyResult<()> {
287
- let type_stubs = type_stubs.map(|type_stubs| SourceFile::new(type_stubs, "type_stubs.pyi"));
288
-
289
- let opt_diagnostics =
290
- type_check(&SourceFile::new(code, script_name), type_stubs.as_ref()).map_err(PyRuntimeError::new_err)?;
291
-
292
- if let Some(diagnostic) = opt_diagnostics {
293
- Err(MontyTypingError::new_err(py, diagnostic))
294
- } else {
295
- Ok(())
296
- }
297
- }
298
-
299
- impl PyMonty {
300
- /// Extracts input values from a Python dict in the order they were declared.
301
- ///
302
- /// Validates that all required inputs are provided. Any dataclass inputs are
303
- /// automatically registered in `dc_registry` via `py_to_monty` so they can be
304
- /// properly reconstructed on output.
305
- fn extract_input_values(
306
- &self,
307
- inputs: Option<&Bound<'_, PyDict>>,
308
- dc_registry: &DcRegistry,
309
- ) -> PyResult<Vec<::monty::MontyObject>> {
310
- if self.input_names.is_empty() {
311
- if inputs.is_some() {
312
- return Err(PyTypeError::new_err(
313
- "No input variables declared but inputs dict was provided",
314
- ));
315
- }
316
- return Ok(vec![]);
317
- }
318
-
319
- let Some(inputs) = inputs else {
320
- return Err(PyTypeError::new_err(format!(
321
- "Missing required inputs: {:?}",
322
- self.input_names
323
- )));
324
- };
325
-
326
- // Extract values in declaration order
327
- self.input_names
328
- .iter()
329
- .map(|name| {
330
- let value = inputs
331
- .get_item(name)?
332
- .ok_or_else(|| PyKeyError::new_err(format!("Missing required input: '{name}'")))?;
333
- py_to_monty(&value, dc_registry)
334
- })
335
- .collect::<PyResult<_>>()
336
- }
337
-
338
- /// Runs code with a generic resource tracker, releasing the GIL during execution.
339
- ///
340
- /// Takes explicit field references instead of `&mut self` so that `run()` can
341
- /// remain `&self` (required for concurrent thread access in PyO3).
342
- fn run_impl(
343
- &self,
344
- py: Python<'_>,
345
- input_values: Vec<MontyObject>,
346
- tracker: impl ResourceTracker + Send,
347
- external_functions: Option<&Bound<'_, PyDict>>,
348
- os: Option<&Bound<'_, PyAny>>,
349
- print_output: PrintWriter<'_>,
350
- ) -> PyResult<Py<PyAny>> {
351
- // wrap print_output in SendWrapper so that it can be accessed inside the py.detach calls despite
352
- // no `Send` bound - py.detach() is overly restrictive to prevent `Bound` types going inside
353
- let mut print_output = SendWrapper::new(print_output);
354
-
355
- // Check if any inputs contain dataclasses (including nested in containers) —
356
- // if so, we need the iterative path because method calls could happen lazily
357
- // and need to be dispatched to the host.
358
- let has_dataclass_inputs = || input_values.iter().any(contains_dataclass);
359
-
360
- if external_functions.is_none() && os.is_none() && !has_dataclass_inputs() {
361
- return match py.detach(|| self.runner.run(input_values, tracker, print_output.reborrow())) {
362
- Ok(v) => monty_to_py(py, &v, &self.dc_registry),
363
- Err(err) => Err(MontyError::new_err(py, err)),
364
- };
365
- }
366
- // Clone the runner since start() consumes it - allows reuse of the parsed code
367
- let runner = self.runner.clone();
368
- let mut progress = py
369
- .detach(|| runner.start(input_values, tracker, print_output.reborrow()))
370
- .map_err(|e| MontyError::new_err(py, e))?;
371
-
372
- loop {
373
- match progress {
374
- RunProgress::Complete(result) => return monty_to_py(py, &result, &self.dc_registry),
375
- RunProgress::FunctionCall(call) => {
376
- // Dataclass method calls have method_call=true and the first arg is the instance
377
- let return_value = if call.method_call {
378
- dispatch_method_call(py, &call.function_name, &call.args, &call.kwargs, &self.dc_registry)
379
- } else if let Some(ext_fns) = external_functions {
380
- let registry = ExternalFunctionRegistry::new(py, ext_fns, &self.dc_registry);
381
- registry.call(&call.function_name, &call.args, &call.kwargs)
382
- } else {
383
- return Err(PyRuntimeError::new_err(format!(
384
- "External function '{}' called but no external_functions provided",
385
- call.function_name
386
- )));
387
- };
388
-
389
- progress = py
390
- .detach(|| call.resume(return_value, print_output.reborrow()))
391
- .map_err(|e| MontyError::new_err(py, e))?;
392
- }
393
- RunProgress::NameLookup(lookup) => {
394
- let result = if let Some(ext_fns) = external_functions
395
- && let Some(value) = ext_fns.get_item(&lookup.name)?
396
- {
397
- NameLookupResult::Value(MontyObject::Function {
398
- name: lookup.name.clone(),
399
- docstring: get_docstring(&value),
400
- })
401
- } else {
402
- NameLookupResult::Undefined
403
- };
404
-
405
- progress = py
406
- .detach(|| lookup.resume(result, print_output.reborrow()))
407
- .map_err(|e| MontyError::new_err(py, e))?;
408
- }
409
- RunProgress::ResolveFutures(_) => {
410
- return Err(PyRuntimeError::new_err("async futures not supported with `Monty.run`"));
411
- }
412
- RunProgress::OsCall(call) => {
413
- let result: ExtFunctionResult = if let Some(os_callback) = os {
414
- // Convert args to Python
415
- let py_args: Vec<Py<PyAny>> = call
416
- .args
417
- .iter()
418
- .map(|arg| monty_to_py(py, arg, &self.dc_registry))
419
- .collect::<PyResult<_>>()?;
420
- let py_args_tuple = PyTuple::new(py, py_args)?;
421
-
422
- // Convert kwargs to Python dict
423
- let py_kwargs = PyDict::new(py);
424
- for (k, v) in &call.kwargs {
425
- py_kwargs.set_item(
426
- monty_to_py(py, k, &self.dc_registry)?,
427
- monty_to_py(py, v, &self.dc_registry)?,
428
- )?;
429
- }
430
-
431
- // call the os callback, if an exception is raised, return it to monty
432
- match os_callback.call1((call.function.to_string(), py_args_tuple, py_kwargs)) {
433
- Ok(result) => py_to_monty(&result, &self.dc_registry)?.into(),
434
- Err(err) => exc_py_to_monty(py, &err).into(),
435
- }
436
- } else {
437
- MontyException::new(
438
- ExcType::NotImplementedError,
439
- Some(format!("OS function '{}' not implemented", call.function)),
440
- )
441
- .into()
442
- };
443
-
444
- progress = py
445
- .detach(|| call.resume(result, print_output.reborrow()))
446
- .map_err(|e| MontyError::new_err(py, e))?;
447
- }
448
- }
449
- }
450
- }
451
- }
452
-
453
- /// pyclass doesn't support generic types, hence hard coding the generics
454
- #[derive(Debug)]
455
- pub(crate) enum EitherProgress {
456
- NoLimit(RunProgress<PySignalTracker<NoLimitTracker>>),
457
- Limited(RunProgress<PySignalTracker<LimitedTracker>>),
458
- /// REPL progress with back-reference to the owning `PyMontyRepl` for auto-restore.
459
- ReplNoLimit(ReplProgress<PySignalTracker<NoLimitTracker>>, Py<PyMontyRepl>),
460
- /// REPL progress with back-reference to the owning `PyMontyRepl` for auto-restore.
461
- ReplLimited(ReplProgress<PySignalTracker<LimitedTracker>>, Py<PyMontyRepl>),
462
- }
463
-
464
- impl EitherProgress {
465
- /// Converts progress into the appropriate Python object:
466
- /// function snapshot, name lookup snapshot, future snapshot, or complete.
467
- pub(crate) fn progress_or_complete(
468
- self,
469
- py: Python<'_>,
470
- script_name: String,
471
- print_callback: Option<Py<PyAny>>,
472
- dc_registry: DcRegistry,
473
- ) -> PyResult<Bound<'_, PyAny>> {
474
- match self {
475
- Self::NoLimit(p) => run_progress_to_py(py, p, script_name, print_callback, dc_registry),
476
- Self::Limited(p) => run_progress_to_py(py, p, script_name, print_callback, dc_registry),
477
- Self::ReplNoLimit(p, owner) => repl_progress_to_py(py, p, script_name, print_callback, dc_registry, owner),
478
- Self::ReplLimited(p, owner) => repl_progress_to_py(py, p, script_name, print_callback, dc_registry, owner),
479
- }
480
- }
481
- }
482
-
483
- /// Converts a `RunProgress<T>` into the appropriate Python snapshot type.
484
- fn run_progress_to_py<T: ResourceTracker>(
485
- py: Python<'_>,
486
- progress: RunProgress<T>,
487
- script_name: String,
488
- print_callback: Option<Py<PyAny>>,
489
- dc_registry: DcRegistry,
490
- ) -> PyResult<Bound<'_, PyAny>>
491
- where
492
- EitherFunctionSnapshot: FromFunctionCall<T> + FromOsCall<T>,
493
- EitherLookupSnapshot: FromNameLookup<T>,
494
- EitherFutureSnapshot: FromResolveFutures<T>,
495
- {
496
- match progress {
497
- RunProgress::Complete(result) => PyMontyComplete::create(py, &result, &dc_registry),
498
- RunProgress::FunctionCall(call) => {
499
- PyFunctionSnapshot::function_call(py, call, script_name, print_callback, dc_registry)
500
- }
501
- RunProgress::OsCall(call) => PyFunctionSnapshot::os_call(py, call, script_name, print_callback, dc_registry),
502
- RunProgress::ResolveFutures(state) => {
503
- PyFutureSnapshot::new_py_any(py, state, script_name, print_callback, dc_registry)
504
- }
505
- RunProgress::NameLookup(lookup) => {
506
- PyNameLookupSnapshot::new_py_any(py, lookup, script_name, print_callback, dc_registry)
507
- }
508
- }
509
- }
510
-
511
- /// Converts a `ReplProgress<T>` into the appropriate Python snapshot type.
512
- ///
513
- /// On completion, restores the REPL state into `repl_owner` before returning `MontyComplete`.
514
- /// The `repl_owner` is propagated into snapshot enum variants so the chain can continue.
515
- fn repl_progress_to_py<T: ResourceTracker>(
516
- py: Python<'_>,
517
- progress: ReplProgress<T>,
518
- script_name: String,
519
- print_callback: Option<Py<PyAny>>,
520
- dc_registry: DcRegistry,
521
- repl_owner: Py<PyMontyRepl>,
522
- ) -> PyResult<Bound<'_, PyAny>>
523
- where
524
- EitherFunctionSnapshot: FromReplFunctionCall<T> + FromReplOsCall<T>,
525
- EitherLookupSnapshot: FromReplNameLookup<T>,
526
- EitherFutureSnapshot: FromReplResolveFutures<T>,
527
- EitherRepl: FromCoreRepl<T>,
528
- {
529
- match progress {
530
- ReplProgress::Complete { repl, value } => {
531
- repl_owner.get().put_repl(EitherRepl::from_core(repl));
532
- PyMontyComplete::create(py, &value, &dc_registry)
533
- }
534
- ReplProgress::FunctionCall(call) => {
535
- PyFunctionSnapshot::repl_function_call(py, call, script_name, print_callback, dc_registry, repl_owner)
536
- }
537
- ReplProgress::OsCall(call) => {
538
- PyFunctionSnapshot::repl_os_call(py, call, script_name, print_callback, dc_registry, repl_owner)
539
- }
540
- ReplProgress::NameLookup(lookup) => {
541
- let variable_name = lookup.name.clone();
542
- PyNameLookupSnapshot::repl_name_lookup(
543
- py,
544
- lookup,
545
- script_name,
546
- print_callback,
547
- dc_registry,
548
- repl_owner,
549
- variable_name,
550
- )
551
- }
552
- ReplProgress::ResolveFutures(state) => {
553
- PyFutureSnapshot::repl_resolve_futures(py, state, script_name, print_callback, dc_registry, repl_owner)
554
- }
555
- }
556
- }
557
-
558
- /// Runtime execution snapshot, holds either a `FunctionCall` or `OsCall` for both
559
- /// resource tracker variants since pyclass structs can't be generic.
560
- ///
561
- /// Also holds REPL variants (`ReplFunctionCall`, `ReplOsCall`) for `MontyRepl.feed_start()`.
562
- /// REPL variants carry a `Py<PyMontyRepl>` back-reference so the REPL can be auto-restored
563
- /// on completion or error.
564
- ///
565
- /// Used internally by `PyFunctionSnapshot` to store execution state. Both `FunctionCall`
566
- /// and `OsCall` have the same `resume()` signature, so we dispatch to the appropriate
567
- /// inner type based on the variant.
568
- ///
569
- /// The `Done` variant indicates the snapshot has been consumed.
570
- ///
571
- /// Serde: REPL variants serialize as their non-REPL counterparts (stripping the owner).
572
- /// Deserialization always produces non-REPL variants.
573
- #[derive(Debug)]
574
- pub(crate) enum EitherFunctionSnapshot {
575
- // Run variants (from Monty.start())
576
- NoLimitFn(FunctionCall<PySignalTracker<NoLimitTracker>>),
577
- NoLimitOs(OsCall<PySignalTracker<NoLimitTracker>>),
578
- LimitedFn(FunctionCall<PySignalTracker<LimitedTracker>>),
579
- LimitedOs(OsCall<PySignalTracker<LimitedTracker>>),
580
- // REPL variants (from MontyRepl.feed_start()) — carry the REPL owner
581
- ReplNoLimitFn(ReplFunctionCall<PySignalTracker<NoLimitTracker>>, Py<PyMontyRepl>),
582
- ReplNoLimitOs(ReplOsCall<PySignalTracker<NoLimitTracker>>, Py<PyMontyRepl>),
583
- ReplLimitedFn(ReplFunctionCall<PySignalTracker<LimitedTracker>>, Py<PyMontyRepl>),
584
- ReplLimitedOs(ReplOsCall<PySignalTracker<LimitedTracker>>, Py<PyMontyRepl>),
585
- /// Sentinel indicating the snapshot has been consumed via `resume()`.
586
- Done,
587
- }
588
-
589
- /// Helper trait for wrapping `FunctionCall<T>` into `EitherFunctionSnapshot`.
590
- trait FromFunctionCall<T: ResourceTracker> {
591
- /// Wraps a function call into the appropriate variant.
592
- fn from_fn(call: FunctionCall<T>) -> Self;
593
- }
594
-
595
- impl FromFunctionCall<PySignalTracker<NoLimitTracker>> for EitherFunctionSnapshot {
596
- fn from_fn(call: FunctionCall<PySignalTracker<NoLimitTracker>>) -> Self {
597
- Self::NoLimitFn(call)
598
- }
599
- }
600
-
601
- impl FromFunctionCall<PySignalTracker<LimitedTracker>> for EitherFunctionSnapshot {
602
- fn from_fn(call: FunctionCall<PySignalTracker<LimitedTracker>>) -> Self {
603
- Self::LimitedFn(call)
604
- }
605
- }
606
-
607
- /// Helper trait for wrapping `OsCall<T>` into `EitherFunctionSnapshot`.
608
- trait FromOsCall<T: ResourceTracker> {
609
- /// Wraps an OS call into the appropriate variant.
610
- fn from_os(call: OsCall<T>) -> Self;
611
- }
612
-
613
- impl FromOsCall<PySignalTracker<NoLimitTracker>> for EitherFunctionSnapshot {
614
- fn from_os(call: OsCall<PySignalTracker<NoLimitTracker>>) -> Self {
615
- Self::NoLimitOs(call)
616
- }
617
- }
618
-
619
- impl FromOsCall<PySignalTracker<LimitedTracker>> for EitherFunctionSnapshot {
620
- fn from_os(call: OsCall<PySignalTracker<LimitedTracker>>) -> Self {
621
- Self::LimitedOs(call)
622
- }
623
- }
624
-
625
- /// Helper trait for wrapping `ReplFunctionCall<T>` into `EitherFunctionSnapshot`.
626
- trait FromReplFunctionCall<T: ResourceTracker> {
627
- /// Wraps a REPL function call into the appropriate variant.
628
- fn from_repl_fn(call: ReplFunctionCall<T>, owner: Py<PyMontyRepl>) -> Self;
629
- }
630
-
631
- impl FromReplFunctionCall<PySignalTracker<NoLimitTracker>> for EitherFunctionSnapshot {
632
- fn from_repl_fn(call: ReplFunctionCall<PySignalTracker<NoLimitTracker>>, owner: Py<PyMontyRepl>) -> Self {
633
- Self::ReplNoLimitFn(call, owner)
634
- }
635
- }
636
-
637
- impl FromReplFunctionCall<PySignalTracker<LimitedTracker>> for EitherFunctionSnapshot {
638
- fn from_repl_fn(call: ReplFunctionCall<PySignalTracker<LimitedTracker>>, owner: Py<PyMontyRepl>) -> Self {
639
- Self::ReplLimitedFn(call, owner)
640
- }
641
- }
642
-
643
- /// Helper trait for wrapping `ReplOsCall<T>` into `EitherFunctionSnapshot`.
644
- trait FromReplOsCall<T: ResourceTracker> {
645
- /// Wraps a REPL OS call into the appropriate variant.
646
- fn from_repl_os(call: ReplOsCall<T>, owner: Py<PyMontyRepl>) -> Self;
647
- }
648
-
649
- impl FromReplOsCall<PySignalTracker<NoLimitTracker>> for EitherFunctionSnapshot {
650
- fn from_repl_os(call: ReplOsCall<PySignalTracker<NoLimitTracker>>, owner: Py<PyMontyRepl>) -> Self {
651
- Self::ReplNoLimitOs(call, owner)
652
- }
653
- }
654
-
655
- impl FromReplOsCall<PySignalTracker<LimitedTracker>> for EitherFunctionSnapshot {
656
- fn from_repl_os(call: ReplOsCall<PySignalTracker<LimitedTracker>>, owner: Py<PyMontyRepl>) -> Self {
657
- Self::ReplLimitedOs(call, owner)
658
- }
659
- }
660
-
661
- /// Snapshot generated during execution when monty yields to the host for a function call.
662
- #[pyclass(name = "FunctionSnapshot", module = "pydantic_monty")]
663
- #[derive(Debug)]
664
- pub struct PyFunctionSnapshot {
665
- snapshot: Mutex<EitherFunctionSnapshot>,
666
- print_callback: Option<Py<PyAny>>,
667
- dc_registry: DcRegistry,
668
-
669
- /// Name of the script being executed
670
- #[pyo3(get)]
671
- pub script_name: String,
672
-
673
- /// Whether this call refers to an OS function
674
- #[pyo3(get)]
675
- pub is_os_function: bool,
676
-
677
- /// Whether this call is a dataclass method call (first arg is `self`)
678
- #[pyo3(get)]
679
- pub is_method_call: bool,
680
-
681
- /// The name of the function being called.
682
- #[pyo3(get)]
683
- pub function_name: String,
684
- /// The positional arguments passed to the function.
685
- #[pyo3(get)]
686
- pub args: Py<PyTuple>,
687
- /// The keyword arguments passed to the function (key, value pairs).
688
- #[pyo3(get)]
689
- pub kwargs: Py<PyDict>,
690
- /// The unique identifier for this call
691
- #[pyo3(get)]
692
- pub call_id: u32,
693
- }
694
-
695
- impl PyFunctionSnapshot {
696
- /// Creates a `PyFunctionSnapshot` for an external function call.
697
- ///
698
- /// Extracts display fields from the `FunctionCall` before moving it into
699
- /// `EitherSnapshot` via the provided `wrap` closure.
700
- fn function_call<T: ResourceTracker>(
701
- py: Python<'_>,
702
- call: FunctionCall<T>,
703
- script_name: String,
704
- print_callback: Option<Py<PyAny>>,
705
- dc_registry: DcRegistry,
706
- ) -> PyResult<Bound<'_, PyAny>>
707
- where
708
- EitherFunctionSnapshot: FromFunctionCall<T>,
709
- {
710
- let function_name = call.function_name.clone();
711
- let call_id = call.call_id;
712
- let method_call = call.method_call;
713
- let items: PyResult<Vec<Py<PyAny>>> = call
714
- .args
715
- .iter()
716
- .map(|item| monty_to_py(py, item, &dc_registry))
717
- .collect();
718
- let dict = PyDict::new(py);
719
- for (k, v) in &call.kwargs {
720
- dict.set_item(monty_to_py(py, k, &dc_registry)?, monty_to_py(py, v, &dc_registry)?)?;
721
- }
722
-
723
- let slf = Self {
724
- snapshot: Mutex::new(EitherFunctionSnapshot::from_fn(call)),
725
- print_callback,
726
- script_name,
727
- is_os_function: false,
728
- is_method_call: method_call,
729
- function_name,
730
- args: PyTuple::new(py, items?)?.unbind(),
731
- kwargs: dict.unbind(),
732
- call_id,
733
- dc_registry,
734
- };
735
- slf.into_bound_py_any(py)
736
- }
737
-
738
- /// Creates a `PyFunctionSnapshot` for an OS-level call.
739
- ///
740
- /// Extracts display fields from the `OsCall` before moving it into
741
- /// `EitherSnapshot` via the provided `wrap` closure.
742
- fn os_call<T: ResourceTracker>(
743
- py: Python<'_>,
744
- call: OsCall<T>,
745
- script_name: String,
746
- print_callback: Option<Py<PyAny>>,
747
- dc_registry: DcRegistry,
748
- ) -> PyResult<Bound<'_, PyAny>>
749
- where
750
- EitherFunctionSnapshot: FromOsCall<T>,
751
- {
752
- let function_name = call.function.to_string();
753
- let call_id = call.call_id;
754
- let items: PyResult<Vec<Py<PyAny>>> = call
755
- .args
756
- .iter()
757
- .map(|item| monty_to_py(py, item, &dc_registry))
758
- .collect();
759
- let dict = PyDict::new(py);
760
- for (k, v) in &call.kwargs {
761
- dict.set_item(monty_to_py(py, k, &dc_registry)?, monty_to_py(py, v, &dc_registry)?)?;
762
- }
763
-
764
- let slf = Self {
765
- snapshot: Mutex::new(EitherFunctionSnapshot::from_os(call)),
766
- print_callback,
767
- script_name,
768
- is_os_function: true,
769
- is_method_call: false,
770
- function_name,
771
- args: PyTuple::new(py, items?)?.unbind(),
772
- kwargs: dict.unbind(),
773
- call_id,
774
- dc_registry,
775
- };
776
- slf.into_bound_py_any(py)
777
- }
778
-
779
- /// Creates a `PyFunctionSnapshot` for a REPL external function call.
780
- fn repl_function_call<T: ResourceTracker>(
781
- py: Python<'_>,
782
- call: ReplFunctionCall<T>,
783
- script_name: String,
784
- print_callback: Option<Py<PyAny>>,
785
- dc_registry: DcRegistry,
786
- repl_owner: Py<PyMontyRepl>,
787
- ) -> PyResult<Bound<'_, PyAny>>
788
- where
789
- EitherFunctionSnapshot: FromReplFunctionCall<T>,
790
- {
791
- let function_name = call.function_name.clone();
792
- let call_id = call.call_id;
793
- let method_call = call.method_call;
794
- let items: PyResult<Vec<Py<PyAny>>> = call
795
- .args
796
- .iter()
797
- .map(|item| monty_to_py(py, item, &dc_registry))
798
- .collect();
799
- let dict = PyDict::new(py);
800
- for (k, v) in &call.kwargs {
801
- dict.set_item(monty_to_py(py, k, &dc_registry)?, monty_to_py(py, v, &dc_registry)?)?;
802
- }
803
-
804
- let slf = Self {
805
- snapshot: Mutex::new(EitherFunctionSnapshot::from_repl_fn(call, repl_owner)),
806
- print_callback,
807
- script_name,
808
- is_os_function: false,
809
- is_method_call: method_call,
810
- function_name,
811
- args: PyTuple::new(py, items?)?.unbind(),
812
- kwargs: dict.unbind(),
813
- call_id,
814
- dc_registry,
815
- };
816
- slf.into_bound_py_any(py)
817
- }
818
-
819
- /// Creates a `PyFunctionSnapshot` for a REPL OS-level call.
820
- fn repl_os_call<T: ResourceTracker>(
821
- py: Python<'_>,
822
- call: ReplOsCall<T>,
823
- script_name: String,
824
- print_callback: Option<Py<PyAny>>,
825
- dc_registry: DcRegistry,
826
- repl_owner: Py<PyMontyRepl>,
827
- ) -> PyResult<Bound<'_, PyAny>>
828
- where
829
- EitherFunctionSnapshot: FromReplOsCall<T>,
830
- {
831
- let function_name = call.function.to_string();
832
- let call_id = call.call_id;
833
- let items: PyResult<Vec<Py<PyAny>>> = call
834
- .args
835
- .iter()
836
- .map(|item| monty_to_py(py, item, &dc_registry))
837
- .collect();
838
- let dict = PyDict::new(py);
839
- for (k, v) in &call.kwargs {
840
- dict.set_item(monty_to_py(py, k, &dc_registry)?, monty_to_py(py, v, &dc_registry)?)?;
841
- }
842
-
843
- let slf = Self {
844
- snapshot: Mutex::new(EitherFunctionSnapshot::from_repl_os(call, repl_owner)),
845
- print_callback,
846
- script_name,
847
- is_os_function: true,
848
- is_method_call: false,
849
- function_name,
850
- args: PyTuple::new(py, items?)?.unbind(),
851
- kwargs: dict.unbind(),
852
- call_id,
853
- dc_registry,
854
- };
855
- slf.into_bound_py_any(py)
856
- }
857
-
858
- /// Constructs a `PyFunctionSnapshot` from deserialized parts.
859
- ///
860
- /// Used by `load_snapshot` and `load_repl_snapshot` to reconstruct snapshot objects.
861
- #[expect(clippy::too_many_arguments)]
862
- pub(crate) fn from_deserialized(
863
- py: Python<'_>,
864
- snapshot: EitherFunctionSnapshot,
865
- print_callback: Option<Py<PyAny>>,
866
- dc_registry: DcRegistry,
867
- script_name: String,
868
- is_os_function: bool,
869
- is_method_call: bool,
870
- function_name: String,
871
- args: Py<PyTuple>,
872
- kwargs: Py<PyDict>,
873
- call_id: u32,
874
- ) -> PyResult<Bound<'_, PyAny>> {
875
- let slf = Self {
876
- snapshot: Mutex::new(snapshot),
877
- print_callback,
878
- dc_registry,
879
- script_name,
880
- is_os_function,
881
- is_method_call,
882
- function_name,
883
- args,
884
- kwargs,
885
- call_id,
886
- };
887
- slf.into_bound_py_any(py)
888
- }
889
- }
890
-
891
- #[pymethods]
892
- impl PyFunctionSnapshot {
893
- /// Resumes execution with either a return value, exception or future.
894
- ///
895
- /// Exactly one of `return_value`, `exception` or `future` must be provided as a keyword argument.
896
- ///
897
- /// # Raises
898
- /// * `TypeError` if both arguments are provided, or neither
899
- /// * `RuntimeError` if the snapshot has already been resumed
900
- #[pyo3(signature = (**kwargs))]
901
- pub fn resume<'py>(&self, py: Python<'py>, kwargs: Option<&Bound<'_, PyDict>>) -> PyResult<Bound<'py, PyAny>> {
902
- const ARGS_ERROR: &str = "resume() accepts either return_value or exception, not both";
903
-
904
- let mut snapshot = self
905
- .snapshot
906
- .lock()
907
- .map_err(|_| PyRuntimeError::new_err("Snapshot is currently being resumed by another thread"))?;
908
-
909
- let snapshot = std::mem::replace(&mut *snapshot, EitherFunctionSnapshot::Done);
910
- let Some(kwargs) = kwargs else {
911
- return Err(PyTypeError::new_err(ARGS_ERROR));
912
- };
913
- let external_result = extract_external_result(py, kwargs, ARGS_ERROR, &self.dc_registry, self.call_id)?;
914
-
915
- // Build print writer before detaching - clone_ref needs py token
916
- let mut print_cb;
917
- let print_writer = match &self.print_callback {
918
- Some(cb) => {
919
- print_cb = CallbackStringPrint::from_py(cb.clone_ref(py));
920
- PrintWriter::Callback(&mut print_cb)
921
- }
922
- None => PrintWriter::Stdout,
923
- };
924
- // wrap print_writer in SendWrapper so that it can be accessed inside the py.detach calls despite
925
- // no `Send` bound - py.detach() is overly restrictive to prevent `Bound` types going inside
926
- let mut print_writer = SendWrapper::new(print_writer);
927
-
928
- let progress = match snapshot {
929
- EitherFunctionSnapshot::NoLimitFn(call) => {
930
- let result = py.detach(|| call.resume(external_result, print_writer.reborrow()));
931
- EitherProgress::NoLimit(result.map_err(|e| MontyError::new_err(py, e))?)
932
- }
933
- EitherFunctionSnapshot::NoLimitOs(call) => {
934
- let result = py.detach(|| call.resume(external_result, print_writer.reborrow()));
935
- EitherProgress::NoLimit(result.map_err(|e| MontyError::new_err(py, e))?)
936
- }
937
- EitherFunctionSnapshot::LimitedFn(call) => {
938
- let result = py.detach(|| call.resume(external_result, print_writer.reborrow()));
939
- EitherProgress::Limited(result.map_err(|e| MontyError::new_err(py, e))?)
940
- }
941
- EitherFunctionSnapshot::LimitedOs(call) => {
942
- let result = py.detach(|| call.resume(external_result, print_writer.reborrow()));
943
- EitherProgress::Limited(result.map_err(|e| MontyError::new_err(py, e))?)
944
- }
945
- EitherFunctionSnapshot::ReplNoLimitFn(call, owner) => {
946
- let result = py
947
- .detach(|| call.resume(external_result, print_writer.reborrow()))
948
- .map_err(|e| restore_repl_from_repl_start_error(py, &owner, *e))?;
949
- EitherProgress::ReplNoLimit(result, owner)
950
- }
951
- EitherFunctionSnapshot::ReplNoLimitOs(call, owner) => {
952
- let result = py
953
- .detach(|| call.resume(external_result, print_writer.reborrow()))
954
- .map_err(|e| restore_repl_from_repl_start_error(py, &owner, *e))?;
955
- EitherProgress::ReplNoLimit(result, owner)
956
- }
957
- EitherFunctionSnapshot::ReplLimitedFn(call, owner) => {
958
- let result = py
959
- .detach(|| call.resume(external_result, print_writer.reborrow()))
960
- .map_err(|e| restore_repl_from_repl_start_error(py, &owner, *e))?;
961
- EitherProgress::ReplLimited(result, owner)
962
- }
963
- EitherFunctionSnapshot::ReplLimitedOs(call, owner) => {
964
- let result = py
965
- .detach(|| call.resume(external_result, print_writer.reborrow()))
966
- .map_err(|e| restore_repl_from_repl_start_error(py, &owner, *e))?;
967
- EitherProgress::ReplLimited(result, owner)
968
- }
969
- EitherFunctionSnapshot::Done => return Err(PyRuntimeError::new_err("Progress already resumed")),
970
- };
971
-
972
- let dc_registry = self.dc_registry.clone_ref(py);
973
- progress.progress_or_complete(
974
- py,
975
- self.script_name.clone(),
976
- self.print_callback.as_ref().map(|cb| cb.clone_ref(py)),
977
- dc_registry,
978
- )
979
- }
980
-
981
- /// Serializes the FunctionSnapshot instance to a binary format.
982
- ///
983
- /// The serialized data can be stored and later restored with `load_snapshot()`
984
- /// or `load_repl_snapshot()`. REPL snapshots automatically include the REPL state.
985
- ///
986
- /// Note: The `print_callback` is not serialized and must be re-provided when loading.
987
- ///
988
- /// # Returns
989
- /// Bytes containing the serialized FunctionSnapshot instance.
990
- ///
991
- /// # Raises
992
- /// `ValueError` if serialization fails.
993
- /// `RuntimeError` if the progress has already been resumed.
994
- fn dump<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
995
- let bytes = crate::serialization::dump_function_snapshot(
996
- py,
997
- &self.snapshot,
998
- &self.script_name,
999
- self.is_os_function,
1000
- self.is_method_call,
1001
- &self.function_name,
1002
- &self.args,
1003
- &self.kwargs,
1004
- self.call_id,
1005
- &self.dc_registry,
1006
- )?;
1007
- Ok(PyBytes::new(py, &bytes))
1008
- }
1009
-
1010
- fn __repr__(&self, py: Python<'_>) -> PyResult<String> {
1011
- Ok(format!(
1012
- "FunctionSnapshot(script_name='{}', function_name='{}', args={}, kwargs={})",
1013
- self.script_name,
1014
- self.function_name,
1015
- self.args.bind(py).repr()?,
1016
- self.kwargs.bind(py).repr()?
1017
- ))
1018
- }
1019
- }
1020
-
1021
- /// Runtime execution snapshot, holds a `NameLookup` for both
1022
- /// resource tracker variants since pyclass structs can't be generic.
1023
- ///
1024
- /// Also holds REPL variants with `Py<PyMontyRepl>` for `MontyRepl.feed_start()`.
1025
- ///
1026
- /// The `Done` variant indicates the snapshot has been consumed.
1027
- #[derive(Debug)]
1028
- pub(crate) enum EitherLookupSnapshot {
1029
- NoLimit(NameLookup<PySignalTracker<NoLimitTracker>>),
1030
- Limited(NameLookup<PySignalTracker<LimitedTracker>>),
1031
- ReplNoLimit(ReplNameLookup<PySignalTracker<NoLimitTracker>>, Py<PyMontyRepl>),
1032
- ReplLimited(ReplNameLookup<PySignalTracker<LimitedTracker>>, Py<PyMontyRepl>),
1033
- /// Sentinel indicating the snapshot has been consumed via `resume()`.
1034
- Done,
1035
- }
1036
-
1037
- /// Helper trait for wrapping `NameLookup<T>` into `EitherLookupSnapshot`.
1038
- trait FromNameLookup<T: ResourceTracker> {
1039
- /// Wraps a name lookup into the appropriate variant.
1040
- fn from_name_lookup(lookup: NameLookup<T>) -> Self;
1041
- }
1042
-
1043
- impl FromNameLookup<PySignalTracker<NoLimitTracker>> for EitherLookupSnapshot {
1044
- fn from_name_lookup(lookup: NameLookup<PySignalTracker<NoLimitTracker>>) -> Self {
1045
- Self::NoLimit(lookup)
1046
- }
1047
- }
1048
-
1049
- impl FromNameLookup<PySignalTracker<LimitedTracker>> for EitherLookupSnapshot {
1050
- fn from_name_lookup(lookup: NameLookup<PySignalTracker<LimitedTracker>>) -> Self {
1051
- Self::Limited(lookup)
1052
- }
1053
- }
1054
-
1055
- /// Helper trait for wrapping `ReplNameLookup<T>` into `EitherLookupSnapshot`.
1056
- trait FromReplNameLookup<T: ResourceTracker> {
1057
- /// Wraps a REPL name lookup into the appropriate variant.
1058
- fn from_repl_name_lookup(lookup: ReplNameLookup<T>, owner: Py<PyMontyRepl>) -> Self;
1059
- }
1060
-
1061
- impl FromReplNameLookup<PySignalTracker<NoLimitTracker>> for EitherLookupSnapshot {
1062
- fn from_repl_name_lookup(lookup: ReplNameLookup<PySignalTracker<NoLimitTracker>>, owner: Py<PyMontyRepl>) -> Self {
1063
- Self::ReplNoLimit(lookup, owner)
1064
- }
1065
- }
1066
-
1067
- impl FromReplNameLookup<PySignalTracker<LimitedTracker>> for EitherLookupSnapshot {
1068
- fn from_repl_name_lookup(lookup: ReplNameLookup<PySignalTracker<LimitedTracker>>, owner: Py<PyMontyRepl>) -> Self {
1069
- Self::ReplLimited(lookup, owner)
1070
- }
1071
- }
1072
-
1073
- /// Snapshot generated during execution when monty yields to the host for a name lookup.
1074
- #[pyclass(name = "NameLookupSnapshot", module = "pydantic_monty")]
1075
- #[derive(Debug)]
1076
- pub struct PyNameLookupSnapshot {
1077
- snapshot: Mutex<EitherLookupSnapshot>,
1078
- print_callback: Option<Py<PyAny>>,
1079
- dc_registry: DcRegistry,
1080
-
1081
- /// Name of the script being executed
1082
- #[pyo3(get)]
1083
- pub script_name: String,
1084
-
1085
- /// Name of the variable being looked up
1086
- #[pyo3(get)]
1087
- pub variable_name: String,
1088
- }
1089
-
1090
- impl PyNameLookupSnapshot {
1091
- /// Creates a `PyNameLookupSnapshot` for an external function call.
1092
- ///
1093
- /// Extracts display fields from the `FunctionCall` before moving it into
1094
- /// `EitherSnapshot` via the provided `wrap` closure.
1095
- fn new_py_any<T: ResourceTracker>(
1096
- py: Python<'_>,
1097
- lookup: NameLookup<T>,
1098
- script_name: String,
1099
- print_callback: Option<Py<PyAny>>,
1100
- dc_registry: DcRegistry,
1101
- ) -> PyResult<Bound<'_, PyAny>>
1102
- where
1103
- EitherLookupSnapshot: FromNameLookup<T>,
1104
- {
1105
- let variable_name = lookup.name.clone();
1106
-
1107
- let slf = Self {
1108
- snapshot: Mutex::new(EitherLookupSnapshot::from_name_lookup(lookup)),
1109
- print_callback,
1110
- dc_registry,
1111
- script_name,
1112
- variable_name,
1113
- };
1114
- slf.into_bound_py_any(py)
1115
- }
1116
-
1117
- /// Creates a `PyNameLookupSnapshot` for a REPL name lookup.
1118
- fn repl_name_lookup<T: ResourceTracker>(
1119
- py: Python<'_>,
1120
- lookup: ReplNameLookup<T>,
1121
- script_name: String,
1122
- print_callback: Option<Py<PyAny>>,
1123
- dc_registry: DcRegistry,
1124
- repl_owner: Py<PyMontyRepl>,
1125
- variable_name: String,
1126
- ) -> PyResult<Bound<'_, PyAny>>
1127
- where
1128
- EitherLookupSnapshot: FromReplNameLookup<T>,
1129
- {
1130
- let slf = Self {
1131
- snapshot: Mutex::new(EitherLookupSnapshot::from_repl_name_lookup(lookup, repl_owner)),
1132
- print_callback,
1133
- dc_registry,
1134
- script_name,
1135
- variable_name,
1136
- };
1137
- slf.into_bound_py_any(py)
1138
- }
1139
-
1140
- /// Constructs a `PyNameLookupSnapshot` from deserialized parts.
1141
- pub(crate) fn from_deserialized(
1142
- py: Python<'_>,
1143
- snapshot: EitherLookupSnapshot,
1144
- print_callback: Option<Py<PyAny>>,
1145
- dc_registry: DcRegistry,
1146
- script_name: String,
1147
- variable_name: String,
1148
- ) -> PyResult<Bound<'_, PyAny>> {
1149
- let slf = Self {
1150
- snapshot: Mutex::new(snapshot),
1151
- print_callback,
1152
- dc_registry,
1153
- script_name,
1154
- variable_name,
1155
- };
1156
- slf.into_bound_py_any(py)
1157
- }
1158
- }
1159
-
1160
- #[pymethods]
1161
- impl PyNameLookupSnapshot {
1162
- /// Resumes execution with either a value or undefined.
1163
- #[pyo3(signature = (**kwargs))]
1164
- pub fn resume<'py>(&self, py: Python<'py>, kwargs: Option<&Bound<'_, PyDict>>) -> PyResult<Bound<'py, PyAny>> {
1165
- let mut snapshot = self
1166
- .snapshot
1167
- .lock()
1168
- .map_err(|_| PyRuntimeError::new_err("Snapshot is currently being resumed by another thread"))?;
1169
-
1170
- let snapshot = std::mem::replace(&mut *snapshot, EitherLookupSnapshot::Done);
1171
- let lookup_result = if let Some(kwargs) = kwargs
1172
- && let Some(value) = kwargs.get_item(intern!(py, "value"))?
1173
- {
1174
- NameLookupResult::Value(py_to_monty(&value, &self.dc_registry)?)
1175
- } else {
1176
- NameLookupResult::Undefined
1177
- };
1178
-
1179
- // Build print writer before detaching - clone_ref needs py token
1180
- let mut print_cb;
1181
- let print_writer = match &self.print_callback {
1182
- Some(cb) => {
1183
- print_cb = CallbackStringPrint::from_py(cb.clone_ref(py));
1184
- PrintWriter::Callback(&mut print_cb)
1185
- }
1186
- None => PrintWriter::Stdout,
1187
- };
1188
- let mut print_writer = SendWrapper::new(print_writer);
1189
-
1190
- let progress = match snapshot {
1191
- EitherLookupSnapshot::NoLimit(snapshot) => {
1192
- let result = py.detach(|| snapshot.resume(lookup_result, print_writer.reborrow()));
1193
- EitherProgress::NoLimit(result.map_err(|e| MontyError::new_err(py, e))?)
1194
- }
1195
- EitherLookupSnapshot::Limited(snapshot) => {
1196
- let result = py.detach(|| snapshot.resume(lookup_result, print_writer.reborrow()));
1197
- EitherProgress::Limited(result.map_err(|e| MontyError::new_err(py, e))?)
1198
- }
1199
- EitherLookupSnapshot::ReplNoLimit(snapshot, owner) => {
1200
- let result = py
1201
- .detach(|| snapshot.resume(lookup_result, print_writer.reborrow()))
1202
- .map_err(|e| restore_repl_from_repl_start_error(py, &owner, *e))?;
1203
- EitherProgress::ReplNoLimit(result, owner)
1204
- }
1205
- EitherLookupSnapshot::ReplLimited(snapshot, owner) => {
1206
- let result = py
1207
- .detach(|| snapshot.resume(lookup_result, print_writer.reborrow()))
1208
- .map_err(|e| restore_repl_from_repl_start_error(py, &owner, *e))?;
1209
- EitherProgress::ReplLimited(result, owner)
1210
- }
1211
- EitherLookupSnapshot::Done => return Err(PyRuntimeError::new_err("Progress already resumed")),
1212
- };
1213
-
1214
- // Clone the Arc handle for the next snapshot/complete
1215
- let dc_registry = self.dc_registry.clone_ref(py);
1216
- progress.progress_or_complete(
1217
- py,
1218
- self.script_name.clone(),
1219
- self.print_callback.as_ref().map(|cb| cb.clone_ref(py)),
1220
- dc_registry,
1221
- )
1222
- }
1223
-
1224
- /// Serializes the NameLookupSnapshot instance to a binary format.
1225
- ///
1226
- /// The serialized data can be stored and later restored with `load_snapshot()`
1227
- /// or `load_repl_snapshot()`. REPL snapshots automatically include the REPL state.
1228
- ///
1229
- /// Note: The `print_callback` is not serialized and must be re-provided when loading.
1230
- ///
1231
- /// # Returns
1232
- /// Bytes containing the serialized NameLookupSnapshot instance.
1233
- ///
1234
- /// # Raises
1235
- /// `ValueError` if serialization fails.
1236
- /// `RuntimeError` if the progress has already been resumed.
1237
- fn dump<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
1238
- let bytes = crate::serialization::dump_lookup_snapshot(&self.snapshot, &self.script_name, &self.variable_name)?;
1239
- Ok(PyBytes::new(py, &bytes))
1240
- }
1241
-
1242
- fn __repr__(&self) -> String {
1243
- format!(
1244
- "NameLookupSnapshot(script_name='{}', variable_name={:?})",
1245
- self.script_name, self.variable_name
1246
- )
1247
- }
1248
- }
1249
-
1250
- /// Holds a `ResolveFutures` for either resource tracker variant.
1251
- ///
1252
- /// Also holds REPL variants with `Py<PyMontyRepl>` for `MontyRepl.feed_start()`.
1253
- ///
1254
- /// Used internally by `PyFutureSnapshot` to store execution state when
1255
- /// awaiting resolution of pending async external calls.
1256
- #[derive(Debug)]
1257
- pub(crate) enum EitherFutureSnapshot {
1258
- NoLimit(ResolveFutures<PySignalTracker<NoLimitTracker>>),
1259
- Limited(ResolveFutures<PySignalTracker<LimitedTracker>>),
1260
- ReplNoLimit(ReplResolveFutures<PySignalTracker<NoLimitTracker>>, Py<PyMontyRepl>),
1261
- ReplLimited(ReplResolveFutures<PySignalTracker<LimitedTracker>>, Py<PyMontyRepl>),
1262
- /// Sentinel indicating the snapshot has been consumed via `resume()`.
1263
- Done,
1264
- }
1265
-
1266
- /// Helper trait for wrapping `ResolveFutures<T>` into `EitherFutureSnapshot`.
1267
- trait FromResolveFutures<T: ResourceTracker> {
1268
- /// Wraps a resolve-futures state into the appropriate variant.
1269
- fn from_resolve_futures(state: ResolveFutures<T>) -> Self;
1270
- }
1271
-
1272
- impl FromResolveFutures<PySignalTracker<NoLimitTracker>> for EitherFutureSnapshot {
1273
- fn from_resolve_futures(state: ResolveFutures<PySignalTracker<NoLimitTracker>>) -> Self {
1274
- Self::NoLimit(state)
1275
- }
1276
- }
1277
-
1278
- impl FromResolveFutures<PySignalTracker<LimitedTracker>> for EitherFutureSnapshot {
1279
- fn from_resolve_futures(state: ResolveFutures<PySignalTracker<LimitedTracker>>) -> Self {
1280
- Self::Limited(state)
1281
- }
1282
- }
1283
-
1284
- /// Helper trait for wrapping `ReplResolveFutures<T>` into `EitherFutureSnapshot`.
1285
- trait FromReplResolveFutures<T: ResourceTracker> {
1286
- /// Wraps a REPL resolve-futures state into the appropriate variant.
1287
- fn from_repl_resolve_futures(state: ReplResolveFutures<T>, owner: Py<PyMontyRepl>) -> Self;
1288
- }
1289
-
1290
- impl FromReplResolveFutures<PySignalTracker<NoLimitTracker>> for EitherFutureSnapshot {
1291
- fn from_repl_resolve_futures(
1292
- state: ReplResolveFutures<PySignalTracker<NoLimitTracker>>,
1293
- owner: Py<PyMontyRepl>,
1294
- ) -> Self {
1295
- Self::ReplNoLimit(state, owner)
1296
- }
1297
- }
1298
-
1299
- impl FromReplResolveFutures<PySignalTracker<LimitedTracker>> for EitherFutureSnapshot {
1300
- fn from_repl_resolve_futures(
1301
- state: ReplResolveFutures<PySignalTracker<LimitedTracker>>,
1302
- owner: Py<PyMontyRepl>,
1303
- ) -> Self {
1304
- Self::ReplLimited(state, owner)
1305
- }
1306
- }
1307
-
1308
- /// Snapshot generated during execution when monty yields to the host to resolve a future.
1309
- ///
1310
- /// Works for both `Monty.start()` and `MontyRepl.feed_start()`.
1311
- #[pyclass(name = "FutureSnapshot", module = "pydantic_monty", frozen)]
1312
- #[derive(Debug)]
1313
- pub struct PyFutureSnapshot {
1314
- snapshot: Mutex<EitherFutureSnapshot>,
1315
- print_callback: Option<Py<PyAny>>,
1316
- dc_registry: DcRegistry,
1317
-
1318
- /// Name of the script being executed
1319
- #[pyo3(get)]
1320
- pub script_name: String,
1321
- }
1322
-
1323
- impl PyFutureSnapshot {
1324
- fn new_py_any<T: ResourceTracker>(
1325
- py: Python<'_>,
1326
- state: ResolveFutures<T>,
1327
- script_name: String,
1328
- print_callback: Option<Py<PyAny>>,
1329
- dc_registry: DcRegistry,
1330
- ) -> PyResult<Bound<'_, PyAny>>
1331
- where
1332
- EitherFutureSnapshot: FromResolveFutures<T>,
1333
- {
1334
- let slf = Self {
1335
- snapshot: Mutex::new(EitherFutureSnapshot::from_resolve_futures(state)),
1336
- print_callback,
1337
- dc_registry,
1338
- script_name,
1339
- };
1340
- slf.into_bound_py_any(py)
1341
- }
1342
-
1343
- /// Constructs a `PyFutureSnapshot` from deserialized parts.
1344
- ///
1345
- /// Used by `load_snapshot` and `load_repl_snapshot` to reconstruct snapshot objects.
1346
- pub(crate) fn from_deserialized(
1347
- py: Python<'_>,
1348
- snapshot: EitherFutureSnapshot,
1349
- print_callback: Option<Py<PyAny>>,
1350
- dc_registry: DcRegistry,
1351
- script_name: String,
1352
- ) -> PyResult<Bound<'_, PyAny>> {
1353
- let slf = Self {
1354
- snapshot: Mutex::new(snapshot),
1355
- print_callback,
1356
- dc_registry,
1357
- script_name,
1358
- };
1359
- slf.into_bound_py_any(py)
1360
- }
1361
-
1362
- /// Creates a `PyFutureSnapshot` for a REPL resolve-futures state.
1363
- fn repl_resolve_futures<T: ResourceTracker>(
1364
- py: Python<'_>,
1365
- state: ReplResolveFutures<T>,
1366
- script_name: String,
1367
- print_callback: Option<Py<PyAny>>,
1368
- dc_registry: DcRegistry,
1369
- repl_owner: Py<PyMontyRepl>,
1370
- ) -> PyResult<Bound<'_, PyAny>>
1371
- where
1372
- EitherFutureSnapshot: FromReplResolveFutures<T>,
1373
- {
1374
- let slf = Self {
1375
- snapshot: Mutex::new(EitherFutureSnapshot::from_repl_resolve_futures(state, repl_owner)),
1376
- print_callback,
1377
- dc_registry,
1378
- script_name,
1379
- };
1380
- slf.into_bound_py_any(py)
1381
- }
1382
- }
1383
-
1384
- #[pymethods]
1385
- impl PyFutureSnapshot {
1386
- /// Resumes execution with results for one or more futures.
1387
- #[pyo3(signature = (results))]
1388
- pub fn resume<'py>(&self, py: Python<'py>, results: &Bound<'_, PyDict>) -> PyResult<Bound<'py, PyAny>> {
1389
- const ARGS_ERROR: &str = "results values must be a dict with either 'return_value' or 'exception', not both";
1390
-
1391
- let mut snapshot = self
1392
- .snapshot
1393
- .lock()
1394
- .map_err(|_| PyRuntimeError::new_err("Snapshot is currently being resumed by another thread"))?;
1395
-
1396
- let snapshot = std::mem::replace(&mut *snapshot, EitherFutureSnapshot::Done);
1397
-
1398
- let external_results = results
1399
- .iter()
1400
- .map(|(key, value)| {
1401
- let call_id = key.extract::<u32>()?;
1402
- let dict = value.cast::<PyDict>()?;
1403
- let value = extract_external_result(py, dict, ARGS_ERROR, &self.dc_registry, call_id)?;
1404
- Ok((call_id, value))
1405
- })
1406
- .collect::<PyResult<Vec<_>>>()?;
1407
-
1408
- // Build print writer before detaching - clone_ref needs py token
1409
- let mut print_cb;
1410
- let print_writer = match &self.print_callback {
1411
- Some(cb) => {
1412
- print_cb = CallbackStringPrint::from_py(cb.clone_ref(py));
1413
- PrintWriter::Callback(&mut print_cb)
1414
- }
1415
- None => PrintWriter::Stdout,
1416
- };
1417
- let mut print_writer = SendWrapper::new(print_writer);
1418
-
1419
- let progress = match snapshot {
1420
- EitherFutureSnapshot::NoLimit(snapshot) => {
1421
- let result = py.detach(|| snapshot.resume(external_results, print_writer.reborrow()));
1422
- EitherProgress::NoLimit(result.map_err(|e| MontyError::new_err(py, e))?)
1423
- }
1424
- EitherFutureSnapshot::Limited(snapshot) => {
1425
- let result = py.detach(|| snapshot.resume(external_results, print_writer.reborrow()));
1426
- EitherProgress::Limited(result.map_err(|e| MontyError::new_err(py, e))?)
1427
- }
1428
- EitherFutureSnapshot::ReplNoLimit(snapshot, owner) => {
1429
- let result = py
1430
- .detach(|| snapshot.resume(external_results, print_writer.reborrow()))
1431
- .map_err(|e| restore_repl_from_repl_start_error(py, &owner, *e))?;
1432
- EitherProgress::ReplNoLimit(result, owner)
1433
- }
1434
- EitherFutureSnapshot::ReplLimited(snapshot, owner) => {
1435
- let result = py
1436
- .detach(|| snapshot.resume(external_results, print_writer.reborrow()))
1437
- .map_err(|e| restore_repl_from_repl_start_error(py, &owner, *e))?;
1438
- EitherProgress::ReplLimited(result, owner)
1439
- }
1440
- EitherFutureSnapshot::Done => return Err(PyRuntimeError::new_err("Progress already resumed")),
1441
- };
1442
-
1443
- // Clone the Arc handle for the next snapshot/complete
1444
- let dc_registry = self.dc_registry.clone_ref(py);
1445
- progress.progress_or_complete(
1446
- py,
1447
- self.script_name.clone(),
1448
- self.print_callback.as_ref().map(|cb| cb.clone_ref(py)),
1449
- dc_registry,
1450
- )
1451
- }
1452
-
1453
- /// Returns the pending call IDs associated with the FutureSnapshot instance.
1454
- ///
1455
- /// # Returns
1456
- /// A slice of pending call IDs.
1457
- #[getter]
1458
- fn pending_call_ids<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyList>> {
1459
- let snapshot = self.snapshot.lock().unwrap_or_else(PoisonError::into_inner);
1460
- match &*snapshot {
1461
- EitherFutureSnapshot::NoLimit(snapshot) => PyList::new(py, snapshot.pending_call_ids()),
1462
- EitherFutureSnapshot::Limited(snapshot) => PyList::new(py, snapshot.pending_call_ids()),
1463
- EitherFutureSnapshot::ReplNoLimit(snapshot, _) => PyList::new(py, snapshot.pending_call_ids()),
1464
- EitherFutureSnapshot::ReplLimited(snapshot, _) => PyList::new(py, snapshot.pending_call_ids()),
1465
- EitherFutureSnapshot::Done => Err(PyRuntimeError::new_err("FutureSnapshot already resumed")),
1466
- }
1467
- }
1468
-
1469
- /// Serializes the FutureSnapshot instance to a binary format.
1470
- ///
1471
- /// The serialized data can be stored and later restored with `load_snapshot()`
1472
- /// or `load_repl_snapshot()`. REPL snapshots automatically include the REPL state.
1473
- ///
1474
- /// Note: The `print_callback` is not serialized and must be re-provided when loading.
1475
- ///
1476
- /// # Returns
1477
- /// Bytes containing the serialized FutureSnapshot instance.
1478
- ///
1479
- /// # Raises
1480
- /// `ValueError` if serialization fails.
1481
- /// `RuntimeError` if the progress has already been resumed.
1482
- fn dump<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
1483
- let bytes = crate::serialization::dump_future_snapshot(&self.snapshot, &self.script_name)?;
1484
- Ok(PyBytes::new(py, &bytes))
1485
- }
1486
-
1487
- fn __repr__(&self) -> String {
1488
- let snapshot = self.snapshot.lock().unwrap_or_else(PoisonError::into_inner);
1489
- let pending_call_ids = match &*snapshot {
1490
- EitherFutureSnapshot::NoLimit(s) => s.pending_call_ids(),
1491
- EitherFutureSnapshot::Limited(s) => s.pending_call_ids(),
1492
- EitherFutureSnapshot::ReplNoLimit(s, _) => s.pending_call_ids(),
1493
- EitherFutureSnapshot::ReplLimited(s, _) => s.pending_call_ids(),
1494
- EitherFutureSnapshot::Done => &[],
1495
- };
1496
- format!(
1497
- "FutureSnapshot(script_name='{}', pending_call_ids={pending_call_ids:?})",
1498
- self.script_name,
1499
- )
1500
- }
1501
- }
1502
-
1503
- #[pyclass(name = "MontyComplete", module = "pydantic_monty", frozen)]
1504
- pub struct PyMontyComplete {
1505
- #[pyo3(get)]
1506
- pub output: Py<PyAny>,
1507
- // TODO we might want to add stats on execution here like time, allocations, etc.
1508
- }
1509
-
1510
- impl PyMontyComplete {
1511
- fn create<'py>(py: Python<'py>, output: &MontyObject, dc_registry: &DcRegistry) -> PyResult<Bound<'py, PyAny>> {
1512
- let output = monty_to_py(py, output, dc_registry)?;
1513
- let slf = Self { output };
1514
- slf.into_bound_py_any(py)
1515
- }
1516
- }
1517
-
1518
- #[pymethods]
1519
- impl PyMontyComplete {
1520
- fn __repr__(&self, py: Python<'_>) -> PyResult<String> {
1521
- Ok(format!("MontyComplete(output={})", self.output.bind(py).repr()?))
1522
- }
1523
- }
1524
-
1525
- fn list_str(arg: Option<&Bound<'_, PyList>>, name: &str) -> PyResult<Vec<String>> {
1526
- if let Some(names) = arg {
1527
- names
1528
- .iter()
1529
- .map(|item| item.extract::<String>())
1530
- .collect::<PyResult<Vec<_>>>()
1531
- .map_err(|e| PyTypeError::new_err(format!("{name}: {e}")))
1532
- } else {
1533
- Ok(vec![])
1534
- }
1535
- }
1536
-
1537
- /// A `PrintWriter` implementation that calls a Python callback for each print output.
1538
- ///
1539
- /// This struct holds a GIL-independent `Py<PyAny>` reference to the callback,
1540
- /// allowing it to be used across GIL release boundaries. The GIL is re-acquired
1541
- /// briefly for each callback invocation.
1542
- #[derive(Debug)]
1543
- pub(crate) struct CallbackStringPrint(Py<PyAny>);
1544
-
1545
- impl CallbackStringPrint {
1546
- /// Creates a new `CallbackStringPrint` from a borrowed Python callback.
1547
- fn new(callback: &Bound<'_, PyAny>) -> Self {
1548
- Self(callback.clone().unbind())
1549
- }
1550
-
1551
- /// Creates a new `CallbackStringPrint` from an owned `Py<PyAny>`.
1552
- pub(crate) fn from_py(callback: Py<PyAny>) -> Self {
1553
- Self(callback)
1554
- }
1555
- }
1556
-
1557
- impl PrintWriterCallback for CallbackStringPrint {
1558
- fn stdout_write(&mut self, output: Cow<'_, str>) -> Result<(), MontyException> {
1559
- Python::attach(|py| {
1560
- self.0.bind(py).call1(("stdout", output.as_ref()))?;
1561
- Ok::<_, PyErr>(())
1562
- })
1563
- .map_err(|e| Python::attach(|py| exc_py_to_monty(py, &e)))
1564
- }
1565
-
1566
- fn stdout_push(&mut self, end: char) -> Result<(), MontyException> {
1567
- Python::attach(|py| {
1568
- self.0.bind(py).call1(("stdout", end.to_string()))?;
1569
- Ok::<_, PyErr>(())
1570
- })
1571
- .map_err(|e| Python::attach(|py| exc_py_to_monty(py, &e)))
1572
- }
1573
- }
1574
-
1575
- /// Recursively checks whether a `MontyObject` contains a dataclass, including
1576
- /// inside containers like `List`, `Tuple`, and `Dict`.
1577
- ///
1578
- /// This is used to decide whether to take the iterative execution path: dataclass
1579
- /// method calls need host dispatch, so if any input (even nested) is a dataclass
1580
- /// we must use the iterative runner rather than the non-iterative `run()`.
1581
- fn contains_dataclass(obj: &MontyObject) -> bool {
1582
- match obj {
1583
- MontyObject::Dataclass { .. } => true,
1584
- MontyObject::List(items) | MontyObject::Tuple(items) => items.iter().any(contains_dataclass),
1585
- MontyObject::Dict(pairs) => pairs
1586
- .into_iter()
1587
- .any(|(k, v)| contains_dataclass(k) || contains_dataclass(v)),
1588
- _ => false,
1589
- }
1590
- }
1591
-
1592
- /// Serialization wrapper for `PyMonty` that includes all fields needed for reconstruction.
1593
- #[derive(serde::Serialize, serde::Deserialize)]
1594
- struct SerializedMonty {
1595
- runner: MontyRun,
1596
- script_name: String,
1597
- input_names: Vec<String>,
1598
- }
1599
-
1600
- /// Extract an external result (object or exception) from a dictionary.
1601
- ///
1602
- /// Any dataclass return values are automatically registered in the `dc_registry` via `py_to_monty`
1603
- /// so they can be properly reconstructed on output.
1604
- /// Extracts an `ExternalResult` from a Python dict with a single key.
1605
- ///
1606
- /// Accepts `return_value`, `exception`, or `future` (with value `...`).
1607
- /// The `call_id` is required for `future` results to track the pending call.
1608
- fn extract_external_result(
1609
- py: Python<'_>,
1610
- dict: &Bound<'_, PyDict>,
1611
- error_msg: &'static str,
1612
- dc_registry: &DcRegistry,
1613
- call_id: u32,
1614
- ) -> PyResult<ExtFunctionResult> {
1615
- if dict.len() != 1 {
1616
- Err(PyTypeError::new_err(error_msg))
1617
- } else if let Some(rv) = dict.get_item(intern!(py, "return_value"))? {
1618
- // Return value provided
1619
- Ok(py_to_monty(&rv, dc_registry)?.into())
1620
- } else if let Some(exc) = dict.get_item(intern!(py, "exception"))? {
1621
- // Exception provided
1622
- let py_err = PyErr::from_value(exc.into_any());
1623
- Ok(exc_py_to_monty(py, &py_err).into())
1624
- } else if let Some(exc) = dict.get_item(intern!(py, "future"))? {
1625
- if exc.eq(py.Ellipsis()).unwrap_or_default() {
1626
- Ok(ExtFunctionResult::Future(call_id))
1627
- } else {
1628
- Err(PyTypeError::new_err(
1629
- "Value for the 'future' key must be Ellipsis (...)",
1630
- ))
1631
- }
1632
- } else {
1633
- // wrong key in kwargs
1634
- Err(PyTypeError::new_err(error_msg))
1635
- }
1636
- }
1637
-
1638
- /// Extracts the REPL from a `ReplStartError`, restores it into the owner,
1639
- /// and returns the Python exception.
1640
- fn restore_repl_from_repl_start_error<T: ResourceTracker>(
1641
- py: Python<'_>,
1642
- repl_owner: &Py<PyMontyRepl>,
1643
- err: ReplStartError<T>,
1644
- ) -> PyErr
1645
- where
1646
- EitherRepl: FromCoreRepl<T>,
1647
- {
1648
- repl_owner.get().put_repl(EitherRepl::from_core(err.repl));
1649
- MontyError::new_err(py, err.error)
1650
- }