rsloop 0.1.51__tar.gz → 0.1.52__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 (272) hide show
  1. {rsloop-0.1.51 → rsloop-0.1.52}/Cargo.lock +1 -1
  2. {rsloop-0.1.51 → rsloop-0.1.52}/Cargo.toml +43 -42
  3. rsloop-0.1.52/PKG-INFO +201 -0
  4. rsloop-0.1.52/README.md +168 -0
  5. {rsloop-0.1.51 → rsloop-0.1.52}/benches/compare_event_loops.py +1 -3
  6. rsloop-0.1.52/docs/benchmarks.md +170 -0
  7. {rsloop-0.1.51 → rsloop-0.1.52}/docs/development.md +62 -5
  8. rsloop-0.1.52/docs/fast-streams.md +41 -0
  9. rsloop-0.1.52/docs/free-threading.md +43 -0
  10. {rsloop-0.1.51 → rsloop-0.1.52}/docs/how-it-works.md +43 -30
  11. {rsloop-0.1.51 → rsloop-0.1.52}/docs/index.md +3 -0
  12. {rsloop-0.1.51 → rsloop-0.1.52}/docs/rust-extensions.md +1 -1
  13. rsloop-0.1.52/docs/supported-features.md +66 -0
  14. {rsloop-0.1.51 → rsloop-0.1.52}/justfile +1 -0
  15. {rsloop-0.1.51 → rsloop-0.1.52}/mkdocs.yml +4 -0
  16. {rsloop-0.1.51 → rsloop-0.1.52}/pyproject.toml +56 -56
  17. {rsloop-0.1.51 → rsloop-0.1.52}/python/rsloop/__init__.pyi +1 -0
  18. {rsloop-0.1.51 → rsloop-0.1.52}/python/rsloop/_loop_compat.py +3 -2
  19. {rsloop-0.1.51 → rsloop-0.1.52}/qualirs.toml +48 -48
  20. {rsloop-0.1.51 → rsloop-0.1.52}/scripts/hotpath_lab.py +12 -2
  21. {rsloop-0.1.51 → rsloop-0.1.52}/src/engine/commands.rs +4 -1
  22. {rsloop-0.1.51 → rsloop-0.1.52}/src/engine/dispatcher.rs +2 -1
  23. {rsloop-0.1.51 → rsloop-0.1.52}/src/engine/loop_core.rs +5 -4
  24. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/accept.rs +10 -2
  25. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/mod.rs +31 -0
  26. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/py_server.rs +2 -0
  27. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/server.rs +1 -0
  28. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/server_core.rs +16 -3
  29. {rsloop-0.1.51 → rsloop-0.1.52}/uv.lock +1 -1
  30. rsloop-0.1.51/PKG-INFO +0 -651
  31. rsloop-0.1.51/README.md +0 -618
  32. {rsloop-0.1.51 → rsloop-0.1.52}/.cargo/config.toml +0 -0
  33. {rsloop-0.1.51 → rsloop-0.1.52}/.github/workflows/anyio.yml +0 -0
  34. {rsloop-0.1.51 → rsloop-0.1.52}/.github/workflows/kani.yml +0 -0
  35. {rsloop-0.1.51 → rsloop-0.1.52}/.github/workflows/mkdocs.yml +0 -0
  36. {rsloop-0.1.51 → rsloop-0.1.52}/.github/workflows/tests.yml +0 -0
  37. {rsloop-0.1.51 → rsloop-0.1.52}/.github/workflows/update-version.yml +0 -0
  38. {rsloop-0.1.51 → rsloop-0.1.52}/.github/workflows/vibeio-native.yml +0 -0
  39. {rsloop-0.1.51 → rsloop-0.1.52}/.github/workflows/wheels.yml +0 -0
  40. {rsloop-0.1.51 → rsloop-0.1.52}/.gitignore +0 -0
  41. {rsloop-0.1.51 → rsloop-0.1.52}/.python-version +0 -0
  42. {rsloop-0.1.51 → rsloop-0.1.52}/.vscode/settings.json +0 -0
  43. {rsloop-0.1.51 → rsloop-0.1.52}/LICENSE +0 -0
  44. {rsloop-0.1.51 → rsloop-0.1.52}/benches/compare_granian.py +0 -0
  45. {rsloop-0.1.51 → rsloop-0.1.52}/benches/workload_matrix.py +0 -0
  46. {rsloop-0.1.51 → rsloop-0.1.52}/build.rs +0 -0
  47. {rsloop-0.1.51 → rsloop-0.1.52}/docs/examples.md +0 -0
  48. {rsloop-0.1.51 → rsloop-0.1.52}/docs/getting-started.md +0 -0
  49. {rsloop-0.1.51 → rsloop-0.1.52}/docs/hotpath-lab.md +0 -0
  50. {rsloop-0.1.51 → rsloop-0.1.52}/docs/project-structure.md +0 -0
  51. {rsloop-0.1.51 → rsloop-0.1.52}/docs/rsloop.png +0 -0
  52. {rsloop-0.1.51 → rsloop-0.1.52}/docs/verification.md +0 -0
  53. {rsloop-0.1.51 → rsloop-0.1.52}/examples/01_basics.py +0 -0
  54. {rsloop-0.1.51 → rsloop-0.1.52}/examples/02_fd_and_sockets.py +0 -0
  55. {rsloop-0.1.51 → rsloop-0.1.52}/examples/03_streams.py +0 -0
  56. {rsloop-0.1.51 → rsloop-0.1.52}/examples/04_unix_and_accepted_socket.py +0 -0
  57. {rsloop-0.1.51 → rsloop-0.1.52}/examples/05_pipes_signals_subprocesses.py +0 -0
  58. {rsloop-0.1.51 → rsloop-0.1.52}/examples/README.md +0 -0
  59. {rsloop-0.1.51 → rsloop-0.1.52}/examples/fastapi_service.py +0 -0
  60. {rsloop-0.1.51 → rsloop-0.1.52}/examples/granian_service.py +0 -0
  61. {rsloop-0.1.51 → rsloop-0.1.52}/examples/picows_server.py +0 -0
  62. {rsloop-0.1.51 → rsloop-0.1.52}/examples/picows_test.py +0 -0
  63. {rsloop-0.1.51 → rsloop-0.1.52}/examples/wsbench_websockets.py +0 -0
  64. {rsloop-0.1.51 → rsloop-0.1.52}/pyrightconfig.json +0 -0
  65. {rsloop-0.1.51 → rsloop-0.1.52}/python/rsloop/__init__.py +0 -0
  66. {rsloop-0.1.51 → rsloop-0.1.52}/python/rsloop/_bootstrap.py +0 -0
  67. {rsloop-0.1.51 → rsloop-0.1.52}/python/rsloop/_loop.pyi +0 -0
  68. {rsloop-0.1.51 → rsloop-0.1.52}/python/rsloop/_run.py +0 -0
  69. {rsloop-0.1.51 → rsloop-0.1.52}/python/rsloop/py.typed +0 -0
  70. {rsloop-0.1.51 → rsloop-0.1.52}/rust-toolchain.toml +0 -0
  71. {rsloop-0.1.51 → rsloop-0.1.52}/scripts/build-pgo-wheels.sh +0 -0
  72. {rsloop-0.1.51 → rsloop-0.1.52}/scripts/build-wheels.sh +0 -0
  73. {rsloop-0.1.51 → rsloop-0.1.52}/scripts/generate_test_tls_certs.py +0 -0
  74. {rsloop-0.1.51 → rsloop-0.1.52}/scripts/prepare_anyio_rsloop_tests.py +0 -0
  75. {rsloop-0.1.51 → rsloop-0.1.52}/scripts/python-versions.sh +0 -0
  76. {rsloop-0.1.51 → rsloop-0.1.52}/scripts/run_all_tests.py +0 -0
  77. {rsloop-0.1.51 → rsloop-0.1.52}/scripts/run_python_tests.py +0 -0
  78. {rsloop-0.1.51 → rsloop-0.1.52}/scripts/run_rust_tests.py +0 -0
  79. {rsloop-0.1.51 → rsloop-0.1.52}/scripts/test-supported-pythons.sh +0 -0
  80. {rsloop-0.1.51 → rsloop-0.1.52}/src/async_event.rs +0 -0
  81. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/asyncgens.rs +0 -0
  82. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/asyncio_cache.rs +0 -0
  83. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/connections.rs +0 -0
  84. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/executor.rs +0 -0
  85. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/fast_callbacks.rs +0 -0
  86. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/ffi_helpers.rs +0 -0
  87. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/lifecycle.rs +0 -0
  88. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/methods.rs +0 -0
  89. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/pipes.rs +0 -0
  90. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/pre_exec.rs +0 -0
  91. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/process_handles.rs +0 -0
  92. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/process_spawn.rs +0 -0
  93. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/process_stdio.rs +0 -0
  94. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/servers.rs +0 -0
  95. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/signals.rs +0 -0
  96. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/sock_ops.rs +0 -0
  97. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/socket_connect.rs +0 -0
  98. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/socket_operation.rs +0 -0
  99. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/sockets.rs +0 -0
  100. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/spawn_env.rs +0 -0
  101. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/tasks.rs +0 -0
  102. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/tls_params.rs +0 -0
  103. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api/watchers.rs +0 -0
  104. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/loop_api.rs +0 -0
  105. {rsloop-0.1.51 → rsloop-0.1.52}/src/bindings/mod.rs +0 -0
  106. {rsloop-0.1.51 → rsloop-0.1.52}/src/blocking.rs +0 -0
  107. {rsloop-0.1.51 → rsloop-0.1.52}/src/build_metadata.rs +0 -0
  108. {rsloop-0.1.51 → rsloop-0.1.52}/src/context.rs +0 -0
  109. {rsloop-0.1.51 → rsloop-0.1.52}/src/engine/callbacks.rs +0 -0
  110. {rsloop-0.1.51 → rsloop-0.1.52}/src/engine/mod.rs +0 -0
  111. {rsloop-0.1.51 → rsloop-0.1.52}/src/engine/timer_entry.rs +0 -0
  112. {rsloop-0.1.51 → rsloop-0.1.52}/src/errors.rs +0 -0
  113. {rsloop-0.1.51 → rsloop-0.1.52}/src/lib.rs +0 -0
  114. {rsloop-0.1.51 → rsloop-0.1.52}/src/module_init.rs +0 -0
  115. {rsloop-0.1.51 → rsloop-0.1.52}/src/platform/fd/mod.rs +0 -0
  116. {rsloop-0.1.51 → rsloop-0.1.52}/src/platform/fd/windows.rs +0 -0
  117. {rsloop-0.1.51 → rsloop-0.1.52}/src/platform/mod.rs +0 -0
  118. {rsloop-0.1.51 → rsloop-0.1.52}/src/python_names.rs +0 -0
  119. {rsloop-0.1.51 → rsloop-0.1.52}/src/rust_async.rs +0 -0
  120. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/mod.rs +0 -0
  121. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/process/core_events.rs +0 -0
  122. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/process/core_protocol.rs +0 -0
  123. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/process/core_state.rs +0 -0
  124. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/process/mod.rs +0 -0
  125. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/process/params.rs +0 -0
  126. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/process/py_pipes.rs +0 -0
  127. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/process/py_transport.rs +0 -0
  128. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/process/spawn.rs +0 -0
  129. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/process/worker.rs +0 -0
  130. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/buffers.rs +0 -0
  131. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/builder.rs +0 -0
  132. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/connect.rs +0 -0
  133. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/core_events.rs +0 -0
  134. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/core_protocol.rs +0 -0
  135. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/core_state.rs +0 -0
  136. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/core_write.rs +0 -0
  137. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/fast.rs +0 -0
  138. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/io_targets.rs +0 -0
  139. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/pipe_transport.rs +0 -0
  140. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/platform.rs +0 -0
  141. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/poll.rs +0 -0
  142. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/protocol.rs +0 -0
  143. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/py_transport.rs +0 -0
  144. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/reader.rs +0 -0
  145. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/reader_task.rs +0 -0
  146. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/server_types.rs +0 -0
  147. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/socket_transport.rs +0 -0
  148. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/stats.rs +0 -0
  149. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/tls_session.rs +0 -0
  150. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/tls_transport.rs +0 -0
  151. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/tuning.rs +0 -0
  152. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/worker.rs +0 -0
  153. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/write_queue.rs +0 -0
  154. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/stream/writer.rs +0 -0
  155. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/tls/material.rs +0 -0
  156. {rsloop-0.1.51 → rsloop-0.1.52}/src/transport/tls/mod.rs +0 -0
  157. {rsloop-0.1.51 → rsloop-0.1.52}/src/verification.rs +0 -0
  158. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/UPSTREAM.md +0 -0
  159. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/blocking/default.rs +0 -0
  160. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/blocking/mod.rs +0 -0
  161. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/builder.rs +0 -0
  162. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/driver/iocp.rs +0 -0
  163. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/driver/kqueue.rs +0 -0
  164. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/driver/mio.rs +0 -0
  165. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/driver/mock.rs +0 -0
  166. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/driver/mod.rs +0 -0
  167. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/driver/uring.rs +0 -0
  168. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/executor.rs +0 -0
  169. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/fd_inner.rs +0 -0
  170. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/fs/file.rs +0 -0
  171. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/fs/metadata.rs +0 -0
  172. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/fs/mod.rs +0 -0
  173. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/fs/open_options.rs +0 -0
  174. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/io/buf.rs +0 -0
  175. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/io/mod.rs +0 -0
  176. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/io/pipe.rs +0 -0
  177. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/io/splice.rs +0 -0
  178. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/io/stdio.rs +0 -0
  179. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/io/util.rs +0 -0
  180. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/lib.rs +0 -0
  181. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/net/mod.rs +0 -0
  182. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/net/tcp/listener.rs +0 -0
  183. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/net/tcp/mod.rs +0 -0
  184. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/net/tcp/stream.rs +0 -0
  185. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/net/udp.rs +0 -0
  186. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/net/unix/listener.rs +0 -0
  187. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/net/unix/mod.rs +0 -0
  188. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/net/unix/stream.rs +0 -0
  189. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/accept.rs +0 -0
  190. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/accept_unix.rs +0 -0
  191. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/connect.rs +0 -0
  192. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/fsync.rs +0 -0
  193. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/hard_link.rs +0 -0
  194. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/io_util.rs +0 -0
  195. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/mkdir.rs +0 -0
  196. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/mod.rs +0 -0
  197. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/open.rs +0 -0
  198. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/read.rs +0 -0
  199. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/readat.rs +0 -0
  200. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/readiness.rs +0 -0
  201. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/readv.rs +0 -0
  202. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/recv.rs +0 -0
  203. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/recvfrom.rs +0 -0
  204. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/rename.rs +0 -0
  205. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/send.rs +0 -0
  206. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/sendto.rs +0 -0
  207. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/socket_addr.rs +0 -0
  208. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/splice.rs +0 -0
  209. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/statx.rs +0 -0
  210. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/symlink.rs +0 -0
  211. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/unlink.rs +0 -0
  212. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/waitpid.rs +0 -0
  213. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/write.rs +0 -0
  214. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/writeat.rs +0 -0
  215. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/op/writev.rs +0 -0
  216. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/process/mod.rs +0 -0
  217. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/process/reaper.rs +0 -0
  218. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/signal/mod.rs +0 -0
  219. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/signal/unix.rs +0 -0
  220. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/signal/windows.rs +0 -0
  221. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/task.rs +0 -0
  222. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/test_support.rs +0 -0
  223. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/time/interval.rs +0 -0
  224. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/time/mod.rs +0 -0
  225. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/time/sleep.rs +0 -0
  226. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/time/timeout.rs +0 -0
  227. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/timer.rs +0 -0
  228. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/util/async_wrap.rs +0 -0
  229. {rsloop-0.1.51 → rsloop-0.1.52}/src/vibeio/util/mod.rs +0 -0
  230. {rsloop-0.1.51 → rsloop-0.1.52}/tests/conftest.py +0 -0
  231. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/_smoke.py +0 -0
  232. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/aiohttp_test.py +0 -0
  233. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/anyio_test.py +0 -0
  234. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/beanie_test.py +0 -0
  235. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/daphne_test.py +0 -0
  236. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/django_asgi_test.py +0 -0
  237. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/django_orm_test.py +0 -0
  238. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/edgy_test.py +0 -0
  239. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/falcon_test.py +0 -0
  240. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/fastapi_test.py +0 -0
  241. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/faststream_test.py +0 -0
  242. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/hypercorn_test.py +0 -0
  243. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/litestar_granian_test.py +0 -0
  244. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/litestar_test.py +0 -0
  245. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/mangum_test.py +0 -0
  246. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/ormar_test.py +0 -0
  247. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/piccolo_test.py +0 -0
  248. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/quart_test.py +0 -0
  249. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/sanic_test.py +0 -0
  250. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/sqlalchemy_test.py +0 -0
  251. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/sqlmodel_test.py +0 -0
  252. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/starlette_test.py +0 -0
  253. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/tortoise_orm_test.py +0 -0
  254. {rsloop-0.1.51 → rsloop-0.1.52}/tests/integration/packages/uvicorn_test.py +0 -0
  255. {rsloop-0.1.51 → rsloop-0.1.52}/tests/proptest-regressions/transport/stream/fast.txt +0 -0
  256. {rsloop-0.1.51 → rsloop-0.1.52}/tests/test_buffered_delivery.py +0 -0
  257. {rsloop-0.1.51 → rsloop-0.1.52}/tests/test_compat.py +0 -0
  258. {rsloop-0.1.51 → rsloop-0.1.52}/tests/test_fast_callbacks.py +0 -0
  259. {rsloop-0.1.51 → rsloop-0.1.52}/tests/test_free_threading.py +0 -0
  260. {rsloop-0.1.51 → rsloop-0.1.52}/tests/test_local_sockets.py +0 -0
  261. {rsloop-0.1.51 → rsloop-0.1.52}/tests/test_local_timers.py +0 -0
  262. {rsloop-0.1.51 → rsloop-0.1.52}/tests/test_numeric_addrinfo.py +0 -0
  263. {rsloop-0.1.51 → rsloop-0.1.52}/tests/test_run.py +0 -0
  264. {rsloop-0.1.51 → rsloop-0.1.52}/tests/test_stream_reader.py +0 -0
  265. {rsloop-0.1.51 → rsloop-0.1.52}/tests/test_subprocesses.py +0 -0
  266. {rsloop-0.1.51 → rsloop-0.1.52}/tests/test_tls.py +0 -0
  267. {rsloop-0.1.51 → rsloop-0.1.52}/tests/test_write_reentrancy.py +0 -0
  268. {rsloop-0.1.51 → rsloop-0.1.52}/tests/tooling/test_benchmark_loops.py +0 -0
  269. {rsloop-0.1.51 → rsloop-0.1.52}/tests/tooling/test_granian_benchmark.py +0 -0
  270. {rsloop-0.1.51 → rsloop-0.1.52}/tests/tooling/test_hotpath_lab.py +0 -0
  271. {rsloop-0.1.51 → rsloop-0.1.52}/tests/tooling/test_test_runner.py +0 -0
  272. {rsloop-0.1.51 → rsloop-0.1.52}/tests/typing/public_api.py +0 -0
