zuvloop 0.0.1__tar.gz → 0.0.2__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 (499) hide show
  1. {zuvloop-0.0.1 → zuvloop-0.0.2}/PKG-INFO +22 -18
  2. {zuvloop-0.0.1 → zuvloop-0.0.2}/README.md +20 -16
  3. {zuvloop-0.0.1 → zuvloop-0.0.2}/build.zig +6 -1
  4. {zuvloop-0.0.1 → zuvloop-0.0.2}/pyproject.toml +1 -1
  5. {zuvloop-0.0.1 → zuvloop-0.0.2}/zig/addr.zig +52 -5
  6. {zuvloop-0.0.1 → zuvloop-0.0.2}/zig/collections.zig +27 -8
  7. {zuvloop-0.0.1 → zuvloop-0.0.2}/zig/datagram.zig +49 -6
  8. {zuvloop-0.0.1 → zuvloop-0.0.2}/zig/dns.zig +104 -5
  9. {zuvloop-0.0.1 → zuvloop-0.0.2}/zig/handle.zig +24 -37
  10. {zuvloop-0.0.1 → zuvloop-0.0.2}/zig/loop.zig +46 -24
  11. {zuvloop-0.0.1 → zuvloop-0.0.2}/zig/module.zig +4 -0
  12. {zuvloop-0.0.1 → zuvloop-0.0.2}/zig/poller.zig +33 -11
  13. {zuvloop-0.0.1 → zuvloop-0.0.2}/zig/process.zig +68 -26
  14. {zuvloop-0.0.1 → zuvloop-0.0.2}/zig/py.zig +12 -0
  15. zuvloop-0.0.2/zig/timer.zig +293 -0
  16. {zuvloop-0.0.1 → zuvloop-0.0.2}/zig/transport.zig +58 -21
  17. zuvloop-0.0.2/zig/tshandle.zig +333 -0
  18. {zuvloop-0.0.1 → zuvloop-0.0.2}/zig/uv.zig +17 -0
  19. {zuvloop-0.0.1 → zuvloop-0.0.2}/zuvloop/_base.py +8 -19
  20. {zuvloop-0.0.1 → zuvloop-0.0.2}/zuvloop/_connect.py +120 -26
  21. {zuvloop-0.0.1 → zuvloop-0.0.2}/zuvloop/_instrumentation.py +14 -1
  22. {zuvloop-0.0.1 → zuvloop-0.0.2}/zuvloop/_process.py +38 -2
  23. {zuvloop-0.0.1 → zuvloop-0.0.2}/zuvloop/_server.py +35 -9
  24. {zuvloop-0.0.1 → zuvloop-0.0.2}/zuvloop/_zuvloop.pyi +29 -3
  25. {zuvloop-0.0.1 → zuvloop-0.0.2}/.gitignore +0 -0
  26. {zuvloop-0.0.1 → zuvloop-0.0.2}/LICENSE +0 -0
  27. {zuvloop-0.0.1 → zuvloop-0.0.2}/build.zig.zon +0 -0
  28. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/README.md +0 -0
  29. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/.gitattributes +0 -0
  30. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/.github/ISSUE_TEMPLATE.md +0 -0
  31. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/.github/dependabot.yml +0 -0
  32. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/.github/workflows/CI-docs.yml +0 -0
  33. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/.github/workflows/CI-sample.yml +0 -0
  34. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/.github/workflows/CI-unix.yml +0 -0
  35. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/.github/workflows/CI-win.yml +0 -0
  36. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/.github/workflows/sanitizer.yml +0 -0
  37. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/.gitignore +0 -0
  38. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/.mailmap +0 -0
  39. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/.readthedocs.yaml +0 -0
  40. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/AUTHORS +0 -0
  41. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/CMakeLists.txt +0 -0
  42. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/CONTRIBUTING.md +0 -0
  43. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/ChangeLog +0 -0
  44. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/LICENSE +0 -0
  45. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/LICENSE-docs +0 -0
  46. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/LICENSE-extra +0 -0
  47. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/LINKS.md +0 -0
  48. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/MAINTAINERS.md +0 -0
  49. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/Makefile.am +0 -0
  50. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/README.md +0 -0
  51. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/SECURITY.md +0 -0
  52. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/SUPPORTED_PLATFORMS.md +0 -0
  53. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/autogen.sh +0 -0
  54. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/cmake-toolchains/cross-mingw32.cmake +0 -0
  55. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/configure.ac +0 -0
  56. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/.gitignore +0 -0
  57. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/CMakeLists.txt +0 -0
  58. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/cgi/main.c +0 -0
  59. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/cgi/tick.c +0 -0
  60. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/default-loop/main.c +0 -0
  61. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/detach/main.c +0 -0
  62. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/dns/main.c +0 -0
  63. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/helloworld/main.c +0 -0
  64. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/idle-basic/main.c +0 -0
  65. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/idle-compute/main.c +0 -0
  66. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/interfaces/main.c +0 -0
  67. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/locks/main.c +0 -0
  68. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/multi-echo-server/main.c +0 -0
  69. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/multi-echo-server/worker.c +0 -0
  70. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/onchange/main.c +0 -0
  71. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/pipe-echo-server/main.c +0 -0
  72. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/plugin/hello.c +0 -0
  73. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/plugin/main.c +0 -0
  74. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/plugin/plugin.h +0 -0
  75. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/proc-streams/main.c +0 -0
  76. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/proc-streams/test.c +0 -0
  77. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/progress/main.c +0 -0
  78. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/queue-cancel/main.c +0 -0
  79. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/queue-work/main.c +0 -0
  80. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/ref-timer/main.c +0 -0
  81. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/signal/main.c +0 -0
  82. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/spawn/main.c +0 -0
  83. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/tcp-echo-server/main.c +0 -0
  84. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/thread-create/main.c +0 -0
  85. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/tty/main.c +0 -0
  86. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/tty-gravity/main.c +0 -0
  87. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/udp-dhcp/main.c +0 -0
  88. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/uvcat/main.c +0 -0
  89. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/uvstop/main.c +0 -0
  90. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/uvtee/main.c +0 -0
  91. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/code/uvwget/main.c +0 -0
  92. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/make.bat +0 -0
  93. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/requirements.txt +0 -0
  94. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/api.rst +0 -0
  95. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/async.rst +0 -0
  96. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/check.rst +0 -0
  97. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/conf.py +0 -0
  98. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/design.rst +0 -0
  99. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/dll.rst +0 -0
  100. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/dns.rst +0 -0
  101. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/errors.rst +0 -0
  102. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/fs.rst +0 -0
  103. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/fs_event.rst +0 -0
  104. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/fs_poll.rst +0 -0
  105. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/guide/about.rst +0 -0
  106. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/guide/basics.rst +0 -0
  107. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/guide/eventloops.rst +0 -0
  108. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/guide/filesystem.rst +0 -0
  109. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/guide/introduction.rst +0 -0
  110. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/guide/networking.rst +0 -0
  111. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/guide/processes.rst +0 -0
  112. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/guide/threads.rst +0 -0
  113. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/guide/utilities.rst +0 -0
  114. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/guide.rst +0 -0
  115. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/handle.rst +0 -0
  116. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/idle.rst +0 -0
  117. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/index.rst +0 -0
  118. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/loop.rst +0 -0
  119. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/metrics.rst +0 -0
  120. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/migration_010_100.rst +0 -0
  121. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/misc.rst +0 -0
  122. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/pipe.rst +0 -0
  123. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/poll.rst +0 -0
  124. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/prepare.rst +0 -0
  125. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/process.rst +0 -0
  126. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/request.rst +0 -0
  127. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/signal.rst +0 -0
  128. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/sphinx-plugins/manpage.py +0 -0
  129. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/static/architecture.png +0 -0
  130. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/static/diagrams.key/Data/st0-311.jpg +0 -0
  131. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/static/diagrams.key/Data/st1-475.jpg +0 -0
  132. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/static/diagrams.key/Index.zip +0 -0
  133. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/static/diagrams.key/Metadata/BuildVersionHistory.plist +0 -0
  134. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/static/diagrams.key/Metadata/DocumentIdentifier +0 -0
  135. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/static/diagrams.key/Metadata/Properties.plist +0 -0
  136. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/static/diagrams.key/preview-micro.jpg +0 -0
  137. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/static/diagrams.key/preview-web.jpg +0 -0
  138. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/static/diagrams.key/preview.jpg +0 -0
  139. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/static/favicon.ico +0 -0
  140. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/static/logo.png +0 -0
  141. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/static/loop_iteration.png +0 -0
  142. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/stream.rst +0 -0
  143. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/tcp.rst +0 -0
  144. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/threading.rst +0 -0
  145. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/threadpool.rst +0 -0
  146. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/timer.rst +0 -0
  147. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/tty.rst +0 -0
  148. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/udp.rst +0 -0
  149. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/upgrading.rst +0 -0
  150. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/docs/src/version.rst +0 -0
  151. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/img/banner.png +0 -0
  152. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/img/logos.svg +0 -0
  153. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/include/uv/aix.h +0 -0
  154. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/include/uv/bsd.h +0 -0
  155. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/include/uv/darwin.h +0 -0
  156. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/include/uv/errno.h +0 -0
  157. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/include/uv/linux.h +0 -0
  158. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/include/uv/os390.h +0 -0
  159. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/include/uv/posix.h +0 -0
  160. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/include/uv/sunos.h +0 -0
  161. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/include/uv/threadpool.h +0 -0
  162. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/include/uv/tree.h +0 -0
  163. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/include/uv/unix.h +0 -0
  164. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/include/uv/version.h +0 -0
  165. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/include/uv/win.h +0 -0
  166. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/include/uv.h +0 -0
  167. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/libuv-static.pc.in +0 -0
  168. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/libuv.pc.in +0 -0
  169. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/m4/.gitignore +0 -0
  170. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/m4/as_case.m4 +0 -0
  171. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/m4/ax_pthread.m4 +0 -0
  172. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/m4/libuv-check-flags.m4 +0 -0
  173. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/fs-poll.c +0 -0
  174. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/heap-inl.h +0 -0
  175. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/idna.c +0 -0
  176. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/idna.h +0 -0
  177. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/inet.c +0 -0
  178. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/queue.h +0 -0
  179. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/random.c +0 -0
  180. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/strscpy.c +0 -0
  181. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/strscpy.h +0 -0
  182. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/strtok.c +0 -0
  183. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/strtok.h +0 -0
  184. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/thread-common.c +0 -0
  185. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/threadpool.c +0 -0
  186. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/timer.c +0 -0
  187. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/aix-common.c +0 -0
  188. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/aix.c +0 -0
  189. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/async.c +0 -0
  190. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/bsd-ifaddrs.c +0 -0
  191. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/bsd-proctitle.c +0 -0
  192. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/core.c +0 -0
  193. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/cygwin.c +0 -0
  194. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/darwin-proctitle.c +0 -0
  195. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/darwin-stub.h +0 -0
  196. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/darwin-syscalls.h +0 -0
  197. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/darwin.c +0 -0
  198. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/dl.c +0 -0
  199. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/freebsd.c +0 -0
  200. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/fs.c +0 -0
  201. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/fsevents.c +0 -0
  202. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/getaddrinfo.c +0 -0
  203. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/getnameinfo.c +0 -0
  204. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/haiku.c +0 -0
  205. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/hurd.c +0 -0
  206. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/ibmi.c +0 -0
  207. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/internal.h +0 -0
  208. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/kqueue.c +0 -0
  209. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/linux.c +0 -0
  210. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/loop-watcher.c +0 -0
  211. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/loop.c +0 -0
  212. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/netbsd.c +0 -0
  213. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/no-fsevents.c +0 -0
  214. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/no-proctitle.c +0 -0
  215. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/openbsd.c +0 -0
  216. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/os390-proctitle.c +0 -0
  217. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/os390-syscalls.c +0 -0
  218. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/os390-syscalls.h +0 -0
  219. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/os390.c +0 -0
  220. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/pipe.c +0 -0
  221. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/poll.c +0 -0
  222. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/posix-hrtime.c +0 -0
  223. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/posix-poll.c +0 -0
  224. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/process.c +0 -0
  225. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/procfs-exepath.c +0 -0
  226. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/proctitle.c +0 -0
  227. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/qnx.c +0 -0
  228. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/random-devurandom.c +0 -0
  229. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/random-getentropy.c +0 -0
  230. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/random-getrandom.c +0 -0
  231. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/random-sysctl-linux.c +0 -0
  232. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/signal.c +0 -0
  233. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/stream.c +0 -0
  234. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/sunos.c +0 -0
  235. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/sysinfo-loadavg.c +0 -0
  236. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/sysinfo-memory.c +0 -0
  237. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/tcp.c +0 -0
  238. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/thread.c +0 -0
  239. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/tty.c +0 -0
  240. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/unix/udp.c +0 -0
  241. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/uv-common.c +0 -0
  242. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/uv-common.h +0 -0
  243. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/uv-data-getter-setters.c +0 -0
  244. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/version.c +0 -0
  245. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/async.c +0 -0
  246. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/atomicops-inl.h +0 -0
  247. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/core.c +0 -0
  248. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/detect-wakeup.c +0 -0
  249. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/dl.c +0 -0
  250. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/error.c +0 -0
  251. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/fs-event.c +0 -0
  252. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/fs-fd-hash-inl.h +0 -0
  253. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/fs.c +0 -0
  254. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/getaddrinfo.c +0 -0
  255. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/getnameinfo.c +0 -0
  256. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/handle-inl.h +0 -0
  257. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/handle.c +0 -0
  258. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/internal.h +0 -0
  259. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/loop-watcher.c +0 -0
  260. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/pipe.c +0 -0
  261. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/poll.c +0 -0
  262. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/process-stdio.c +0 -0
  263. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/process.c +0 -0
  264. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/req-inl.h +0 -0
  265. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/signal.c +0 -0
  266. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/snprintf.c +0 -0
  267. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/stream-inl.h +0 -0
  268. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/stream.c +0 -0
  269. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/tcp.c +0 -0
  270. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/thread.c +0 -0
  271. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/tty.c +0 -0
  272. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/udp.c +0 -0
  273. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/util.c +0 -0
  274. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/winapi.c +0 -0
  275. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/winapi.h +0 -0
  276. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/winsock.c +0 -0
  277. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/src/win/winsock.h +0 -0
  278. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/benchmark-async-pummel.c +0 -0
  279. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/benchmark-async.c +0 -0
  280. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/benchmark-fs-stat.c +0 -0
  281. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/benchmark-getaddrinfo.c +0 -0
  282. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/benchmark-list.h +0 -0
  283. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/benchmark-loop-count.c +0 -0
  284. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/benchmark-million-async.c +0 -0
  285. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/benchmark-million-timers.c +0 -0
  286. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/benchmark-multi-accept.c +0 -0
  287. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/benchmark-ping-pongs.c +0 -0
  288. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/benchmark-ping-udp.c +0 -0
  289. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/benchmark-pound.c +0 -0
  290. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/benchmark-pump.c +0 -0
  291. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/benchmark-queue-work.c +0 -0
  292. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/benchmark-sizes.c +0 -0
  293. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/benchmark-spawn.c +0 -0
  294. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/benchmark-tcp-write-batch.c +0 -0
  295. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/benchmark-thread.c +0 -0
  296. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/benchmark-udp-pummel.c +0 -0
  297. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/blackhole-server.c +0 -0
  298. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/echo-server.c +0 -0
  299. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/fixtures/empty_file +0 -0
  300. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/fixtures/load_error.node +0 -0
  301. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/fixtures/lorem_ipsum.txt +0 -0
  302. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/fixtures/one_file/one_file +0 -0
  303. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/run-benchmarks.c +0 -0
  304. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/run-tests.c +0 -0
  305. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/runner-unix.c +0 -0
  306. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/runner-unix.h +0 -0
  307. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/runner-win.c +0 -0
  308. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/runner-win.h +0 -0
  309. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/runner.c +0 -0
  310. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/runner.h +0 -0
  311. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/task.h +0 -0
  312. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-active.c +0 -0
  313. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-async-null-cb.c +0 -0
  314. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-async.c +0 -0
  315. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-barrier.c +0 -0
  316. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-callback-stack.c +0 -0
  317. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-close-fd.c +0 -0
  318. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-close-order.c +0 -0
  319. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-condvar.c +0 -0
  320. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-connect-unspecified.c +0 -0
  321. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-connection-fail.c +0 -0
  322. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-cwd-and-chdir.c +0 -0
  323. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-default-loop-close.c +0 -0
  324. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-delayed-accept.c +0 -0
  325. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-dlerror.c +0 -0
  326. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-eintr-handling.c +0 -0
  327. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-embed.c +0 -0
  328. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-emfile.c +0 -0
  329. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-env-vars.c +0 -0
  330. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-error.c +0 -0
  331. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-fail-always.c +0 -0
  332. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-fork.c +0 -0
  333. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-fs-copyfile.c +0 -0
  334. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-fs-event.c +0 -0
  335. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-fs-fd-hash.c +0 -0
  336. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-fs-open-flags.c +0 -0
  337. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-fs-poll.c +0 -0
  338. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-fs-readdir.c +0 -0
  339. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-fs.c +0 -0
  340. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-get-currentexe.c +0 -0
  341. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-get-loadavg.c +0 -0
  342. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-get-memory.c +0 -0
  343. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-get-passwd.c +0 -0
  344. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-getaddrinfo.c +0 -0
  345. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-gethostname.c +0 -0
  346. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-getnameinfo.c +0 -0
  347. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-getsockname.c +0 -0
  348. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-getters-setters.c +0 -0
  349. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-gettimeofday.c +0 -0
  350. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-handle-fileno.c +0 -0
  351. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-homedir.c +0 -0
  352. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-hrtime.c +0 -0
  353. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-idle.c +0 -0
  354. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-idna.c +0 -0
  355. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-iouring-pollhup.c +0 -0
  356. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-ip-name.c +0 -0
  357. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-ip4-addr.c +0 -0
  358. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-ip6-addr.c +0 -0
  359. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-ipc-heavy-traffic-deadlock-bug.c +0 -0
  360. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-ipc-send-recv.c +0 -0
  361. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-ipc.c +0 -0
  362. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-list.h +0 -0
  363. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-loop-alive.c +0 -0
  364. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-loop-close.c +0 -0
  365. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-loop-configure.c +0 -0
  366. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-loop-handles.c +0 -0
  367. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-loop-oom.c +0 -0
  368. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-loop-stop.c +0 -0
  369. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-loop-time.c +0 -0
  370. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-metrics.c +0 -0
  371. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-multiple-listen.c +0 -0
  372. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-mutexes.c +0 -0
  373. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-not-readable-nor-writable-on-read-error.c +0 -0
  374. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-not-writable-after-shutdown.c +0 -0
  375. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-osx-select.c +0 -0
  376. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-pass-always.c +0 -0
  377. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-ping-pong.c +0 -0
  378. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-pipe-bind-error.c +0 -0
  379. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-pipe-close-stdout-read-stdin.c +0 -0
  380. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-pipe-connect-error.c +0 -0
  381. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-pipe-connect-multiple.c +0 -0
  382. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-pipe-connect-prepare.c +0 -0
  383. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-pipe-getsockname.c +0 -0
  384. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-pipe-pending-instances.c +0 -0
  385. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-pipe-sendmsg.c +0 -0
  386. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-pipe-server-close.c +0 -0
  387. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-pipe-set-fchmod.c +0 -0
  388. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-pipe-set-non-blocking.c +0 -0
  389. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-platform-output.c +0 -0
  390. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-poll-close-doesnt-corrupt-stack.c +0 -0
  391. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-poll-close.c +0 -0
  392. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-poll-closesocket.c +0 -0
  393. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-poll-multiple-handles.c +0 -0
  394. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-poll-oob.c +0 -0
  395. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-poll.c +0 -0
  396. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-process-priority.c +0 -0
  397. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-process-title-threadsafe.c +0 -0
  398. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-process-title.c +0 -0
  399. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-queue-foreach-delete.c +0 -0
  400. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-random.c +0 -0
  401. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-readable-on-eof.c +0 -0
  402. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-ref.c +0 -0
  403. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-run-nowait.c +0 -0
  404. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-run-once.c +0 -0
  405. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-semaphore.c +0 -0
  406. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-shutdown-close.c +0 -0
  407. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-shutdown-eof.c +0 -0
  408. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-shutdown-simultaneous.c +0 -0
  409. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-shutdown-twice.c +0 -0
  410. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-signal-multiple-loops.c +0 -0
  411. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-signal-pending-on-close.c +0 -0
  412. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-signal.c +0 -0
  413. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-socket-buffer-size.c +0 -0
  414. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-spawn.c +0 -0
  415. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-stdio-over-pipes.c +0 -0
  416. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-strscpy.c +0 -0
  417. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-strtok.c +0 -0
  418. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-alloc-cb-fail.c +0 -0
  419. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-bind-error.c +0 -0
  420. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-bind6-error.c +0 -0
  421. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-close-accept.c +0 -0
  422. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-close-after-read-timeout.c +0 -0
  423. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-close-reset.c +0 -0
  424. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-close-while-connecting.c +0 -0
  425. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-close.c +0 -0
  426. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-connect-error-after-write.c +0 -0
  427. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-connect-error.c +0 -0
  428. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-connect-timeout.c +0 -0
  429. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-connect6-error.c +0 -0
  430. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-create-socket-early.c +0 -0
  431. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-flags.c +0 -0
  432. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-oob.c +0 -0
  433. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-open.c +0 -0
  434. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-read-stop-start.c +0 -0
  435. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-read-stop.c +0 -0
  436. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-reuseport.c +0 -0
  437. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-rst.c +0 -0
  438. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-shutdown-after-write.c +0 -0
  439. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-try-write-error.c +0 -0
  440. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-try-write.c +0 -0
  441. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-unexpected-read.c +0 -0
  442. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-write-after-connect.c +0 -0
  443. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-write-fail.c +0 -0
  444. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-write-in-a-row.c +0 -0
  445. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-write-queue-order.c +0 -0
  446. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-write-to-half-open-connection.c +0 -0
  447. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tcp-writealot.c +0 -0
  448. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-test-macros.c +0 -0
  449. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-thread-affinity.c +0 -0
  450. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-thread-equal.c +0 -0
  451. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-thread-name.c +0 -0
  452. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-thread-priority.c +0 -0
  453. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-thread.c +0 -0
  454. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-threadpool-cancel.c +0 -0
  455. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-threadpool.c +0 -0
  456. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-timer-again.c +0 -0
  457. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-timer-from-check.c +0 -0
  458. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-timer.c +0 -0
  459. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tmpdir.c +0 -0
  460. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tty-duplicate-key.c +0 -0
  461. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tty-escape-sequence-processing.c +0 -0
  462. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-tty.c +0 -0
  463. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-alloc-cb-fail.c +0 -0
  464. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-bind.c +0 -0
  465. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-connect.c +0 -0
  466. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-connect6.c +0 -0
  467. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-create-socket-early.c +0 -0
  468. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-dgram-too-big.c +0 -0
  469. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-ipv6.c +0 -0
  470. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-mmsg.c +0 -0
  471. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-multicast-interface.c +0 -0
  472. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-multicast-interface6.c +0 -0
  473. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-multicast-join.c +0 -0
  474. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-multicast-join6.c +0 -0
  475. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-multicast-ttl.c +0 -0
  476. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-open.c +0 -0
  477. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-options.c +0 -0
  478. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-recv-in-a-row.c +0 -0
  479. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-reuseport.c +0 -0
  480. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-send-and-recv.c +0 -0
  481. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-send-hang-loop.c +0 -0
  482. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-send-immediate.c +0 -0
  483. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-send-unreachable.c +0 -0
  484. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-sendmmsg-error.c +0 -0
  485. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-udp-try-send.c +0 -0
  486. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-uname.c +0 -0
  487. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-walk-handles.c +0 -0
  488. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/test/test-watcher-cross-stop.c +0 -0
  489. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/tools/make_dist_html.py +0 -0
  490. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/tools/vswhere_usability_wrapper.cmd +0 -0
  491. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/tsansupp.txt +0 -0
  492. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/libuv/uv_win_longpath.manifest +0 -0
  493. {zuvloop-0.0.1 → zuvloop-0.0.2}/vendor/update-libuv.sh +0 -0
  494. {zuvloop-0.0.1 → zuvloop-0.0.2}/zig/c.zig +0 -0
  495. {zuvloop-0.0.1 → zuvloop-0.0.2}/zuvloop/__init__.py +0 -0
  496. {zuvloop-0.0.1 → zuvloop-0.0.2}/zuvloop/_loop.py +0 -0
  497. {zuvloop-0.0.1 → zuvloop-0.0.2}/zuvloop/_runner.py +0 -0
  498. {zuvloop-0.0.1 → zuvloop-0.0.2}/zuvloop/_sockets.py +0 -0
  499. {zuvloop-0.0.1 → zuvloop-0.0.2}/zuvloop/py.typed +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: zuvloop
