shellsim 0.1.15__tar.gz → 0.1.16__tar.gz

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 (183) hide show
  1. {shellsim-0.1.15 → shellsim-0.1.16}/Cargo.lock +1 -1
  2. {shellsim-0.1.15 → shellsim-0.1.16}/Cargo.toml +1 -1
  3. {shellsim-0.1.15 → shellsim-0.1.16}/PKG-INFO +1 -1
  4. {shellsim-0.1.15 → shellsim-0.1.16}/python/native/Cargo.lock +2 -2
  5. {shellsim-0.1.15 → shellsim-0.1.16}/python/native/Cargo.toml +1 -1
  6. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/compiler.rs +0 -2
  7. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/heap.rs +6 -1
  8. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/asyncio.py +100 -25
  9. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/vm/calls.rs +1 -0
  10. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/vm/iteration.rs +43 -22
  11. {shellsim-0.1.15 → shellsim-0.1.16}/LICENSE +0 -0
  12. {shellsim-0.1.15 → shellsim-0.1.16}/README.md +0 -0
  13. {shellsim-0.1.15 → shellsim-0.1.16}/pyproject.toml +0 -0
  14. {shellsim-0.1.15 → shellsim-0.1.16}/python/native/src/lib.rs +0 -0
  15. {shellsim-0.1.15 → shellsim-0.1.16}/python/shellsim/__init__.py +0 -0
  16. {shellsim-0.1.15 → shellsim-0.1.16}/python/shellsim/__main__.py +0 -0
  17. {shellsim-0.1.15 → shellsim-0.1.16}/python/shellsim/_api.py +0 -0
  18. {shellsim-0.1.15 → shellsim-0.1.16}/python/shellsim/_cli.py +0 -0
  19. {shellsim-0.1.15 → shellsim-0.1.16}/python/shellsim/py.typed +0 -0
  20. {shellsim-0.1.15 → shellsim-0.1.16}/python/shellsim/python.py +0 -0
  21. {shellsim-0.1.15 → shellsim-0.1.16}/rust-toolchain.toml +0 -0
  22. {shellsim-0.1.15 → shellsim-0.1.16}/src/bin/shellsim-python.rs +0 -0
  23. {shellsim-0.1.15 → shellsim-0.1.16}/src/clock.rs +0 -0
  24. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/archives.rs +0 -0
  25. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/awk/ast.rs +0 -0
  26. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/awk/eval.rs +0 -0
  27. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/awk/lexer.rs +0 -0
  28. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/awk/parser.rs +0 -0
  29. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/awk.rs +0 -0
  30. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/builtins.rs +0 -0
  31. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/dd.rs +0 -0
  32. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/echo.rs +0 -0
  33. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/find.rs +0 -0
  34. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/fs.rs +0 -0
  35. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/git/apply.rs +0 -0
  36. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/git/commit.rs +0 -0
  37. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/git/compare.rs +0 -0
  38. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/git/config.rs +0 -0
  39. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/git/conflict.rs +0 -0
  40. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/git/diff.rs +0 -0
  41. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/git/ignore.rs +0 -0
  42. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/git/import.rs +0 -0
  43. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/git/log.rs +0 -0
  44. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/git/merge.rs +0 -0
  45. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/git/mod.rs +0 -0
  46. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/git/plumbing.rs +0 -0
  47. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/git/rebase.rs +0 -0
  48. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/git/refs.rs +0 -0
  49. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/git/repo.rs +0 -0
  50. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/git/stash.rs +0 -0
  51. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/git/switch.rs +0 -0
  52. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/git/worktree.rs +0 -0
  53. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/hashing.rs +0 -0
  54. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/makecmd.rs +0 -0
  55. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/mod.rs +0 -0
  56. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/net.rs +0 -0
  57. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/options.rs +0 -0
  58. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/patch.rs +0 -0
  59. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/pkg.rs +0 -0
  60. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/printf.rs +0 -0
  61. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/proc.rs +0 -0
  62. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/regex_compat.rs +0 -0
  63. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/rgcmd.rs +0 -0
  64. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/sed.rs +0 -0
  65. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/sort.rs +0 -0
  66. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/system.rs +0 -0
  67. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/tarcmd.rs +0 -0
  68. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/text.rs +0 -0
  69. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/unavailable.rs +0 -0
  70. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/util.rs +0 -0
  71. {shellsim-0.1.15 → shellsim-0.1.16}/src/commands/zipcmd.rs +0 -0
  72. {shellsim-0.1.15 → shellsim-0.1.16}/src/descriptors.rs +0 -0
  73. {shellsim-0.1.15 → shellsim-0.1.16}/src/exec.rs +0 -0
  74. {shellsim-0.1.15 → shellsim-0.1.16}/src/expand.rs +0 -0
  75. {shellsim-0.1.15 → shellsim-0.1.16}/src/harness.rs +0 -0
  76. {shellsim-0.1.15 → shellsim-0.1.16}/src/harness_manager.rs +0 -0
  77. {shellsim-0.1.15 → shellsim-0.1.16}/src/hashes.rs +0 -0
  78. {shellsim-0.1.15 → shellsim-0.1.16}/src/host_ingest.rs +0 -0
  79. {shellsim-0.1.15 → shellsim-0.1.16}/src/interp.rs +0 -0
  80. {shellsim-0.1.15 → shellsim-0.1.16}/src/jqcmd.rs +0 -0
  81. {shellsim-0.1.15 → shellsim-0.1.16}/src/lib.rs +0 -0
  82. {shellsim-0.1.15 → shellsim-0.1.16}/src/main.rs +0 -0
  83. {shellsim-0.1.15 → shellsim-0.1.16}/src/mcp.rs +0 -0
  84. {shellsim-0.1.15 → shellsim-0.1.16}/src/net.rs +0 -0
  85. {shellsim-0.1.15 → shellsim-0.1.16}/src/netcmd.rs +0 -0
  86. {shellsim-0.1.15 → shellsim-0.1.16}/src/process.rs +0 -0
  87. {shellsim-0.1.15 → shellsim-0.1.16}/src/pseudo_fs.rs +0 -0
  88. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/ast.rs +0 -0
  89. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/bytecode.rs +0 -0
  90. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/filesystem.rs +0 -0
  91. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/http.rs +0 -0
  92. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/lexer.rs +0 -0
  93. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/mapping.rs +0 -0
  94. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/mod.rs +0 -0
  95. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/native.rs +0 -0
  96. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/number.rs +0 -0
  97. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/object_model.rs +0 -0
  98. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/parser.rs +0 -0
  99. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/process.rs +0 -0
  100. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/protocol.rs +0 -0
  101. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/slice.rs +0 -0
  102. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/source.rs +0 -0
  103. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/argparse.rs +0 -0
  104. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/asyncio.rs +0 -0
  105. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/base64.rs +0 -0
  106. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/bisect.rs +0 -0
  107. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/collections.rs +0 -0
  108. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/core.rs +0 -0
  109. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/dataclasses.rs +0 -0
  110. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/enum.rs +0 -0
  111. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/frozen.rs +0 -0
  112. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/functools.rs +0 -0
  113. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/hashlib.rs +0 -0
  114. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/heapq.rs +0 -0
  115. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/http.rs +0 -0
  116. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/importlib.rs +0 -0
  117. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/itertools.rs +0 -0
  118. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/json.rs +0 -0
  119. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/math.rs +0 -0
  120. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/mod.rs +0 -0
  121. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/numpy.rs +0 -0
  122. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/os.rs +0 -0
  123. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/pytest.rs +0 -0
  124. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/re.rs +0 -0
  125. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/abc.py +0 -0
  126. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/base64.py +0 -0
  127. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/cmath.py +0 -0
  128. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/codecs.py +0 -0
  129. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/collections.py +0 -0
  130. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/complex.py +0 -0
  131. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/copy.py +0 -0
  132. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/csv.py +0 -0
  133. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/datetime.py +0 -0
  134. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/glob.py +0 -0
  135. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/hashlib.py +0 -0
  136. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/http.py +0 -0
  137. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/http_client.py +0 -0
  138. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/importlib.py +0 -0
  139. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/io.py +0 -0
  140. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/json.py +0 -0
  141. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/logging.py +0 -0
  142. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/numpy_random.py +0 -0
  143. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/os.py +0 -0
  144. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/pathlib.py +0 -0
  145. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/pytest.py +0 -0
  146. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/random.py +0 -0
  147. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/shutil.py +0 -0
  148. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/statistics.py +0 -0
  149. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/struct.py +0 -0
  150. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/subprocess.py +0 -0
  151. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/tempfile.py +0 -0
  152. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/textwrap.py +0 -0
  153. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/urllib.py +0 -0
  154. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/urllib_error.py +0 -0
  155. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/urllib_request.py +0 -0
  156. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/uuid.py +0 -0
  157. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/zipfile.py +0 -0
  158. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/source/zlib.py +0 -0
  159. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/string.rs +0 -0
  160. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/struct.rs +0 -0
  161. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/subprocess.rs +0 -0
  162. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/sys.rs +0 -0
  163. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/time.rs +0 -0
  164. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/typing.rs +0 -0
  165. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/unittest.rs +0 -0
  166. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/vfs.rs +0 -0
  167. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/stdlib/zlib.rs +0 -0
  168. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/string.rs +0 -0
  169. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/token.rs +0 -0
  170. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/vm/dispatch.rs +0 -0
  171. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/vm/host.rs +0 -0
  172. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/vm/namespace.rs +0 -0
  173. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/vm/native_runtime.rs +0 -0
  174. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/vm/objects.rs +0 -0
  175. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/vm/operations.rs +0 -0
  176. {shellsim-0.1.15 → shellsim-0.1.16}/src/python/vm.rs +0 -0
  177. {shellsim-0.1.15 → shellsim-0.1.16}/src/resources.rs +0 -0
  178. {shellsim-0.1.15 → shellsim-0.1.16}/src/sandbox.rs +0 -0
  179. {shellsim-0.1.15 → shellsim-0.1.16}/src/scenario.rs +0 -0
  180. {shellsim-0.1.15 → shellsim-0.1.16}/src/scheduler.rs +0 -0
  181. {shellsim-0.1.15 → shellsim-0.1.16}/src/shell.rs +0 -0
  182. {shellsim-0.1.15 → shellsim-0.1.16}/src/telemetry.rs +0 -0
  183. {shellsim-0.1.15 → shellsim-0.1.16}/src/vfs.rs +0 -0