@@ -869,7 +869,7 @@ dependencies = [
869
869
 
870
870
  [[package]]
871
871
  name = "rsloop"
872
- version = "0.1.51"
872
+ version = "0.1.52"
873
873
  dependencies = [
874
874
  "async-channel 2.5.0",
875
875
  "async-io",
@@ -1,45 +1,37 @@
1
1
  [package]
2
2
  name = "rsloop"
3
- version = "0.1.51"
3
+ version = "0.1.52"
4
4
  edition = "2024"
5
5
  description = "An event loop for asyncio written in Rust"
6
- license = "Apache-2.0"
6
+ documentation = "https://github.com/RustedBytes/rsloop#readme"
7
7
  readme = "README.md"
8
- repository = "https://github.com/RustedBytes/rsloop"
9
8
  homepage = "https://github.com/RustedBytes/rsloop"
10
- documentation = "https://github.com/RustedBytes/rsloop#readme"
9
+ repository = "https://github.com/RustedBytes/rsloop"
10
+ license = "Apache-2.0"
11
+
12
+ [package.metadata.kani.flags]
13
+ # Force every proof that reaches a loop to state and review its own bound.
14
+ default-unwind = "1"
11
15
 
12
16
  [lib]
13
- name = "rsloop"
14
17
  crate-type = ["cdylib", "rlib"]
15
-
16
- [features]
17
- default = []
18
- # Embedded-runtime modules are opt-in; production wheels retain the default
19
- # networking/timer build unless a feature is explicitly requested.
20
- fs = []
21
- process = ["dep:async-channel"]
22
- signal = ["dep:once_cell", "dep:errno"]
23
- pipe = []
24
- stdio = []
25
- splice = []
26
- blocking-default = ["dep:rusty_pool"]
18
+ name = "rsloop"
27
19
 
28
20
  [dependencies]
29
- errno = { version = "0.3", optional = true }
30
21
  async-channel = { version = "2", optional = true }
31
22
  async-io = "2"
32
23
  async-std = "1"
33
24
  crossbeam-channel = "0.5"
34
25
  crossbeam-queue = "0.3"
26
+ errno = { version = "0.3", optional = true }
35
27
  futures = { version = "0.3", default-features = false, features = ["std"] }
36
28
  futures-util = "0.3"
37
29
  libc = "0.2"
38
30
  memchr = "2"
39
31
  mio = "1"
32
+ once_cell = { version = "1", optional = true }
40
33
  oneshot = { version = "0.2", features = ["async", "std"] }
41
34
  pin-project-lite = "0.2"
42
- once_cell = { version = "1", optional = true }
43
35
  pyo3 = { version = "0.29.2" }
44
36
  pyo3-async-runtimes = { version = "0.29", features = ["async-std-runtime"] }
45
37
  rustls = "0.23"
@@ -50,48 +42,57 @@ signal-hook = "0.4"
50
42
  slab = "0.4"
51
43
  socket2 = "0.6"
52
44
  tokio = { version = "1", default-features = false, features = ["io-util"] }
45
+
46
+ [dev-dependencies]
47
+ proptest = { version = "1", default-features = false, features = ["std"] }
48
+
49
+ [build-dependencies]
50
+ pyo3-build-config = "0.29.2"
51
+
53
52
  [target.'cfg(target_os = "linux")'.dependencies]
54
53
  io-uring = "0.7"
55
54
 
56
- [target.'cfg(unix)'.dependencies]
57
- mio = { version = "1", features = ["os-poll", "os-ext"] }
55
+ [target."cfg(unix)".dependencies]
56
+ mio = { version = "1", features = ["os-ext", "os-poll"] }
58
57
 
59
- [target.'cfg(windows)'.dependencies]
58
+ [target."cfg(windows)".dependencies]
60
59
  windows-sys = { version = "0.61", features = ["Wdk_Foundation", "Wdk_Storage_FileSystem", "Wdk_System_IO", "Wdk_System_SystemServices", "Win32_Foundation", "Win32_Networking_WinSock", "Win32_Security", "Win32_Storage_FileSystem", "Win32_System_Console", "Win32_System_IO", "Win32_System_Pipes", "Win32_System_SystemInformation", "Win32_System_Threading"] }
61
60
 
62
- [build-dependencies]
63
- pyo3-build-config = "0.29.2"
64
-
65
- [dev-dependencies]
66
- proptest = { version = "1", default-features = false, features = ["std"] }
61
+ [features]
62
+ default = []
63
+ blocking-default = ["dep:rusty_pool"]
64
+ # Embedded-runtime modules are opt-in; production wheels retain the default
65
+ # networking/timer build unless a feature is explicitly requested.
66
+ fs = []
67
+ pipe = []
68
+ process = ["dep:async-channel"]
69
+ signal = ["dep:errno", "dep:once_cell"]
70
+ splice = []
71
+ stdio = []
67
72
 
68
73
  [lints.clippy]
74
+ await_holding_lock = "warn"
75
+ await_holding_refcell_ref = "warn"
76
+ cast_ptr_alignment = "warn"
77
+ complexity = { level = "warn", priority = -1 }
69
78
  # Enforce bug, concurrency, and performance checks rather than style preferences.
70
79
  correctness = { level = "deny", priority = -1 }
71
- suspicious = { level = "warn", priority = -1 }
72
- perf = { level = "warn", priority = -1 }
73
- complexity = { level = "warn", priority = -1 }
74
- style = { level = "allow", priority = -1 }
75
- pedantic = { level = "allow", priority = -1 }
76
80
  # Keep safety checks even when they belong to an otherwise disabled group.
77
81
  missing_safety_doc = "warn"
78
- cast_ptr_alignment = "warn"
79
- await_holding_lock = "warn"
80
- await_holding_refcell_ref = "warn"
82
+ pedantic = { level = "allow", priority = -1 }
83
+ perf = { level = "warn", priority = -1 }
84
+ style = { level = "allow", priority = -1 }
85
+ suspicious = { level = "warn", priority = -1 }
81
86
 
82
87
  [lints.rust]
83
88
  unexpected_cfgs = { level = "warn", check-cfg = ["cfg(kani)", "cfg(musl_v1_2_3)", "cfg(syscall_accept4)", "cfg(feature, values(\"blocking-default\", \"fs\", \"pipe\", \"process\", \"signal\", \"splice\", \"stdio\"))"] }
84
89
 
85
- [package.metadata.kani.flags]
86
- # Force every proof that reaches a loop to state and review its own bound.
87
- default-unwind = "1"
90
+ [profile.bench]
91
+ inherits = "release"
88
92
 
89
93
  [profile.release]
90
94
  opt-level = 3
91
95
  lto = "fat"
92
- codegen-units = 1
93
96
  incremental = false
97
+ codegen-units = 1
94
98
  # strip = true
95
-
96
- [profile.bench]
97
- inherits = "release"
rsloop-0.1.52/PKG-INFO ADDED
@@ -0,0 +1,201 @@
1
+ Metadata-Version: 2.4
2
+ Name: rsloop
3
+ Version: 0.1.52
4
+ Classifier: Development Status :: 3 - Alpha
5
+ Classifier: Intended Audience :: Developers
6
+ Classifier: License :: OSI Approved :: Apache Software License
7
+ Classifier: Operating System :: MacOS
8
+ Classifier: Operating System :: Microsoft :: Windows
9
+ Classifier: Operating System :: POSIX :: Linux
10
+ Classifier: Programming Language :: Python
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3 :: Only
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Classifier: Programming Language :: Python :: Free Threading :: 2 - Beta
19
+ Classifier: Programming Language :: Rust
20
+ Classifier: Topic :: Software Development :: Libraries
21
+ Classifier: Topic :: System :: Networking
22
+ License-File: LICENSE
23
+ Summary: An event loop for asyncio written in Rust
24
+ Keywords: asyncio,event-loop,pyo3,python,rust
25
+ Home-Page: https://github.com/RustedBytes/rsloop
26
+ Author: Yehor Smoliakov <egorsmkv@gmail.com>
27
+ Requires-Python: >=3.10
28
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
29
+ Project-URL: Homepage, https://github.com/RustedBytes/rsloop
30
+ Project-URL: Issues, https://github.com/RustedBytes/rsloop/issues
31
+ Project-URL: Repository, https://github.com/RustedBytes/rsloop
32
+
33
+ <img src="./docs/rsloop.png" alt="rsloop logo" align="center">
34
+
35
+ # An event loop for asyncio written in Rust
36
+
37
+ [![PyPI - Version](https://img.shields.io/pypi/v/rsloop)](https://pypi.org/project/rsloop/)
38
+ [![Tests](https://github.com/RustedBytes/rsloop/actions/workflows/tests.yml/badge.svg)](https://github.com/RustedBytes/rsloop/actions/workflows/tests.yml)
39
+ [![PyPI Downloads](https://static.pepy.tech/personalized-badge/rsloop?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/rsloop)
40
+
41
+ `rsloop` is a PyO3-based `asyncio` event loop implemented in Rust.
42
+
43
+ Each `rsloop.Loop` owns a dedicated Rust runtime thread for loop coordination
44
+ and I/O work. That thread runs an rsloop-specialized `vibeio` runtime, using
45
+ io_uring on Linux, IOCP on Windows, and native kqueue readiness on macOS.
46
+ Native-stream TCP reads and Unix-domain socket reads run on that runtime. On Unix, generic
47
+ TCP protocol readers use a second `vibeio` runtime on the Python loop thread
48
+ (io_uring on Linux), avoiding cross-thread delivery of each read. Non-TLS accepts
49
+ run on either runtime depending on where the server starts. Python callbacks,
50
+ tasks, and coroutines run on the thread that calls
51
+ `run_forever()` or `run_until_complete()` (usually the main Python thread).
52
+
53
+ The package exposes:
54
+
55
+ - a native extension module at `rsloop._loop`
56
+ - a Python wrapper in [`python/rsloop/__init__.py`](./python/rsloop/__init__.py)
57
+ - `rsloop.Loop`, `rsloop.EventLoopPolicy`, `rsloop.new_event_loop()`,
58
+ `rsloop.run(...)`, `rsloop.install()`, `rsloop.uninstall()`, and
59
+ `rsloop.build_info()`
60
+
61
+ Repository metadata currently targets Python `>=3.10`.
62
+ The native runtime requires Linux 6.1+, macOS 13+, or Windows 10+ so its hot
63
+ paths can rely on modern completion, timer, and scheduler primitives.
64
+ Free-threaded CPython (`3.14t`) is supported: the extension declares
65
+ `gil_used = false`, so importing it no longer re-enables the GIL. See
66
+ [Free-Threaded CPython](./docs/free-threading.md) for what that does and does not
67
+ buy you.
68
+
69
+ ## Documentation
70
+
71
+ Project documentation now lives in [`docs/`](./docs/).
72
+
73
+ If you are new to the repository, start with:
74
+
75
+ - [`docs/index.md`](./docs/index.md)
76
+ - [`docs/getting-started.md`](./docs/getting-started.md)
77
+ - [`docs/supported-features.md`](./docs/supported-features.md)
78
+ - [`docs/fast-streams.md`](./docs/fast-streams.md)
79
+ - [`docs/free-threading.md`](./docs/free-threading.md)
80
+ - [`docs/rust-extensions.md`](./docs/rust-extensions.md)
81
+ - [`docs/how-it-works.md`](./docs/how-it-works.md)
82
+ - [`docs/project-structure.md`](./docs/project-structure.md)
83
+ - [`docs/development.md`](./docs/development.md) for building, testing, and profiling
84
+
85
+ To browse the docs locally with MkDocs:
86
+
87
+ ```bash
88
+ uvx --from mkdocs mkdocs serve
89
+ ```
90
+
91
+ ## Install
92
+
93
+ From PyPI:
94
+
95
+ ```bash
96
+ pip install rsloop
97
+ ```
98
+
99
+ With `uv`:
100
+
101
+ ```bash
102
+ uv add rsloop
103
+ ```
104
+
105
+ From [conda-forge](https://conda-forge.org), using [pixi](https://pixi.prefix.dev/latest/#installation):
106
+
107
+ ```bash
108
+ pixi add rsloop
109
+ ```
110
+
111
+ ## Usage
112
+
113
+ Simple entry point:
114
+
115
+ ```python
116
+ import rsloop
117
+
118
+
119
+ async def main(): ...
120
+
121
+
122
+ rsloop.run(main())
123
+ ```
124
+
125
+ Install as the default asyncio event loop policy:
126
+
127
+ ```python
128
+ import asyncio
129
+ import rsloop
130
+
131
+ rsloop.install()
132
+ try:
133
+ asyncio.run(main())
134
+ finally:
135
+ rsloop.uninstall()
136
+ ```
137
+
138
+ Manual loop creation also works:
139
+
140
+ ```python
141
+ import asyncio
142
+ import rsloop
143
+
144
+ loop = rsloop.new_event_loop()
145
+ asyncio.set_event_loop(loop)
146
+ try:
147
+ loop.run_until_complete(...)
148
+ finally:
149
+ asyncio.set_event_loop(None)
150
+ loop.close()
151
+ ```
152
+
153
+ Importing `rsloop` also patches `asyncio.set_event_loop()` so Python 3.10 can
154
+ accept an `rsloop.Loop` instance, matching the behavior exercised by
155
+ [`tests/test_run.py`](./tests/test_run.py).
156
+
157
+ ## Examples
158
+
159
+ Run the repository examples from the project root:
160
+
161
+ ```bash
162
+ uv run python examples/01_basics.py
163
+ uv run python examples/02_fd_and_sockets.py
164
+ uv run python examples/03_streams.py
165
+ uv run python examples/04_unix_and_accepted_socket.py
166
+ uv run python examples/05_pipes_signals_subprocesses.py
167
+ ```
168
+
169
+ Example files:
170
+ [`examples/01_basics.py`](./examples/01_basics.py),
171
+ [`examples/02_fd_and_sockets.py`](./examples/02_fd_and_sockets.py),
172
+ [`examples/03_streams.py`](./examples/03_streams.py),
173
+ [`examples/04_unix_and_accepted_socket.py`](./examples/04_unix_and_accepted_socket.py),
174
+ [`examples/05_pipes_signals_subprocesses.py`](./examples/05_pipes_signals_subprocesses.py).
175
+
176
+ The repository also includes:
177
+
178
+ - [`examples/fastapi_service.py`](./examples/fastapi_service.py) for running the same
179
+ FastAPI app on stdlib `asyncio`, `uvloop`, or `rsloop`
180
+ - [`examples/granian_service.py`](./examples/granian_service.py) for registering
181
+ `rsloop` as Granian's worker event loop
182
+ - [`benches/compare_event_loops.py`](./benches/compare_event_loops.py)
183
+ for callback, task, and TCP stream comparisons
184
+ - [`benches/compare_granian.py`](./benches/compare_granian.py) for Granian HTTP
185
+ throughput and latency comparisons with `oha`
186
+
187
+ ## Benchmarks
188
+
189
+ See [benchmark results and reproduction commands](./docs/benchmarks.md).
190
+
191
+ ## Acknowledgements
192
+
193
+ `rsloop` builds on the Python `asyncio` model and is implemented with
194
+ [PyO3](https://pyo3.rs/) on the Rust side. Runtime and socket I/O are powered by
195
+ [vibeio](https://crates.io/crates/vibeio).
196
+
197
+ ## License
198
+
199
+ This project is licensed under the Apache License, Version 2.0. See
200
+ [`LICENSE`](./LICENSE) for the full text.
201
+
@@ -0,0 +1,168 @@
1
+ <img src="./docs/rsloop.png" alt="rsloop logo" align="center">
2
+
3
+ # An event loop for asyncio written in Rust
4
+
5
+ [![PyPI - Version](https://img.shields.io/pypi/v/rsloop)](https://pypi.org/project/rsloop/)
6
+ [![Tests](https://github.com/RustedBytes/rsloop/actions/workflows/tests.yml/badge.svg)](https://github.com/RustedBytes/rsloop/actions/workflows/tests.yml)
7
+ [![PyPI Downloads](https://static.pepy.tech/personalized-badge/rsloop?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/rsloop)
8
+
9
+ `rsloop` is a PyO3-based `asyncio` event loop implemented in Rust.
10
+
11
+ Each `rsloop.Loop` owns a dedicated Rust runtime thread for loop coordination
12
+ and I/O work. That thread runs an rsloop-specialized `vibeio` runtime, using
13
+ io_uring on Linux, IOCP on Windows, and native kqueue readiness on macOS.
14
+ Native-stream TCP reads and Unix-domain socket reads run on that runtime. On Unix, generic
15
+ TCP protocol readers use a second `vibeio` runtime on the Python loop thread
16
+ (io_uring on Linux), avoiding cross-thread delivery of each read. Non-TLS accepts
17
+ run on either runtime depending on where the server starts. Python callbacks,
18
+ tasks, and coroutines run on the thread that calls
19
+ `run_forever()` or `run_until_complete()` (usually the main Python thread).
20
+
21
+ The package exposes:
22
+
23
+ - a native extension module at `rsloop._loop`
24
+ - a Python wrapper in [`python/rsloop/__init__.py`](./python/rsloop/__init__.py)
25
+ - `rsloop.Loop`, `rsloop.EventLoopPolicy`, `rsloop.new_event_loop()`,
26
+ `rsloop.run(...)`, `rsloop.install()`, `rsloop.uninstall()`, and
27
+ `rsloop.build_info()`
28
+
29
+ Repository metadata currently targets Python `>=3.10`.
30
+ The native runtime requires Linux 6.1+, macOS 13+, or Windows 10+ so its hot
31
+ paths can rely on modern completion, timer, and scheduler primitives.
32
+ Free-threaded CPython (`3.14t`) is supported: the extension declares
33
+ `gil_used = false`, so importing it no longer re-enables the GIL. See
34
+ [Free-Threaded CPython](./docs/free-threading.md) for what that does and does not
35
+ buy you.
36
+
37
+ ## Documentation
38
+
39
+ Project documentation now lives in [`docs/`](./docs/).
40
+
41
+ If you are new to the repository, start with:
42
+
43
+ - [`docs/index.md`](./docs/index.md)
44
+ - [`docs/getting-started.md`](./docs/getting-started.md)
45
+ - [`docs/supported-features.md`](./docs/supported-features.md)
46
+ - [`docs/fast-streams.md`](./docs/fast-streams.md)
47
+ - [`docs/free-threading.md`](./docs/free-threading.md)
48
+ - [`docs/rust-extensions.md`](./docs/rust-extensions.md)
49
+ - [`docs/how-it-works.md`](./docs/how-it-works.md)
50
+ - [`docs/project-structure.md`](./docs/project-structure.md)
51
+ - [`docs/development.md`](./docs/development.md) for building, testing, and profiling
52
+
53
+ To browse the docs locally with MkDocs:
54
+
55
+ ```bash
56
+ uvx --from mkdocs mkdocs serve
57
+ ```
58
+
59
+ ## Install
60
+
61
+ From PyPI:
62
+
63
+ ```bash
64
+ pip install rsloop
65
+ ```
66
+
67
+ With `uv`:
68
+
69
+ ```bash
70
+ uv add rsloop
71
+ ```
72
+
73
+ From [conda-forge](https://conda-forge.org), using [pixi](https://pixi.prefix.dev/latest/#installation):
74
+
75
+ ```bash
76
+ pixi add rsloop
77
+ ```
78
+
79
+ ## Usage
80
+
81
+ Simple entry point:
82
+
83
+ ```python
84
+ import rsloop
85
+
86
+
87
+ async def main(): ...
88
+
89
+
90
+ rsloop.run(main())
91
+ ```
92
+
93
+ Install as the default asyncio event loop policy:
94
+
95
+ ```python
96
+ import asyncio
97
+ import rsloop
98
+
99
+ rsloop.install()
100
+ try:
101
+ asyncio.run(main())
102
+ finally:
103
+ rsloop.uninstall()
104
+ ```
105
+
106
+ Manual loop creation also works:
107
+
108
+ ```python
109
+ import asyncio
110
+ import rsloop
111
+
112
+ loop = rsloop.new_event_loop()
113
+ asyncio.set_event_loop(loop)
114
+ try:
115
+ loop.run_until_complete(...)
116
+ finally:
117
+ asyncio.set_event_loop(None)
118
+ loop.close()
119
+ ```
120
+
121
+ Importing `rsloop` also patches `asyncio.set_event_loop()` so Python 3.10 can
122
+ accept an `rsloop.Loop` instance, matching the behavior exercised by
123
+ [`tests/test_run.py`](./tests/test_run.py).
124
+
125
+ ## Examples
126
+
127
+ Run the repository examples from the project root:
128
+
129
+ ```bash
130
+ uv run python examples/01_basics.py
131
+ uv run python examples/02_fd_and_sockets.py
132
+ uv run python examples/03_streams.py
133
+ uv run python examples/04_unix_and_accepted_socket.py
134
+ uv run python examples/05_pipes_signals_subprocesses.py
135
+ ```
136
+
137
+ Example files:
138
+ [`examples/01_basics.py`](./examples/01_basics.py),
139
+ [`examples/02_fd_and_sockets.py`](./examples/02_fd_and_sockets.py),
140
+ [`examples/03_streams.py`](./examples/03_streams.py),
141
+ [`examples/04_unix_and_accepted_socket.py`](./examples/04_unix_and_accepted_socket.py),
142
+ [`examples/05_pipes_signals_subprocesses.py`](./examples/05_pipes_signals_subprocesses.py).
143
+
144
+ The repository also includes:
145
+
146
+ - [`examples/fastapi_service.py`](./examples/fastapi_service.py) for running the same
147
+ FastAPI app on stdlib `asyncio`, `uvloop`, or `rsloop`
148
+ - [`examples/granian_service.py`](./examples/granian_service.py) for registering
149
+ `rsloop` as Granian's worker event loop
150
+ - [`benches/compare_event_loops.py`](./benches/compare_event_loops.py)
151
+ for callback, task, and TCP stream comparisons
152
+ - [`benches/compare_granian.py`](./benches/compare_granian.py) for Granian HTTP
153
+ throughput and latency comparisons with `oha`
154
+
155
+ ## Benchmarks
156
+
157
+ See [benchmark results and reproduction commands](./docs/benchmarks.md).
158
+
159
+ ## Acknowledgements
160
+
161
+ `rsloop` builds on the Python `asyncio` model and is implemented with
162
+ [PyO3](https://pyo3.rs/) on the Rust side. Runtime and socket I/O are powered by
163
+ [vibeio](https://crates.io/crates/vibeio).
164
+
165
+ ## License
166
+
167
+ This project is licensed under the Apache License, Version 2.0. See
168
+ [`LICENSE`](./LICENSE) for the full text.
@@ -533,9 +533,7 @@ def run_child(
533
533
  if not lines:
534
534
  raise RuntimeError(f"{loop_name}/{workload} produced no output")
535
535
  payload = next(
536
- json.loads(line)
537
- for line in reversed(lines)
538
- if line.lstrip().startswith("{")
536
+ json.loads(line) for line in reversed(lines) if line.lstrip().startswith("{")
539
537
  )
540
538
  return ChildResult(
541
539
  loop=payload["loop"],