3
- Version: 0.0.1
3
+ Version: 0.0.2
4
4
  Summary: A libuv event loop for asyncio, written in Zig.
5
5
  Project-URL: Source, https://github.com/Kludex/zuvloop
6
6
  Author-email: Marcelo Trylesinski <marcelotryle@gmail.com>
@@ -59,16 +59,17 @@ Throughput relative to stock asyncio (higher is better), measured with the suite
59
59
 
60
60
  | Benchmark | asyncio | uvloop | zuvloop |
61
61
  | --- | ---: | ---: | ---: |
62
- | `call_soon` | 2.69M/s | 4.69M/s | **5.91M/s** |
63
- | `call_soon` with arguments | 2.43M/s | 3.87M/s | **6.47M/s** |
64
- | timer schedule + cancel | 1.58M/s | 2.62M/s | **9.55M/s** |
65
- | bulk stream | 8.4 GiB/s | 8.5 GiB/s | **10.2 GiB/s** |
66
- | echo round trips, 1 KiB | 39.0k/s | 56.8k/s | **58.5k/s** |
67
- | uvicorn, plaintext | 55.3k req/s | 71.9k req/s | **75.9k req/s** |
68
- | uvicorn, 10 KiB body | 52.6k req/s | 68.7k req/s | **73.6k req/s** |
69
- | aiohttp server | 49.0k req/s | 59.8k req/s | **60.6k req/s** |
70
- | aiohttp client | 13.2k req/s | 16.2k req/s | **16.9k req/s** |
71
- | `getaddrinfo`, numeric host | 28.5k/s | 1.57M/s | **1.90M/s** |
62
+ | `call_soon` | 2.59M/s | 5.66M/s | **5.90M/s** |
63
+ | `call_soon` with arguments | 2.45M/s | 3.55M/s | **6.36M/s** |
64
+ | `call_soon_threadsafe` | 0.44M/s | 5.06M/s | **6.51M/s** |
65
+ | timer schedule + cancel | 1.55M/s | 2.57M/s | **9.58M/s** |
66
+ | bulk stream | 8.6 GiB/s | 9.0 GiB/s | **10.7 GiB/s** |
67
+ | echo round trips, 1 KiB | 38.4k/s | 53.0k/s | **58.4k/s** |
68
+ | uvicorn, plaintext | 54.0k req/s | 70.5k req/s | **76.7k req/s** |
69
+ | uvicorn, 10 KiB body | 51.6k req/s | 69.5k req/s | **74.2k req/s** |
70
+ | aiohttp server | 48.8k req/s | 61.0k req/s | **62.6k req/s** |
71
+ | aiohttp client | 13.4k req/s | 16.6k req/s | **16.9k req/s** |
72
+ | `getaddrinfo`, numeric host | 28.3k/s | 1.58M/s | **1.91M/s** |
72
73
 
73
74
  Curious how? The [architecture docs](https://zuvloop.marcelotryle.com) explain the design:
74
75
  argument storage inside handles (no tuple per callback), a native timer heap behind a single
@@ -121,8 +122,9 @@ That's it. That's the migration. 🎉
121
122
  ## Observability
122
123
 
123
124
  zuvloop emits plain OpenTelemetry. The only runtime dependency is `opentelemetry-api` — not the
124
- SDK, nothing vendor-specific. Until your application installs a provider, the instruments are
125
- no-ops and cost nothing.
125
+ SDK, nothing vendor-specific. Configure providers before starting the loop; zuvloop checks for them
126
+ at each `run_forever()` entry. Until then the instruments are no-ops and slow-callback timing stays
127
+ off.
126
128
 
127
129
  Anything that speaks OpenTelemetry can collect it. For example, with
128
130
  <a href="https://logfire.pydantic.dev" target="_blank">Logfire</a>:
@@ -192,10 +194,12 @@ returns and nothing else. A loop that needs a controllable clock should schedule
192
194
  explicitly.
193
195
 
194
196
  Also not implemented: `sendfile()` and `sock_sendfile()` raise `NotImplementedError`. Handles
195
- returned by `call_soon` and `call_later` implement the `asyncio.Handle` and
196
- `asyncio.TimerHandle` interfaces but are not instances of those classes; `call_soon_threadsafe`
197
- does return a real `asyncio.Handle`, because 3.14 requires cancelling one from another thread to
198
- block until a callback that has already started finishes.
197
+ returned by `call_soon` implement the `asyncio.Handle` interface but are not instances of it:
198
+ the base class is 56 bytes of storage such a handle never writes, measured at 2% of `call_soon`,
199
+ which is the object the loop allocates more often than any other. `call_later` and `call_at`
200
+ do return real `asyncio.TimerHandle` instances, so they order and compare by deadline, and
201
+ `call_soon_threadsafe` returns a real `asyncio.Handle`, because 3.14 requires cancelling one
202
+ from another thread to block until a callback that has already started finishes.
199
203
 
200
204
  ## Development
201
205
 
@@ -35,16 +35,17 @@ Throughput relative to stock asyncio (higher is better), measured with the suite
35
35
 
36
36
  | Benchmark | asyncio | uvloop | zuvloop |
37
37
  | --- | ---: | ---: | ---: |
38
- | `call_soon` | 2.69M/s | 4.69M/s | **5.91M/s** |
39
- | `call_soon` with arguments | 2.43M/s | 3.87M/s | **6.47M/s** |
40
- | timer schedule + cancel | 1.58M/s | 2.62M/s | **9.55M/s** |
41
- | bulk stream | 8.4 GiB/s | 8.5 GiB/s | **10.2 GiB/s** |
42
- | echo round trips, 1 KiB | 39.0k/s | 56.8k/s | **58.5k/s** |
43
- | uvicorn, plaintext | 55.3k req/s | 71.9k req/s | **75.9k req/s** |
44
- | uvicorn, 10 KiB body | 52.6k req/s | 68.7k req/s | **73.6k req/s** |
45
- | aiohttp server | 49.0k req/s | 59.8k req/s | **60.6k req/s** |
46
- | aiohttp client | 13.2k req/s | 16.2k req/s | **16.9k req/s** |
47
- | `getaddrinfo`, numeric host | 28.5k/s | 1.57M/s | **1.90M/s** |
38
+ | `call_soon` | 2.59M/s | 5.66M/s | **5.90M/s** |
39
+ | `call_soon` with arguments | 2.45M/s | 3.55M/s | **6.36M/s** |
40
+ | `call_soon_threadsafe` | 0.44M/s | 5.06M/s | **6.51M/s** |
41
+ | timer schedule + cancel | 1.55M/s | 2.57M/s | **9.58M/s** |
42
+ | bulk stream | 8.6 GiB/s | 9.0 GiB/s | **10.7 GiB/s** |
43
+ | echo round trips, 1 KiB | 38.4k/s | 53.0k/s | **58.4k/s** |
44
+ | uvicorn, plaintext | 54.0k req/s | 70.5k req/s | **76.7k req/s** |
45
+ | uvicorn, 10 KiB body | 51.6k req/s | 69.5k req/s | **74.2k req/s** |
46
+ | aiohttp server | 48.8k req/s | 61.0k req/s | **62.6k req/s** |
47
+ | aiohttp client | 13.4k req/s | 16.6k req/s | **16.9k req/s** |
48
+ | `getaddrinfo`, numeric host | 28.3k/s | 1.58M/s | **1.91M/s** |
48
49
 
49
50
  Curious how? The [architecture docs](https://zuvloop.marcelotryle.com) explain the design:
50
51
  argument storage inside handles (no tuple per callback), a native timer heap behind a single
@@ -97,8 +98,9 @@ That's it. That's the migration. 🎉
97
98
  ## Observability
98
99
 
99
100
  zuvloop emits plain OpenTelemetry. The only runtime dependency is `opentelemetry-api` — not the
100
- SDK, nothing vendor-specific. Until your application installs a provider, the instruments are
101
- no-ops and cost nothing.
101
+ SDK, nothing vendor-specific. Configure providers before starting the loop; zuvloop checks for them
102
+ at each `run_forever()` entry. Until then the instruments are no-ops and slow-callback timing stays
103
+ off.
102
104
 
103
105
  Anything that speaks OpenTelemetry can collect it. For example, with
104
106
  <a href="https://logfire.pydantic.dev" target="_blank">Logfire</a>:
@@ -168,10 +170,12 @@ returns and nothing else. A loop that needs a controllable clock should schedule
168
170
  explicitly.
169
171
 
170
172
  Also not implemented: `sendfile()` and `sock_sendfile()` raise `NotImplementedError`. Handles
171
- returned by `call_soon` and `call_later` implement the `asyncio.Handle` and
172
- `asyncio.TimerHandle` interfaces but are not instances of those classes; `call_soon_threadsafe`
173
- does return a real `asyncio.Handle`, because 3.14 requires cancelling one from another thread to
174
- block until a callback that has already started finishes.
173
+ returned by `call_soon` implement the `asyncio.Handle` interface but are not instances of it:
174
+ the base class is 56 bytes of storage such a handle never writes, measured at 2% of `call_soon`,
175
+ which is the object the loop allocates more often than any other. `call_later` and `call_at`
176
+ do return real `asyncio.TimerHandle` instances, so they order and compare by deadline, and
177
+ `call_soon_threadsafe` returns a real `asyncio.Handle`, because 3.14 requires cancelling one
178
+ from another thread to block until a callback that has already started finishes.
175
179
 
176
180
  ## Development
177
181
 
@@ -55,7 +55,12 @@ const uv_linux = [_][]const u8{
55
55
  };
56
56
 
57
57
  pub fn build(b: *std.Build) void {
58
- const target = b.standardTargetOptions(.{});
58
+ // A wheel is built on whatever machine the job landed on, and without a
59
+ // baseline default Zig compiles for that machine's CPU: the published
60
+ // manylinux wheel carried AVX2, BMI and MOVBE, so it would raise SIGILL on
61
+ // anything older than Haswell. Which instructions it needed depended on the
62
+ // runner. `-Dcpu=native` is still there for a build meant for one machine.
63
+ const target = b.standardTargetOptions(.{ .default_target = .{ .cpu_model = .baseline } });
59
64
  const optimize = b.standardOptimizeOption(.{});
60
65
 
61
66
  // hatch-ziglang passes the building interpreter through the environment, so a
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "zuvloop"
7
- version = "0.0.1"
7
+ version = "0.0.2"
8
8
  description = "A libuv event loop for asyncio, written in Zig."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.14"
@@ -23,12 +23,16 @@ pub const AF_INET: c_int = posix.AF.INET;
23
23
  pub const AF_INET6: c_int = posix.AF.INET6;
24
24
  pub const AF_UNIX: c_int = posix.AF.UNIX;
25
25
 
26
+ const UN_BASE = @offsetOf(posix.sockaddr.un, "path");
27
+
26
28
  fn tupleItem(t: *py.Object, i: c.Py_ssize_t) py.Error!*py.Object {
27
29
  return c.PyTuple_GetItem(t, i) orelse py.Error.Python;
28
30
  }
29
31
 
30
- /// Fills `out` from `(host, port[, flowinfo, scopeid])` or a filesystem path.
31
- pub fn fromPython(family: c_int, address: *py.Object, out: *Storage) py.Error!void {
32
+ /// Fills `out` from `(host, port[, flowinfo, scopeid])` or a filesystem path,
33
+ /// returning its length - the only thing that tells an abstract `AF_UNIX` name
34
+ /// from a shorter one padded with zeros.
35
+ pub fn fromPython(family: c_int, address: *py.Object, out: *Storage) py.Error!c_int {
32
36
  out.* = .{};
33
37
  if (family == AF_UNIX) {
34
38
  var path: [*c]const u8 = undefined;
@@ -45,7 +49,7 @@ pub fn fromPython(family: c_int, address: *py.Object, out: *Storage) py.Error!vo
45
49
  if (len >= un.path.len) return py.errValue("AF_UNIX path too long");
46
50
  un.family = @intCast(AF_UNIX);
47
51
  @memcpy(un.path[0..@intCast(len)], path[0..@intCast(len)]);
48
- return;
52
+ return @intCast(UN_BASE + @as(usize, @intCast(len)));
49
53
  }
50
54
 
51
55
  if (c.PyTuple_Check(address) == 0) return py.errType("address must be a tuple");
@@ -53,7 +57,14 @@ pub fn fromPython(family: c_int, address: *py.Object, out: *Storage) py.Error!vo
53
57
  if (size < 2) return py.errType("address tuple must be (host, port)");
54
58
 
55
59
  const host_obj = try tupleItem(address, 0);
56
- const port = try py.asCInt(try tupleItem(address, 1));
60
+ // Read wide and saturating, then narrow: converting to `c_int` first would
61
+ // refuse a port above `INT_MAX` with an error about the width of the type,
62
+ // before the range check below ever saw it.
63
+ const port_value = try py.asIsizeClamped(try tupleItem(address, 1));
64
+ // `uv_ip4_addr` stores `htons(port)`, which truncates rather than complains:
65
+ // a port of 70000 would quietly address 4464. The standard library rejects it.
66
+ if (port_value < 0 or port_value > 65535) return py.errOverflow("port must be 0-65535");
67
+ const port: c_int = @intCast(port_value);
57
68
 
58
69
  var host_buf: [256]u8 = undefined;
59
70
  const host: [*:0]const u8 = blk: {
@@ -71,10 +82,11 @@ pub fn fromPython(family: c_int, address: *py.Object, out: *Storage) py.Error!vo
71
82
  try py.errUvIfNeg(uv.uv_ip6_addr(host, port, sin6));
72
83
  if (size >= 3) sin6.flowinfo = @intCast(try py.asCInt(try tupleItem(address, 2)));
73
84
  if (size >= 4) sin6.scope_id = @intCast(try py.asCInt(try tupleItem(address, 3)));
74
- return;
85
+ return @sizeOf(posix.sockaddr.in6);
75
86
  }
76
87
  const sin: *posix.sockaddr.in = @ptrCast(out);
77
88
  try py.errUvIfNeg(uv.uv_ip4_addr(host, port, sin));
89
+ return @sizeOf(posix.sockaddr.in);
78
90
  }
79
91
 
80
92
  /// Builds the tuple `socket.getsockname()` would return for `sa`.
@@ -105,3 +117,38 @@ pub fn toPython(sa: *const posix.sockaddr) py.Error!*py.Object {
105
117
  @as(c_uint, sin6.scope_id),
106
118
  ) orelse py.Error.Python;
107
119
  }
120
+
121
+ /// Whether two addresses name the same endpoint.
122
+ ///
123
+ /// Only the fields that identify the peer are read: a byte comparison would trip
124
+ /// over padding, and over the `sin_len` the BSDs carry.
125
+ /// The bytes that name an `AF_UNIX` socket, as the kernel distinguishes them: an
126
+ /// abstract name is as long as the reported length says, so `\0foo` and `\0foo\0`
127
+ /// differ, while a pathname ends at its terminator - which the two sides need not
128
+ /// agree on counting.
129
+ fn unixName(sa: *const posix.sockaddr, len: c_int) []const u8 {
130
+ const un: *const posix.sockaddr.un = @ptrCast(@alignCast(sa));
131
+ if (len <= UN_BASE) return un.path[0..0];
132
+ const n = @min(@as(usize, @intCast(len)) - UN_BASE, un.path.len);
133
+ if (un.path[0] == 0) return un.path[0..n];
134
+ return un.path[0 .. std.mem.indexOfScalar(u8, un.path[0..n], 0) orelse n];
135
+ }
136
+
137
+ pub fn same(a: *const posix.sockaddr, a_len: c_int, b: *const posix.sockaddr, b_len: c_int) bool {
138
+ if (a.family != b.family) return false;
139
+ if (a.family == AF_UNIX) return std.mem.eql(u8, unixName(a, a_len), unixName(b, b_len));
140
+ if (a.family == AF_INET) {
141
+ const x: *const posix.sockaddr.in = @ptrCast(@alignCast(a));
142
+ const y: *const posix.sockaddr.in = @ptrCast(@alignCast(b));
143
+ return x.port == y.port and x.addr == y.addr;
144
+ }
145
+ if (a.family == AF_INET6) {
146
+ const x: *const posix.sockaddr.in6 = @ptrCast(@alignCast(a));
147
+ const y: *const posix.sockaddr.in6 = @ptrCast(@alignCast(b));
148
+ if (x.port != y.port or !std.mem.eql(u8, &x.addr, &y.addr)) return false;
149
+ // asyncio compares tuples, so it wants the scope stated rather than
150
+ // treating a zero as a wildcard.
151
+ return x.scope_id == y.scope_id;
152
+ }
153
+ return false;
154
+ }
@@ -119,13 +119,30 @@ pub const Timers = struct {
119
119
  }
120
120
 
121
121
  /// Drops cancelled entries once they dominate the heap.
122
- pub fn compact(self: *Timers, isCancelled: *const fn (*py.Object) bool) void {
122
+ /// Drops cancelled entries and restores the heap.
123
+ ///
124
+ /// The handles are released only once the heap is whole again. Releasing one
125
+ /// runs its arguments' finalizers, and a finalizer calling `call_later`
126
+ /// reaches `push`, which writes at `items[len]` and sifts - so a release from
127
+ /// inside the pass would shuffle slots the pass has already moved, and one
128
+ /// from inside the array would land on an entry not yet released. Which is
129
+ /// also why the doomed handles are copied out rather than parked in the tail.
130
+ pub fn compact(self: *Timers, shouldDrop: *const fn (*py.Object) bool) void {
131
+ // Sized by the heap rather than by `cancelled`, which is a hint and not a
132
+ // guarantee: `Handle.cancel` only reports to the loop while it still has
133
+ // one, so an entry can be cancelled without ever being counted. Nowhere
134
+ // to set them aside means nothing can be released, so the heap is left
135
+ // exactly as it was - count included - for the next cancellation to retry.
136
+ const doomed = alloc.alloc(*py.Object, self.len) catch return;
137
+ defer alloc.free(doomed);
138
+ var dropped: usize = 0;
123
139
  var write: usize = 0;
124
140
  var read: usize = 0;
125
141
  while (read < self.len) : (read += 1) {
126
142
  const entry = self.items[read];
127
- if (isCancelled(entry.handle)) {
128
- py.decref(entry.handle);
143
+ if (shouldDrop(entry.handle)) {
144
+ doomed[dropped] = entry.handle;
145
+ dropped += 1;
129
146
  } else {
130
147
  self.items[write] = entry;
131
148
  write += 1;
@@ -133,12 +150,14 @@ pub const Timers = struct {
133
150
  }
134
151
  self.len = write;
135
152
  self.cancelled = 0;
136
- if (write < 2) return;
137
- var i = write / 2;
138
- while (i > 0) {
139
- i -= 1;
140
- self.siftDown(i);
153
+ if (write >= 2) {
154
+ var i = write / 2;
155
+ while (i > 0) {
156
+ i -= 1;
157
+ self.siftDown(i);
158
+ }
141
159
  }
160
+ for (doomed[0..dropped]) |handle| py.decref(handle);
142
161
  }
143
162
 
144
163
  fn grow(self: *Timers) error{OutOfMemory}!void {
@@ -215,7 +215,11 @@ fn onRecv(
215
215
  };
216
216
  defer py.decref(data);
217
217
  const sender = addr.toPython(from.?) catch {
218
- c.PyErr_Clear();
218
+ // The datagram cannot be delivered without naming its sender, and a
219
+ // receive failure is what `error_received` exists to report.
220
+ const exc = c.PyErr_GetRaisedException() orelse return;
221
+ defer py.decref(exc);
222
+ callInContext(self, self.cb_error_received, &.{exc});
219
223
  return;
220
224
  };
221
225
  defer py.decref(sender);
@@ -365,16 +369,25 @@ fn sendto(self_obj: *py.Object, args: []const ?*py.Object, nargs: usize, kwnames
365
369
  }
366
370
  }
367
371
  const self = asDatagram(self_obj);
368
- if (self.flags & CONN_LOST != 0) return py.noneRef();
369
- if (self.flags & CLOSING != 0) return py.errRuntime("Cannot call sendto() after close()");
370
372
 
371
373
  const target = if (address) |a| (if (py.isNone(a)) null else address) else null;
372
374
  var dest: addr.Storage = .{};
373
375
  var dest_ptr: ?*const std.posix.sockaddr = null;
374
376
  if (target) |t| {
375
- if (self.flags & CONNECTED != 0) return py.errValue("Transport is connected; sendto() takes no address");
376
- try addr.fromPython(self.family, t, &dest);
377
- dest_ptr = dest.ptr();
377
+ const dest_len = try addr.fromPython(self.family, t, &dest);
378
+ if (self.flags & CONNECTED != 0) {
379
+ // Naming the peer is allowed, as it is for asyncio; naming anything
380
+ // else is not.
381
+ var peer: addr.Storage = .{};
382
+ var len: c_int = @sizeOf(addr.Storage);
383
+ if (uv.uv_udp_getpeername(self.udp(), peer.ptr(), &len) < 0 or
384
+ !addr.same(dest.constPtr(), dest_len, peer.constPtr(), len))
385
+ {
386
+ return py.errValue("Transport is connected; sendto() takes no address but the peer's");
387
+ }
388
+ } else {
389
+ dest_ptr = dest.ptr();
390
+ }
378
391
  } else if (self.flags & CONNECTED == 0) {
379
392
  return py.errValue("sendto() requires an address on an unconnected transport");
380
393
  }
@@ -382,6 +395,11 @@ fn sendto(self_obj: *py.Object, args: []const ?*py.Object, nargs: usize, kwnames
382
395
  var view: c.Py_buffer = undefined;
383
396
  if (c.PyObject_GetBuffer(args[0].?, &view, c.PyBUF_SIMPLE) < 0) return py.Error.Python;
384
397
  defer c.PyBuffer_Release(&view);
398
+
399
+ // A closing endpoint drops the datagram, as asyncio does - but the argument
400
+ // errors above still raise there, which is why they all come first.
401
+ if (self.flags & (CONN_LOST | CLOSING) != 0) return py.noneRef();
402
+
385
403
  const buf = uv.Buf{ .base = @ptrCast(view.buf), .len = @intCast(view.len) };
386
404
 
387
405
  if (self.write_buffer_size == 0) {
@@ -509,6 +527,29 @@ fn adoptSocketView(self_obj: *py.Object, view: *py.Object) py.Error!*py.Object {
509
527
  return py.noneRef();
510
528
  }
511
529
 
530
+ /// `pause_reading()`: stop delivering datagrams until reading resumes.
531
+ ///
532
+ /// A datagram endpoint that is not reading leaves what arrives in the socket's
533
+ /// receive buffer, and the kernel drops from there once it fills. That is what
534
+ /// asyncio's does too; uvloop's has no such method at all.
535
+ fn pauseReading(self_obj: *py.Object) py.Error!*py.Object {
536
+ const self = asDatagram(self_obj);
537
+ if (self.flags & CLOSING != 0) return py.errRuntime("Cannot pause_reading() after close()");
538
+ if (self.flags & READING != 0) {
539
+ _ = uv.uv_udp_recv_stop(self.udp());
540
+ self.flags &= ~READING;
541
+ }
542
+ return py.noneRef();
543
+ }
544
+
545
+ /// `resume_reading()`: deliver datagrams again.
546
+ fn resumeReading(self_obj: *py.Object) py.Error!*py.Object {
547
+ const self = asDatagram(self_obj);
548
+ if (self.flags & CLOSING != 0) return py.errRuntime("Cannot resume_reading() after close()");
549
+ try startReceiving(self);
550
+ return py.noneRef();
551
+ }
552
+
512
553
  fn startReceivingMethod(self_obj: *py.Object) py.Error!*py.Object {
513
554
  const self = asDatagram(self_obj);
514
555
  startReceiving(self) catch {
@@ -652,6 +693,8 @@ var methods = [_]c.PyMethodDef{
652
693
  py.methodNoArgs("get_protocol", getProtocol, "Return the current protocol."),
653
694
  py.methodO("set_protocol", setProtocol, "Replace the current protocol."),
654
695
  py.methodO("_adopt_socket_view", adoptSocketView, "Track the socket object mirroring libuv's descriptor."),
696
+ py.methodNoArgs("pause_reading", pauseReading, "Stop delivering datagrams."),
697
+ py.methodNoArgs("resume_reading", resumeReading, "Deliver datagrams again."),
655
698
  py.methodNoArgs("_start_receiving", startReceivingMethod, "Begin delivering datagrams."),
656
699
  py.methodKw("sendto", sendto, "Send a datagram to an address."),
657
700
  py.methodNoArgs("get_write_buffer_size", getWriteBufferSize, "Return the number of bytes queued."),
@@ -152,10 +152,72 @@ fn settle(future: *py.Object, method: ?*py.Object, value: *py.Object) void {
152
152
  py.decref(res);
153
153
  }
154
154
 
155
- fn failFuture(future: *py.Object, status: c_int) void {
155
+ /// The member if this platform has it, and a stand-in if it does not: glibc
156
+ /// carries no `EAI_BADHINTS` or `EAI_PROTOCOL`, and the codes are not the same
157
+ /// numbers across platforms either.
158
+ inline fn eai(comptime name: [:0]const u8, comptime fallback: std.c.EAI) std.c.EAI {
159
+ return if (@hasField(std.c.EAI, name)) @field(std.c.EAI, name) else fallback;
160
+ }
161
+
162
+ /// libuv reports resolver failures with codes of its own; `socket.gaierror`
163
+ /// carries the platform's `EAI_*`, which is what callers written against the
164
+ /// standard library compare against. Anything that is not a resolver failure -
165
+ /// a cancellation, an out-of-memory - is left to `OSError`.
166
+ fn resolverError(status: c_int) ?std.c.EAI {
167
+ return switch (status) {
168
+ uv.EAI_ADDRFAMILY => eai("ADDRFAMILY", .FAIL),
169
+ uv.EAI_AGAIN => .AGAIN,
170
+ uv.EAI_BADFLAGS => .BADFLAGS,
171
+ uv.EAI_BADHINTS => eai("BADHINTS", .FAIL),
172
+ uv.EAI_FAIL => .FAIL,
173
+ uv.EAI_FAMILY => .FAMILY,
174
+ uv.EAI_MEMORY => .MEMORY,
175
+ uv.EAI_NODATA => eai("NODATA", .NONAME),
176
+ uv.EAI_NONAME => .NONAME,
177
+ uv.EAI_OVERFLOW => eai("OVERFLOW", .FAIL),
178
+ uv.EAI_PROTOCOL => eai("PROTOCOL", .FAIL),
179
+ uv.EAI_SERVICE => .SERVICE,
180
+ uv.EAI_SOCKTYPE => .SOCKTYPE,
181
+ else => null,
182
+ };
183
+ }
184
+
185
+ /// Builds the exception the standard library would have raised for `status`.
186
+ fn resolverException(status: c_int) ?*py.Object {
187
+ if (resolverError(status)) |code| {
188
+ return c.PyObject_CallFunction(gaierror, "is", @intFromEnum(code), std.c.gai_strerror(code));
189
+ }
156
190
  var buf: [128]u8 = undefined;
157
191
  const msg = uv.strerror(status, &buf);
158
- const exc = c.PyObject_CallFunction(gaierror, "is", @as(c_int, status), msg.ptr) orelse {
192
+ return c.PyObject_CallFunction(@ptrCast(c.PyExc_OSError), "is", uv.toErrno(status), msg.ptr);
193
+ }
194
+
195
+ /// Raises `socket.gaierror` for a code the platform's resolver produced itself.
196
+ fn raisePlatformError(code: std.c.EAI) py.Error {
197
+ // `EAI_SYSTEM` says only that the real error is in `errno`, so the standard
198
+ // library reports that instead - `set_gaierror` in CPython's socketmodule
199
+ // hands it straight to `PyErr_SetFromErrno`. Windows has no such code.
200
+ if (@hasField(std.c.EAI, "SYSTEM") and code == eai("SYSTEM", .FAIL)) {
201
+ _ = c.PyErr_SetFromErrno(@ptrCast(c.PyExc_OSError));
202
+ return py.Error.Python;
203
+ }
204
+ const exc = c.PyObject_CallFunction(gaierror, "is", @intFromEnum(code), std.c.gai_strerror(code)) orelse
205
+ return py.Error.Python;
206
+ c.PyErr_SetRaisedException(exc);
207
+ return py.Error.Python;
208
+ }
209
+
210
+ /// Raises it, for the paths that report synchronously rather than through a future.
211
+ /// `PyErr_SetRaisedException` takes the reference, and needs no separate type -
212
+ /// `PyObject_Type` would hand back one more to own.
213
+ fn raiseResolverError(status: c_int) py.Error {
214
+ const exc = resolverException(status) orelse return py.Error.Python;
215
+ c.PyErr_SetRaisedException(exc);
216
+ return py.Error.Python;
217
+ }
218
+
219
+ fn failFuture(future: *py.Object, status: c_int) void {
220
+ const exc = resolverException(status) orelse {
159
221
  py.writeUnraisable(future);
160
222
  return;
161
223
  };
@@ -370,6 +432,35 @@ pub fn getaddrinfo(self_obj: *py.Object, args: []const ?*py.Object) py.Error!*py
370
432
  hints.protocol = try py.asCInt(args[4].?);
371
433
  hints.flags = @bitCast(@as(u32, @bitCast(try py.asCInt(args[5].?))));
372
434
 
435
+ // libuv refuses this pair outright, before any resolver sees it, and reports
436
+ // it as EINVAL. The resolver the standard library reaches would have answered
437
+ // "neither node nor service", which is what callers are written to expect.
438
+ if (host == null and service == null) return raiseResolverError(uv.EAI_NONAME);
439
+
440
+ // libuv runs every hostname through IDNA, which rejects an empty one, so `""`
441
+ // can never reach a resolver that way. The platforms disagree about what it
442
+ // means - BSD reads it as the null host, glibc as a name it cannot find - and
443
+ // matching `socket.getaddrinfo` means letting the platform answer rather than
444
+ // picking one.
445
+ //
446
+ // Nothing is resolved here, but this does enter libc on the loop thread, and
447
+ // the first call in a process pays for the resolver's own initialization:
448
+ // measured on macOS at 1.5ms for a numeric service and 2.3ms for a name,
449
+ // then under a microsecond for every call after it. `resolveNumeric` pays the
450
+ // same initialization on the main path, so moving this one to a threadpool
451
+ // would not buy a loop that never waits for the resolver to wake up.
452
+ if (host) |name| if (name[0] == 0) {
453
+ var res: ?*std.c.addrinfo = null;
454
+ const rc = std.c.getaddrinfo(name, service, &hints, &res);
455
+ if (rc != @as(std.c.EAI, @enumFromInt(0))) return raisePlatformError(rc);
456
+ defer if (res) |first| std.c.freeaddrinfo(first);
457
+ const list = try buildResults(res);
458
+ defer py.decref(list);
459
+ const future = c.PyObject_CallMethodNoArgs(@ptrCast(loop), str_create_future) orelse return py.Error.Python;
460
+ settle(future, str_set_result, list);
461
+ return future;
462
+ };
463
+
373
464
  if (resolveLiteral(&hints, host, service) orelse resolveNumeric(&hints, host, service)) |list| {
374
465
  defer py.decref(list);
375
466
  const future = c.PyObject_CallMethodNoArgs(@ptrCast(loop), str_create_future) orelse return py.Error.Python;
@@ -385,7 +476,8 @@ pub fn getaddrinfo(self_obj: *py.Object, args: []const ?*py.Object) py.Error!*py
385
476
  const req_host: ?[*:0]const u8 = if (host == null) null else @ptrCast(&req.host);
386
477
  const req_service: ?[*:0]const u8 = if (service == null) null else @ptrCast(&req.service);
387
478
 
388
- try py.errUvIfNeg(uv.uv_getaddrinfo(loop.state().uvloop, req.addrReq(), onAddrInfo, req_host, req_service, &req.hints));
479
+ const status = uv.uv_getaddrinfo(loop.state().uvloop, req.addrReq(), onAddrInfo, req_host, req_service, &req.hints);
480
+ if (status < 0) return raiseResolverError(status);
389
481
  return py.newref(req.future.?).?;
390
482
  }
391
483
 
@@ -396,12 +488,19 @@ pub fn getnameinfo(self_obj: *py.Object, args: []const ?*py.Object) py.Error!*py
396
488
  try loopmod.checkClosed(loop.state());
397
489
 
398
490
  var storage: addr.Storage = .{};
399
- try addr.fromPython(0, args[0].?, &storage);
491
+ _ = addr.fromPython(0, args[0].?, &storage) catch |e| {
492
+ // Only the host is the resolver's to report; a bad tuple or port keeps
493
+ // its own exception, and those are not `OSError`.
494
+ if (c.PyErr_ExceptionMatches(@ptrCast(c.PyExc_OSError)) == 0) return e;
495
+ c.PyErr_Clear();
496
+ return raisePlatformError(eai("NONAME", .FAIL));
497
+ };
400
498
  const flags = try py.asCInt(args[1].?);
401
499
 
402
500
  const req = try allocRequest(loop, .getnameinfo);
403
501
  errdefer freeRequest(req, .getnameinfo);
404
- try py.errUvIfNeg(uv.uv_getnameinfo(loop.state().uvloop, req.nameReq(), onNameInfo, storage.constPtr(), flags));
502
+ const status = uv.uv_getnameinfo(loop.state().uvloop, req.nameReq(), onNameInfo, storage.constPtr(), flags);
503
+ if (status < 0) return raiseResolverError(status);
405
504
  return py.newref(req.future.?).?;
406
505
  }
407
506