@@ -330,7 +330,7 @@ dependencies = [
330
330
 
331
331
  [[package]]
332
332
  name = "shellsim"
333
- version = "0.1.15"
333
+ version = "0.1.16"
334
334
  dependencies = [
335
335
  "base64",
336
336
  "crc32fast",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "shellsim"
3
- version = "0.1.15"
3
+ version = "0.1.16"
4
4
  edition = "2021"
5
5
  description = "In-process BusyBox-like environment for RL rollouts and agent tests"
6
6
  license = "Apache-2.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shellsim
3
- Version: 0.1.15
3
+ Version: 0.1.16
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: License :: OSI Approved :: Apache Software License
6
6
  Classifier: Operating System :: MacOS :: MacOS X
@@ -406,7 +406,7 @@ dependencies = [
406
406
 
407
407
  [[package]]
408
408
  name = "shellsim"
409
- version = "0.1.15"
409
+ version = "0.1.16"
410
410
  dependencies = [
411
411
  "base64",
412
412
  "crc32fast",
@@ -427,7 +427,7 @@ dependencies = [
427
427
 
428
428
  [[package]]
429
429
  name = "shellsim-python-bindings"
430
- version = "0.1.15"
430
+ version = "0.1.16"
431
431
  dependencies = [
432
432
  "pyo3",
433
433
  "serde",
@@ -2,7 +2,7 @@
2
2
 
3
3
  [package]
4
4
  name = "shellsim-python-bindings"
5
- version = "0.1.15"
5
+ version = "0.1.16"
6
6
  edition = "2021"
7
7
  description = "Python bindings for shellsim"
8
8
  license = "Apache-2.0"
@@ -659,8 +659,6 @@ impl Compiler {
659
659
  self.protected_regions.pop();
660
660
  if let Some(handler_body_try) = handler_body_try {
661
661
  self.emit(Operation::TryEnd, span);
662
- self.emit(Operation::ClearException, span);
663
- self.statements(finalbody.clone());
664
662
  let handler_body_done = self.emit(Operation::Jump(usize::MAX), span);
665
663
  let handler_body_cleanup = self.instructions.len();
666
664
  self.patch_try_begin(handler_body_try, handler_body_cleanup);
@@ -202,13 +202,14 @@ pub enum Object {
202
202
  exhausted: bool,
203
203
  },
204
204
  /// A suspended Python generator frame. The bytecode is immutable; the instruction pointer,
205
- /// exception-handler stack, and lexical scope are the complete resumable state.
205
+ /// exception state, and lexical scope are the complete resumable state.
206
206
  Generator {
207
207
  name: String,
208
208
  code: CodeRef,
209
209
  scope: ScopeId,
210
210
  instruction_pointer: usize,
211
211
  handlers: Vec<(usize, usize)>,
212
+ exceptions: Vec<(String, Value)>,
212
213
  stack: Vec<Value>,
213
214
  exhausted: bool,
214
215
  running: bool,
@@ -1433,11 +1434,13 @@ fn trace_object(
1433
1434
  }
1434
1435
  Object::Generator {
1435
1436
  scope,
1437
+ exceptions,
1436
1438
  stack,
1437
1439
  return_value,
1438
1440
  ..
1439
1441
  } => {
1440
1442
  scope_work.push(*scope);
1443
+ trace_values(exceptions.iter().map(|(_, value)| *value), object_work);
1441
1444
  trace_values(stack.iter().copied(), object_work);
1442
1445
  trace_value(*return_value, object_work);
1443
1446
  }
@@ -1566,12 +1569,14 @@ fn modeled_size(object: &Object) -> Result<u64, String> {
1566
1569
  name,
1567
1570
  code,
1568
1571
  handlers,
1572
+ exceptions,
1569
1573
  stack,
1570
1574
  ..
1571
1575
  } => name
1572
1576
  .len()
1573
1577
  .checked_add(code.instructions.len())
1574
1578
  .and_then(|size| size.checked_add(handlers.len()))
1579
+ .and_then(|size| size.checked_add(exceptions.len()))
1575
1580
  .and_then(|size| size.checked_add(stack.len()))
1576
1581
  .ok_or("modeled object size overflow")?,
1577
1582
  Object::Module { name, .. } => name.len(),
@@ -232,6 +232,7 @@ class Task:
232
232
  self._name = name
233
233
  self._callbacks = []
234
234
  self._cancel_requests = 0
235
+ self._must_cancel = False
235
236
  self._logical_task = self
236
237
 
237
238
  def done(self):
@@ -269,6 +270,8 @@ class Task:
269
270
  def uncancel(self):
270
271
  if self._cancel_requests:
271
272
  self._cancel_requests -= 1
273
+ if not self._cancel_requests:
274
+ self._must_cancel = False
272
275
  return self._cancel_requests
273
276
 
274
277
  def add_done_callback(self, callback, context=None):
@@ -704,8 +707,12 @@ class _Loop:
704
707
  self._resource_waiters = []
705
708
  self._tasks = []
706
709
  self._current = None
710
+ self._running = False
711
+ self._closed = False
707
712
 
708
713
  def create_task(self, coroutine, name=None):
714
+ if self._closed:
715
+ raise RuntimeError("Event loop is closed")
709
716
  task = Task(coroutine, self, name)
710
717
  self._tasks.append(task)
711
718
  self._ready.append(task)
@@ -723,6 +730,8 @@ class _Loop:
723
730
  return _monotonic_ns() / 1000000000
724
731
 
725
732
  def call_soon(self, callback, *args, context=None):
733
+ if self._closed:
734
+ raise RuntimeError("Event loop is closed")
726
735
  handle = Handle(callback, args)
727
736
  self._ready.append(handle)
728
737
  return handle
@@ -731,6 +740,8 @@ class _Loop:
731
740
  return self.call_soon(callback, *args, context=context)
732
741
 
733
742
  def call_at(self, when, callback, *args, context=None):
743
+ if self._closed:
744
+ raise RuntimeError("Event loop is closed")
734
745
  handle = TimerHandle(when, callback, args)
735
746
  self._timers.append((int(when * 1000000000), handle))
736
747
  return handle
@@ -744,7 +755,8 @@ class _Loop:
744
755
  waiter for waiter in self._resource_waiters if waiter[0] is not task
745
756
  ]
746
757
  task._send_value = (True, value)
747
- self._ready.append(task)
758
+ if task not in self._ready:
759
+ self._ready.append(task)
748
760
 
749
761
  def _schedule_failure(self, task, error):
750
762
  if not task._done:
@@ -752,9 +764,13 @@ class _Loop:
752
764
  waiter for waiter in self._resource_waiters if waiter[0] is not task
753
765
  ]
754
766
  task._send_value = (False, error)
755
- self._ready.append(task)
767
+ if task not in self._ready:
768
+ self._ready.append(task)
756
769
 
757
770
  def _cancel(self, task):
771
+ if self._current is task:
772
+ task._must_cancel = True
773
+ return
758
774
  dependency = task._waiting_on
759
775
  if isinstance(dependency, (Task, Future)) and dependency.cancel():
760
776
  return
@@ -925,30 +941,83 @@ class _Loop:
925
941
  raise TypeError("object cannot be used in 'await' expression")
926
942
 
927
943
  def run(self, coroutine):
944
+ if self._closed:
945
+ raise RuntimeError("Event loop is closed")
946
+ if self._running:
947
+ raise RuntimeError("This event loop is already running")
928
948
  root = self.create_task(coroutine)
929
- while not root.done():
930
- if not self._ready:
931
- self._wake_due_timers()
932
- if not self._ready:
933
- self._wait_for_resources()
934
- task = self._ready.pop(0)
935
- if isinstance(task, Handle):
936
- task._run()
937
- continue
938
- if task._done:
939
- continue
940
- task._started = True
941
- self._current = task
942
- status, value = _step(task._coroutine, task._send_value)
949
+ self._running = True
950
+ try:
951
+ while not root.done():
952
+ if not self._ready:
953
+ self._wake_due_timers()
954
+ if not self._ready:
955
+ self._wait_for_resources()
956
+ task = self._ready.pop(0)
957
+ if isinstance(task, Handle):
958
+ task._run()
959
+ continue
960
+ if task._done:
961
+ continue
962
+ task._started = True
963
+ self._current = task
964
+ status, value = _step(task._coroutine, task._send_value)
965
+ self._current = None
966
+ task._send_value = None
967
+ if status == 1:
968
+ self._finish(task, value)
969
+ elif status == 2:
970
+ self._fail(task, value)
971
+ elif task._must_cancel:
972
+ task._must_cancel = False
973
+ self._schedule_failure(task, CancelledError())
974
+ else:
975
+ self._dispatch_yield(task, value)
976
+ return root.result()
977
+ finally:
943
978
  self._current = None
944
- task._send_value = None
945
- if status == 1:
946
- self._finish(task, value)
947
- elif status == 2:
948
- self._fail(task, value)
949
- else:
950
- self._dispatch_yield(task, value)
951
- return root.result()
979
+ self._running = False
980
+
981
+ def run_until_complete(self, awaitable):
982
+ async def wait_for_awaitable():
983
+ return await awaitable
984
+
985
+ return self.run(wait_for_awaitable())
986
+
987
+ def is_running(self):
988
+ return self._running
989
+
990
+ def is_closed(self):
991
+ return self._closed
992
+
993
+ async def shutdown_asyncgens(self):
994
+ return None
995
+
996
+ async def shutdown_default_executor(self, timeout=None):
997
+ return None
998
+
999
+ def _shutdown(self):
1000
+ pending = [task for task in self._tasks if not task.done()]
1001
+ if not pending:
1002
+ return
1003
+ for task in pending:
1004
+ task.cancel()
1005
+
1006
+ async def wait_for_pending():
1007
+ await gather(*pending, return_exceptions=True)
1008
+
1009
+ self.run(wait_for_pending())
1010
+
1011
+ def close(self):
1012
+ if self._running:
1013
+ raise RuntimeError("Cannot close a running event loop")
1014
+ if self._closed:
1015
+ return
1016
+ self._closed = True
1017
+ self._ready = []
1018
+ self._timers = []
1019
+ self._resource_waiters = []
1020
+ self._tasks = []
952
1021
 
953
1022
 
954
1023
  def get_running_loop():
@@ -1262,4 +1331,10 @@ def run(coroutine):
1262
1331
  try:
1263
1332
  return loop.run(coroutine)
1264
1333
  finally:
1265
- _running_loop = None
1334
+ try:
1335
+ loop._shutdown()
1336
+ loop.run(loop.shutdown_asyncgens())
1337
+ loop.run(loop.shutdown_default_executor())
1338
+ finally:
1339
+ loop.close()
1340
+ _running_loop = None
@@ -1179,6 +1179,7 @@ impl Vm<'_> {
1179
1179
  scope,
1180
1180
  instruction_pointer: 0,
1181
1181
  handlers: Vec::new(),
1182
+ exceptions: Vec::new(),
1182
1183
  stack: Vec::new(),
1183
1184
  exhausted: false,
1184
1185
  running: false,
@@ -274,28 +274,38 @@ impl Vm<'_> {
274
274
  if self.call_depth >= MAX_GENERATOR_DEPTH {
275
275
  return Err("maximum recursion depth exceeded".into());
276
276
  }
277
- let (code, scope, instruction_pointer, mut handlers, frame_stack, exhausted, running) =
278
- match self.state.heap.get(id)?.clone() {
279
- Object::Generator {
280
- code,
281
- scope,
282
- instruction_pointer,
283
- handlers,
284
- stack,
285
- exhausted,
286
- running,
287
- ..
288
- } => (
289
- code,
290
- scope,
291
- instruction_pointer,
292
- handlers,
293
- stack,
294
- exhausted,
295
- running,
296
- ),
297
- _ => return Err("object is not a generator".into()),
298
- };
277
+ let (
278
+ code,
279
+ scope,
280
+ instruction_pointer,
281
+ mut handlers,
282
+ exceptions,
283
+ frame_stack,
284
+ exhausted,
285
+ running,
286
+ ) = match self.state.heap.get(id)?.clone() {
287
+ Object::Generator {
288
+ code,
289
+ scope,
290
+ instruction_pointer,
291
+ handlers,
292
+ exceptions,
293
+ stack,
294
+ exhausted,
295
+ running,
296
+ ..
297
+ } => (
298
+ code,
299
+ scope,
300
+ instruction_pointer,
301
+ handlers,
302
+ exceptions,
303
+ stack,
304
+ exhausted,
305
+ running,
306
+ ),
307
+ _ => return Err("object is not a generator".into()),
308
+ };
299
309
  if exhausted {
300
310
  return Ok(None);
301
311
  }
@@ -313,11 +323,20 @@ impl Vm<'_> {
313
323
  if instruction_pointer != 0 {
314
324
  self.stack.push(sent);
315
325
  }
326
+ let generator_exceptions = exceptions
327
+ .into_iter()
328
+ .map(|(kind, value)| super::RaisedException { kind, value })
329
+ .collect();
330
+ let outer_exceptions = std::mem::replace(&mut self.exception_stack, generator_exceptions);
316
331
  self.local_scopes.push(scope);
317
332
  self.call_depth += 1;
318
333
  let result = self.execute_code_from(&code, instruction_pointer, &mut handlers, 0);
319
334
  self.call_depth -= 1;
320
335
  self.local_scopes.pop();
336
+ let generator_exceptions = std::mem::replace(&mut self.exception_stack, outer_exceptions)
337
+ .into_iter()
338
+ .map(|exception| (exception.kind, exception.value))
339
+ .collect();
321
340
  let frame_result_stack = std::mem::take(&mut self.stack);
322
341
  self.stack = outer_stack;
323
342
 
@@ -328,6 +347,7 @@ impl Vm<'_> {
328
347
  if let Object::Generator {
329
348
  instruction_pointer,
330
349
  handlers: saved_handlers,
350
+ exceptions: saved_exceptions,
331
351
  stack: saved_stack,
332
352
  running,
333
353
  ..
@@ -335,6 +355,7 @@ impl Vm<'_> {
335
355
  {
336
356
  *instruction_pointer = next_instruction;
337
357
  *saved_handlers = handlers;
358
+ *saved_exceptions = generator_exceptions;
338
359
  *saved_stack = frame_result_stack;
339
360
  *running = false;
340
361
  }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes