@ajksunkang-aios/kgraph-linux-x64 0.1.2 → 0.1.3

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 (196) hide show
  1. package/bin/kgraph-launcher +15 -3
  2. package/lib/kgraph/scripts/build-bundle.sh +17 -4
  3. package/lib/site-packages/outcome/__init__.py +20 -0
  4. package/lib/site-packages/outcome/_impl.py +239 -0
  5. package/lib/site-packages/outcome/_util.py +33 -0
  6. package/lib/site-packages/outcome/_version.py +7 -0
  7. package/lib/site-packages/outcome/py.typed +0 -0
  8. package/lib/site-packages/outcome-1.3.0.post0.dist-info/INSTALLER +1 -0
  9. package/lib/site-packages/outcome-1.3.0.post0.dist-info/LICENSE +3 -0
  10. package/lib/site-packages/outcome-1.3.0.post0.dist-info/LICENSE.APACHE2 +202 -0
  11. package/lib/site-packages/outcome-1.3.0.post0.dist-info/LICENSE.MIT +20 -0
  12. package/lib/site-packages/outcome-1.3.0.post0.dist-info/METADATA +63 -0
  13. package/lib/site-packages/outcome-1.3.0.post0.dist-info/RECORD +13 -0
  14. package/lib/site-packages/outcome-1.3.0.post0.dist-info/WHEEL +6 -0
  15. package/lib/site-packages/outcome-1.3.0.post0.dist-info/top_level.txt +1 -0
  16. package/lib/site-packages/sniffio/__init__.py +17 -0
  17. package/lib/site-packages/sniffio/_impl.py +95 -0
  18. package/lib/site-packages/sniffio/_tests/__init__.py +0 -0
  19. package/lib/site-packages/sniffio/_tests/test_sniffio.py +84 -0
  20. package/lib/site-packages/sniffio/_version.py +3 -0
  21. package/lib/site-packages/sniffio/py.typed +0 -0
  22. package/lib/site-packages/sniffio-1.3.1.dist-info/INSTALLER +1 -0
  23. package/lib/site-packages/sniffio-1.3.1.dist-info/LICENSE +3 -0
  24. package/lib/site-packages/sniffio-1.3.1.dist-info/LICENSE.APACHE2 +202 -0
  25. package/lib/site-packages/sniffio-1.3.1.dist-info/LICENSE.MIT +20 -0
  26. package/lib/site-packages/sniffio-1.3.1.dist-info/METADATA +104 -0
  27. package/lib/site-packages/sniffio-1.3.1.dist-info/RECORD +14 -0
  28. package/lib/site-packages/sniffio-1.3.1.dist-info/WHEEL +5 -0
  29. package/lib/site-packages/sniffio-1.3.1.dist-info/top_level.txt +1 -0
  30. package/lib/site-packages/sortedcontainers/__init__.py +74 -0
  31. package/lib/site-packages/sortedcontainers/sorteddict.py +812 -0
  32. package/lib/site-packages/sortedcontainers/sortedlist.py +2646 -0
  33. package/lib/site-packages/sortedcontainers/sortedset.py +733 -0
  34. package/lib/site-packages/sortedcontainers-2.4.0.dist-info/INSTALLER +1 -0
  35. package/lib/site-packages/sortedcontainers-2.4.0.dist-info/LICENSE +13 -0
  36. package/lib/site-packages/sortedcontainers-2.4.0.dist-info/METADATA +264 -0
  37. package/lib/site-packages/sortedcontainers-2.4.0.dist-info/RECORD +10 -0
  38. package/lib/site-packages/sortedcontainers-2.4.0.dist-info/WHEEL +6 -0
  39. package/lib/site-packages/sortedcontainers-2.4.0.dist-info/top_level.txt +1 -0
  40. package/lib/site-packages/trio/__init__.py +133 -0
  41. package/lib/site-packages/trio/__main__.py +3 -0
  42. package/lib/site-packages/trio/_abc.py +714 -0
  43. package/lib/site-packages/trio/_channel.py +610 -0
  44. package/lib/site-packages/trio/_core/__init__.py +94 -0
  45. package/lib/site-packages/trio/_core/_asyncgens.py +243 -0
  46. package/lib/site-packages/trio/_core/_concat_tb.py +26 -0
  47. package/lib/site-packages/trio/_core/_entry_queue.py +223 -0
  48. package/lib/site-packages/trio/_core/_exceptions.py +169 -0
  49. package/lib/site-packages/trio/_core/_generated_instrumentation.py +50 -0
  50. package/lib/site-packages/trio/_core/_generated_io_epoll.py +98 -0
  51. package/lib/site-packages/trio/_core/_generated_io_kqueue.py +153 -0
  52. package/lib/site-packages/trio/_core/_generated_io_windows.py +204 -0
  53. package/lib/site-packages/trio/_core/_generated_run.py +269 -0
  54. package/lib/site-packages/trio/_core/_generated_windows_ffi.py +10 -0
  55. package/lib/site-packages/trio/_core/_instrumentation.py +117 -0
  56. package/lib/site-packages/trio/_core/_io_common.py +31 -0
  57. package/lib/site-packages/trio/_core/_io_epoll.py +385 -0
  58. package/lib/site-packages/trio/_core/_io_kqueue.py +292 -0
  59. package/lib/site-packages/trio/_core/_io_windows.py +1036 -0
  60. package/lib/site-packages/trio/_core/_ki.py +271 -0
  61. package/lib/site-packages/trio/_core/_local.py +104 -0
  62. package/lib/site-packages/trio/_core/_mock_clock.py +165 -0
  63. package/lib/site-packages/trio/_core/_parking_lot.py +317 -0
  64. package/lib/site-packages/trio/_core/_run.py +3148 -0
  65. package/lib/site-packages/trio/_core/_run_context.py +15 -0
  66. package/lib/site-packages/trio/_core/_tests/__init__.py +0 -0
  67. package/lib/site-packages/trio/_core/_tests/test_asyncgen.py +339 -0
  68. package/lib/site-packages/trio/_core/_tests/test_cancelled.py +222 -0
  69. package/lib/site-packages/trio/_core/_tests/test_exceptiongroup_gc.py +103 -0
  70. package/lib/site-packages/trio/_core/_tests/test_guest_mode.py +755 -0
  71. package/lib/site-packages/trio/_core/_tests/test_instrumentation.py +315 -0
  72. package/lib/site-packages/trio/_core/_tests/test_io.py +522 -0
  73. package/lib/site-packages/trio/_core/_tests/test_ki.py +703 -0
  74. package/lib/site-packages/trio/_core/_tests/test_local.py +118 -0
  75. package/lib/site-packages/trio/_core/_tests/test_mock_clock.py +193 -0
  76. package/lib/site-packages/trio/_core/_tests/test_parking_lot.py +389 -0
  77. package/lib/site-packages/trio/_core/_tests/test_run.py +3024 -0
  78. package/lib/site-packages/trio/_core/_tests/test_thread_cache.py +227 -0
  79. package/lib/site-packages/trio/_core/_tests/test_tutil.py +13 -0
  80. package/lib/site-packages/trio/_core/_tests/test_unbounded_queue.py +154 -0
  81. package/lib/site-packages/trio/_core/_tests/test_windows.py +305 -0
  82. package/lib/site-packages/trio/_core/_tests/tutil.py +117 -0
  83. package/lib/site-packages/trio/_core/_tests/type_tests/nursery_start.py +79 -0
  84. package/lib/site-packages/trio/_core/_tests/type_tests/run.py +51 -0
  85. package/lib/site-packages/trio/_core/_thread_cache.py +317 -0
  86. package/lib/site-packages/trio/_core/_traps.py +318 -0
  87. package/lib/site-packages/trio/_core/_unbounded_queue.py +163 -0
  88. package/lib/site-packages/trio/_core/_wakeup_socketpair.py +75 -0
  89. package/lib/site-packages/trio/_core/_windows_cffi.py +313 -0
  90. package/lib/site-packages/trio/_deprecate.py +171 -0
  91. package/lib/site-packages/trio/_dtls.py +1380 -0
  92. package/lib/site-packages/trio/_file_io.py +513 -0
  93. package/lib/site-packages/trio/_highlevel_generic.py +125 -0
  94. package/lib/site-packages/trio/_highlevel_open_tcp_listeners.py +251 -0
  95. package/lib/site-packages/trio/_highlevel_open_tcp_stream.py +397 -0
  96. package/lib/site-packages/trio/_highlevel_open_unix_stream.py +65 -0
  97. package/lib/site-packages/trio/_highlevel_serve_listeners.py +148 -0
  98. package/lib/site-packages/trio/_highlevel_socket.py +423 -0
  99. package/lib/site-packages/trio/_highlevel_ssl_helpers.py +180 -0
  100. package/lib/site-packages/trio/_path.py +289 -0
  101. package/lib/site-packages/trio/_repl.py +159 -0
  102. package/lib/site-packages/trio/_signals.py +185 -0
  103. package/lib/site-packages/trio/_socket.py +1326 -0
  104. package/lib/site-packages/trio/_ssl.py +964 -0
  105. package/lib/site-packages/trio/_subprocess.py +1178 -0
  106. package/lib/site-packages/trio/_subprocess_platform/__init__.py +123 -0
  107. package/lib/site-packages/trio/_subprocess_platform/kqueue.py +48 -0
  108. package/lib/site-packages/trio/_subprocess_platform/waitid.py +113 -0
  109. package/lib/site-packages/trio/_subprocess_platform/windows.py +11 -0
  110. package/lib/site-packages/trio/_sync.py +908 -0
  111. package/lib/site-packages/trio/_tests/__init__.py +0 -0
  112. package/lib/site-packages/trio/_tests/astrill-codesigning-cert.cer +0 -0
  113. package/lib/site-packages/trio/_tests/check_type_completeness.py +247 -0
  114. package/lib/site-packages/trio/_tests/module_with_deprecations.py +22 -0
  115. package/lib/site-packages/trio/_tests/pytest_plugin.py +54 -0
  116. package/lib/site-packages/trio/_tests/test_abc.py +72 -0
  117. package/lib/site-packages/trio/_tests/test_channel.py +750 -0
  118. package/lib/site-packages/trio/_tests/test_contextvars.py +56 -0
  119. package/lib/site-packages/trio/_tests/test_deprecate.py +277 -0
  120. package/lib/site-packages/trio/_tests/test_deprecate_strict_exception_groups_false.py +64 -0
  121. package/lib/site-packages/trio/_tests/test_dtls.py +950 -0
  122. package/lib/site-packages/trio/_tests/test_exports.py +626 -0
  123. package/lib/site-packages/trio/_tests/test_fakenet.py +317 -0
  124. package/lib/site-packages/trio/_tests/test_file_io.py +269 -0
  125. package/lib/site-packages/trio/_tests/test_highlevel_generic.py +98 -0
  126. package/lib/site-packages/trio/_tests/test_highlevel_open_tcp_listeners.py +419 -0
  127. package/lib/site-packages/trio/_tests/test_highlevel_open_tcp_stream.py +693 -0
  128. package/lib/site-packages/trio/_tests/test_highlevel_open_unix_stream.py +86 -0
  129. package/lib/site-packages/trio/_tests/test_highlevel_serve_listeners.py +186 -0
  130. package/lib/site-packages/trio/_tests/test_highlevel_socket.py +336 -0
  131. package/lib/site-packages/trio/_tests/test_highlevel_ssl_helpers.py +169 -0
  132. package/lib/site-packages/trio/_tests/test_path.py +279 -0
  133. package/lib/site-packages/trio/_tests/test_repl.py +428 -0
  134. package/lib/site-packages/trio/_tests/test_scheduler_determinism.py +47 -0
  135. package/lib/site-packages/trio/_tests/test_signals.py +186 -0
  136. package/lib/site-packages/trio/_tests/test_socket.py +1253 -0
  137. package/lib/site-packages/trio/_tests/test_ssl.py +1371 -0
  138. package/lib/site-packages/trio/_tests/test_subprocess.py +767 -0
  139. package/lib/site-packages/trio/_tests/test_sync.py +735 -0
  140. package/lib/site-packages/trio/_tests/test_testing.py +682 -0
  141. package/lib/site-packages/trio/_tests/test_testing_raisesgroup.py +1128 -0
  142. package/lib/site-packages/trio/_tests/test_threads.py +1173 -0
  143. package/lib/site-packages/trio/_tests/test_timeouts.py +281 -0
  144. package/lib/site-packages/trio/_tests/test_tracing.py +88 -0
  145. package/lib/site-packages/trio/_tests/test_trio.py +8 -0
  146. package/lib/site-packages/trio/_tests/test_unix_pipes.py +288 -0
  147. package/lib/site-packages/trio/_tests/test_util.py +349 -0
  148. package/lib/site-packages/trio/_tests/test_wait_for_object.py +225 -0
  149. package/lib/site-packages/trio/_tests/test_windows_pipes.py +112 -0
  150. package/lib/site-packages/trio/_tests/tools/__init__.py +0 -0
  151. package/lib/site-packages/trio/_tests/tools/test_gen_exports.py +179 -0
  152. package/lib/site-packages/trio/_tests/tools/test_mypy_annotate.py +140 -0
  153. package/lib/site-packages/trio/_tests/tools/test_sync_requirements.py +80 -0
  154. package/lib/site-packages/trio/_tests/type_tests/check_wraps.py +9 -0
  155. package/lib/site-packages/trio/_tests/type_tests/open_memory_channel.py +4 -0
  156. package/lib/site-packages/trio/_tests/type_tests/path.py +140 -0
  157. package/lib/site-packages/trio/_tests/type_tests/subprocesses.py +23 -0
  158. package/lib/site-packages/trio/_tests/type_tests/task_status.py +29 -0
  159. package/lib/site-packages/trio/_threads.py +610 -0
  160. package/lib/site-packages/trio/_timeouts.py +197 -0
  161. package/lib/site-packages/trio/_tools/__init__.py +0 -0
  162. package/lib/site-packages/trio/_tools/gen_exports.py +401 -0
  163. package/lib/site-packages/trio/_tools/mypy_annotate.py +126 -0
  164. package/lib/site-packages/trio/_tools/sync_requirements.py +98 -0
  165. package/lib/site-packages/trio/_tools/windows_ffi_build.py +220 -0
  166. package/lib/site-packages/trio/_unix_pipes.py +197 -0
  167. package/lib/site-packages/trio/_util.py +385 -0
  168. package/lib/site-packages/trio/_version.py +3 -0
  169. package/lib/site-packages/trio/_wait_for_object.py +67 -0
  170. package/lib/site-packages/trio/_windows_pipes.py +144 -0
  171. package/lib/site-packages/trio/abc.py +23 -0
  172. package/lib/site-packages/trio/from_thread.py +13 -0
  173. package/lib/site-packages/trio/lowlevel.py +95 -0
  174. package/lib/site-packages/trio/py.typed +0 -0
  175. package/lib/site-packages/trio/socket.py +602 -0
  176. package/lib/site-packages/trio/testing/__init__.py +58 -0
  177. package/lib/site-packages/trio/testing/_check_streams.py +570 -0
  178. package/lib/site-packages/trio/testing/_checkpoints.py +69 -0
  179. package/lib/site-packages/trio/testing/_fake_net.py +584 -0
  180. package/lib/site-packages/trio/testing/_memory_streams.py +633 -0
  181. package/lib/site-packages/trio/testing/_network.py +36 -0
  182. package/lib/site-packages/trio/testing/_raises_group.py +1015 -0
  183. package/lib/site-packages/trio/testing/_sequencer.py +87 -0
  184. package/lib/site-packages/trio/testing/_trio_test.py +50 -0
  185. package/lib/site-packages/trio/to_thread.py +4 -0
  186. package/lib/site-packages/trio-0.33.0.dist-info/INSTALLER +1 -0
  187. package/lib/site-packages/trio-0.33.0.dist-info/METADATA +186 -0
  188. package/lib/site-packages/trio-0.33.0.dist-info/RECORD +156 -0
  189. package/lib/site-packages/trio-0.33.0.dist-info/REQUESTED +0 -0
  190. package/lib/site-packages/trio-0.33.0.dist-info/WHEEL +5 -0
  191. package/lib/site-packages/trio-0.33.0.dist-info/entry_points.txt +2 -0
  192. package/lib/site-packages/trio-0.33.0.dist-info/licenses/LICENSE +3 -0
  193. package/lib/site-packages/trio-0.33.0.dist-info/licenses/LICENSE.APACHE2 +202 -0
  194. package/lib/site-packages/trio-0.33.0.dist-info/licenses/LICENSE.MIT +22 -0
  195. package/lib/site-packages/trio-0.33.0.dist-info/top_level.txt +1 -0
  196. package/package.json +1 -1
@@ -0,0 +1,682 @@
1
+ from __future__ import annotations
2
+
3
+ # XX this should get broken up, like testing.py did
4
+ import tempfile
5
+ from typing import TYPE_CHECKING
6
+
7
+ import pytest
8
+
9
+ from .. import _core, sleep, socket as tsocket
10
+ from .._core._tests.tutil import can_bind_ipv6
11
+ from .._highlevel_generic import StapledStream, aclose_forcefully
12
+ from .._highlevel_socket import SocketListener
13
+ from ..testing import *
14
+ from ..testing._check_streams import _assert_raises
15
+ from ..testing._memory_streams import _UnboundedByteQueue
16
+
17
+ if TYPE_CHECKING:
18
+ from trio import Nursery
19
+ from trio.abc import ReceiveStream, SendStream
20
+
21
+
22
+ async def test_wait_all_tasks_blocked() -> None:
23
+ record = []
24
+
25
+ async def busy_bee() -> None:
26
+ for _ in range(10):
27
+ await _core.checkpoint()
28
+ record.append("busy bee exhausted")
29
+
30
+ async def waiting_for_bee_to_leave() -> None:
31
+ await wait_all_tasks_blocked()
32
+ record.append("quiet at last!")
33
+
34
+ async with _core.open_nursery() as nursery:
35
+ nursery.start_soon(busy_bee)
36
+ nursery.start_soon(waiting_for_bee_to_leave)
37
+ nursery.start_soon(waiting_for_bee_to_leave)
38
+
39
+ # check cancellation
40
+ record = []
41
+
42
+ async def cancelled_while_waiting() -> None:
43
+ try:
44
+ await wait_all_tasks_blocked()
45
+ except _core.Cancelled:
46
+ record.append("ok")
47
+
48
+ async with _core.open_nursery() as nursery:
49
+ nursery.start_soon(cancelled_while_waiting)
50
+ nursery.cancel_scope.cancel()
51
+ assert record == ["ok"]
52
+
53
+
54
+ async def test_wait_all_tasks_blocked_with_timeouts(mock_clock: MockClock) -> None:
55
+ record = []
56
+
57
+ async def timeout_task() -> None:
58
+ record.append("tt start")
59
+ await sleep(5)
60
+ record.append("tt finished")
61
+
62
+ async with _core.open_nursery() as nursery:
63
+ nursery.start_soon(timeout_task)
64
+ await wait_all_tasks_blocked()
65
+ assert record == ["tt start"]
66
+ mock_clock.jump(10)
67
+ await wait_all_tasks_blocked()
68
+ assert record == ["tt start", "tt finished"]
69
+
70
+
71
+ async def test_wait_all_tasks_blocked_with_cushion() -> None:
72
+ record = []
73
+
74
+ async def blink() -> None:
75
+ record.append("blink start")
76
+ await sleep(0.01)
77
+ await sleep(0.01)
78
+ await sleep(0.01)
79
+ record.append("blink end")
80
+
81
+ async def wait_no_cushion() -> None:
82
+ await wait_all_tasks_blocked()
83
+ record.append("wait_no_cushion end")
84
+
85
+ async def wait_small_cushion() -> None:
86
+ await wait_all_tasks_blocked(0.02)
87
+ record.append("wait_small_cushion end")
88
+
89
+ async def wait_big_cushion() -> None:
90
+ await wait_all_tasks_blocked(0.03)
91
+ record.append("wait_big_cushion end")
92
+
93
+ async with _core.open_nursery() as nursery:
94
+ nursery.start_soon(blink)
95
+ nursery.start_soon(wait_no_cushion)
96
+ nursery.start_soon(wait_small_cushion)
97
+ nursery.start_soon(wait_small_cushion)
98
+ nursery.start_soon(wait_big_cushion)
99
+
100
+ assert record == [
101
+ "blink start",
102
+ "wait_no_cushion end",
103
+ "blink end",
104
+ "wait_small_cushion end",
105
+ "wait_small_cushion end",
106
+ "wait_big_cushion end",
107
+ ]
108
+
109
+
110
+ ################################################################
111
+
112
+
113
+ async def test_assert_checkpoints(recwarn: pytest.WarningsRecorder) -> None:
114
+ with assert_checkpoints():
115
+ await _core.checkpoint()
116
+
117
+ with pytest.raises(AssertionError):
118
+ with assert_checkpoints():
119
+ 1 + 1 # noqa: B018 # "useless expression"
120
+
121
+ # partial yield cases
122
+ # if you have a schedule point but not a cancel point, or vice-versa, then
123
+ # that's not a checkpoint.
124
+ for partial_yield in [
125
+ _core.checkpoint_if_cancelled,
126
+ _core.cancel_shielded_checkpoint,
127
+ ]:
128
+ print(partial_yield)
129
+ with pytest.raises(AssertionError):
130
+ with assert_checkpoints():
131
+ await partial_yield()
132
+
133
+ # But both together count as a checkpoint
134
+ with assert_checkpoints():
135
+ await _core.checkpoint_if_cancelled()
136
+ await _core.cancel_shielded_checkpoint()
137
+
138
+
139
+ async def test_assert_no_checkpoints(recwarn: pytest.WarningsRecorder) -> None:
140
+ with assert_no_checkpoints():
141
+ 1 + 1 # noqa: B018 # "useless expression"
142
+
143
+ with pytest.raises(AssertionError):
144
+ with assert_no_checkpoints():
145
+ await _core.checkpoint()
146
+
147
+ # partial yield cases
148
+ # if you have a schedule point but not a cancel point, or vice-versa, then
149
+ # that doesn't make *either* version of assert_{no_,}yields happy.
150
+ for partial_yield in [
151
+ _core.checkpoint_if_cancelled,
152
+ _core.cancel_shielded_checkpoint,
153
+ ]:
154
+ print(partial_yield)
155
+ with pytest.raises(AssertionError):
156
+ with assert_no_checkpoints():
157
+ await partial_yield()
158
+
159
+ # And both together also count as a checkpoint
160
+ with pytest.raises(AssertionError):
161
+ with assert_no_checkpoints():
162
+ await _core.checkpoint_if_cancelled()
163
+ await _core.cancel_shielded_checkpoint()
164
+
165
+
166
+ ################################################################
167
+
168
+
169
+ async def test_Sequencer() -> None:
170
+ record = []
171
+
172
+ def t(val: object) -> None:
173
+ print(val)
174
+ record.append(val)
175
+
176
+ async def f1(seq: Sequencer) -> None:
177
+ async with seq(1):
178
+ t(("f1", 1))
179
+ async with seq(3):
180
+ t(("f1", 3))
181
+ async with seq(4):
182
+ t(("f1", 4))
183
+
184
+ async def f2(seq: Sequencer) -> None:
185
+ async with seq(0):
186
+ t(("f2", 0))
187
+ async with seq(2):
188
+ t(("f2", 2))
189
+
190
+ seq = Sequencer()
191
+ async with _core.open_nursery() as nursery:
192
+ nursery.start_soon(f1, seq)
193
+ nursery.start_soon(f2, seq)
194
+ async with seq(5):
195
+ await wait_all_tasks_blocked()
196
+ assert record == [("f2", 0), ("f1", 1), ("f2", 2), ("f1", 3), ("f1", 4)]
197
+
198
+ seq = Sequencer()
199
+ # Catches us if we try to reuse a sequence point:
200
+ async with seq(0):
201
+ pass
202
+ with pytest.raises(RuntimeError):
203
+ async with seq(0):
204
+ pass # pragma: no cover
205
+
206
+
207
+ async def test_Sequencer_cancel() -> None:
208
+ # Killing a blocked task makes everything blow up
209
+ record = []
210
+ seq = Sequencer()
211
+
212
+ async def child(i: int) -> None:
213
+ with _core.CancelScope() as scope:
214
+ if i == 1:
215
+ scope.cancel()
216
+ try:
217
+ async with seq(i):
218
+ pass # pragma: no cover
219
+ except RuntimeError:
220
+ record.append(f"seq({i}) RuntimeError")
221
+
222
+ async with _core.open_nursery() as nursery:
223
+ nursery.start_soon(child, 1)
224
+ nursery.start_soon(child, 2)
225
+ async with seq(0):
226
+ pass # pragma: no cover
227
+
228
+ assert record == ["seq(1) RuntimeError", "seq(2) RuntimeError"]
229
+
230
+ # Late arrivals also get errors
231
+ with pytest.raises(RuntimeError):
232
+ async with seq(3):
233
+ pass # pragma: no cover
234
+
235
+
236
+ ################################################################
237
+ def test__assert_raises() -> None:
238
+ with pytest.raises(AssertionError):
239
+ with _assert_raises(RuntimeError):
240
+ 1 + 1 # noqa: B018 # "useless expression"
241
+
242
+ with pytest.raises(TypeError):
243
+ with _assert_raises(RuntimeError):
244
+ "foo" + 1 # type: ignore[operator] # noqa: B018 # "useless expression"
245
+
246
+ with _assert_raises(RuntimeError):
247
+ raise RuntimeError
248
+
249
+
250
+ # This is a private implementation detail, but it's complex enough to be worth
251
+ # testing directly
252
+ async def test__UnboundeByteQueue() -> None:
253
+ ubq = _UnboundedByteQueue()
254
+
255
+ ubq.put(b"123")
256
+ ubq.put(b"456")
257
+ assert ubq.get_nowait(1) == b"1"
258
+ assert ubq.get_nowait(10) == b"23456"
259
+ ubq.put(b"789")
260
+ assert ubq.get_nowait() == b"789"
261
+
262
+ with pytest.raises(_core.WouldBlock):
263
+ ubq.get_nowait(10)
264
+ with pytest.raises(_core.WouldBlock):
265
+ ubq.get_nowait()
266
+
267
+ with pytest.raises(TypeError):
268
+ ubq.put("string") # type: ignore[arg-type]
269
+
270
+ ubq.put(b"abc")
271
+ with assert_checkpoints():
272
+ assert await ubq.get(10) == b"abc"
273
+ ubq.put(b"def")
274
+ ubq.put(b"ghi")
275
+ with assert_checkpoints():
276
+ assert await ubq.get(1) == b"d"
277
+ with assert_checkpoints():
278
+ assert await ubq.get() == b"efghi"
279
+
280
+ async def putter(data: bytes) -> None:
281
+ await wait_all_tasks_blocked()
282
+ ubq.put(data)
283
+
284
+ async def getter(expect: bytes) -> None:
285
+ with assert_checkpoints():
286
+ assert await ubq.get() == expect
287
+
288
+ async with _core.open_nursery() as nursery:
289
+ nursery.start_soon(getter, b"xyz")
290
+ nursery.start_soon(putter, b"xyz")
291
+
292
+ # Two gets at the same time -> BusyResourceError
293
+ with pytest.RaisesGroup(_core.BusyResourceError):
294
+ async with _core.open_nursery() as nursery:
295
+ nursery.start_soon(getter, b"asdf")
296
+ nursery.start_soon(getter, b"asdf")
297
+
298
+ # Closing
299
+
300
+ ubq.close()
301
+ with pytest.raises(_core.ClosedResourceError):
302
+ ubq.put(b"---")
303
+
304
+ assert ubq.get_nowait(10) == b""
305
+ assert ubq.get_nowait() == b""
306
+ assert await ubq.get(10) == b""
307
+ assert await ubq.get() == b""
308
+
309
+ # close is idempotent
310
+ ubq.close()
311
+
312
+ # close wakes up blocked getters
313
+ ubq2 = _UnboundedByteQueue()
314
+
315
+ async def closer() -> None:
316
+ await wait_all_tasks_blocked()
317
+ ubq2.close()
318
+
319
+ async with _core.open_nursery() as nursery:
320
+ nursery.start_soon(getter, b"")
321
+ nursery.start_soon(closer)
322
+
323
+
324
+ async def test_MemorySendStream() -> None:
325
+ mss = MemorySendStream()
326
+
327
+ async def do_send_all(data: bytes) -> None:
328
+ with assert_checkpoints():
329
+ await mss.send_all(data)
330
+
331
+ await do_send_all(b"123")
332
+ assert mss.get_data_nowait(1) == b"1"
333
+ assert mss.get_data_nowait() == b"23"
334
+
335
+ with assert_checkpoints():
336
+ await mss.wait_send_all_might_not_block()
337
+
338
+ with pytest.raises(_core.WouldBlock):
339
+ mss.get_data_nowait()
340
+ with pytest.raises(_core.WouldBlock):
341
+ mss.get_data_nowait(10)
342
+
343
+ await do_send_all(b"456")
344
+ with assert_checkpoints():
345
+ assert await mss.get_data() == b"456"
346
+
347
+ # Call send_all twice at once; one should get BusyResourceError and one
348
+ # should succeed. But we can't let the error propagate, because it might
349
+ # cause the other to be cancelled before it can finish doing its thing,
350
+ # and we don't know which one will get the error.
351
+ resource_busy_count = 0
352
+
353
+ async def do_send_all_count_resourcebusy() -> None:
354
+ nonlocal resource_busy_count
355
+ try:
356
+ await do_send_all(b"xxx")
357
+ except _core.BusyResourceError:
358
+ resource_busy_count += 1
359
+
360
+ async with _core.open_nursery() as nursery:
361
+ nursery.start_soon(do_send_all_count_resourcebusy)
362
+ nursery.start_soon(do_send_all_count_resourcebusy)
363
+
364
+ assert resource_busy_count == 1
365
+
366
+ with assert_checkpoints():
367
+ await mss.aclose()
368
+
369
+ assert await mss.get_data() == b"xxx"
370
+ assert await mss.get_data() == b""
371
+ with pytest.raises(_core.ClosedResourceError):
372
+ await do_send_all(b"---")
373
+
374
+ # hooks
375
+
376
+ assert mss.send_all_hook is None
377
+ assert mss.wait_send_all_might_not_block_hook is None
378
+ assert mss.close_hook is None
379
+
380
+ record = []
381
+
382
+ async def send_all_hook() -> None:
383
+ # hook runs after send_all does its work (can pull data out)
384
+ assert mss2.get_data_nowait() == b"abc"
385
+ record.append("send_all_hook")
386
+
387
+ async def wait_send_all_might_not_block_hook() -> None:
388
+ record.append("wait_send_all_might_not_block_hook")
389
+
390
+ def close_hook() -> None:
391
+ record.append("close_hook")
392
+
393
+ mss2 = MemorySendStream(
394
+ send_all_hook,
395
+ wait_send_all_might_not_block_hook,
396
+ close_hook,
397
+ )
398
+
399
+ assert mss2.send_all_hook is send_all_hook
400
+ assert mss2.wait_send_all_might_not_block_hook is wait_send_all_might_not_block_hook
401
+ assert mss2.close_hook is close_hook
402
+
403
+ await mss2.send_all(b"abc")
404
+ await mss2.wait_send_all_might_not_block()
405
+ await aclose_forcefully(mss2)
406
+ mss2.close()
407
+
408
+ assert record == [
409
+ "send_all_hook",
410
+ "wait_send_all_might_not_block_hook",
411
+ "close_hook",
412
+ "close_hook",
413
+ ]
414
+
415
+
416
+ async def test_MemoryReceiveStream() -> None:
417
+ mrs = MemoryReceiveStream()
418
+
419
+ async def do_receive_some(max_bytes: int | None) -> bytes:
420
+ with assert_checkpoints():
421
+ return await mrs.receive_some(max_bytes)
422
+
423
+ mrs.put_data(b"abc")
424
+ assert await do_receive_some(1) == b"a"
425
+ assert await do_receive_some(10) == b"bc"
426
+ mrs.put_data(b"abc")
427
+ assert await do_receive_some(None) == b"abc"
428
+
429
+ with pytest.RaisesGroup(_core.BusyResourceError):
430
+ async with _core.open_nursery() as nursery:
431
+ nursery.start_soon(do_receive_some, 10)
432
+ nursery.start_soon(do_receive_some, 10)
433
+
434
+ assert mrs.receive_some_hook is None
435
+
436
+ mrs.put_data(b"def")
437
+ mrs.put_eof()
438
+ mrs.put_eof()
439
+
440
+ assert await do_receive_some(10) == b"def"
441
+ assert await do_receive_some(10) == b""
442
+ assert await do_receive_some(10) == b""
443
+
444
+ with pytest.raises(_core.ClosedResourceError):
445
+ mrs.put_data(b"---")
446
+
447
+ async def receive_some_hook() -> None:
448
+ mrs2.put_data(b"xxx")
449
+
450
+ record = []
451
+
452
+ def close_hook() -> None:
453
+ record.append("closed")
454
+
455
+ mrs2 = MemoryReceiveStream(receive_some_hook, close_hook)
456
+ assert mrs2.receive_some_hook is receive_some_hook
457
+ assert mrs2.close_hook is close_hook
458
+
459
+ mrs2.put_data(b"yyy")
460
+ assert await mrs2.receive_some(10) == b"yyyxxx"
461
+ assert await mrs2.receive_some(10) == b"xxx"
462
+ assert await mrs2.receive_some(10) == b"xxx"
463
+
464
+ mrs2.put_data(b"zzz")
465
+ mrs2.receive_some_hook = None
466
+ assert await mrs2.receive_some(10) == b"zzz"
467
+
468
+ mrs2.put_data(b"lost on close")
469
+ with assert_checkpoints():
470
+ await mrs2.aclose()
471
+ assert record == ["closed"]
472
+
473
+ with pytest.raises(_core.ClosedResourceError):
474
+ await mrs2.receive_some(10)
475
+
476
+
477
+ async def test_MemoryRecvStream_closing() -> None:
478
+ mrs = MemoryReceiveStream()
479
+ # close with no pending data
480
+ mrs.close()
481
+ with pytest.raises(_core.ClosedResourceError):
482
+ assert await mrs.receive_some(10) == b""
483
+ # repeated closes ok
484
+ mrs.close()
485
+ # put_data now fails
486
+ with pytest.raises(_core.ClosedResourceError):
487
+ mrs.put_data(b"123")
488
+
489
+ mrs2 = MemoryReceiveStream()
490
+ # close with pending data
491
+ mrs2.put_data(b"xyz")
492
+ mrs2.close()
493
+ with pytest.raises(_core.ClosedResourceError):
494
+ await mrs2.receive_some(10)
495
+
496
+
497
+ async def test_memory_stream_pump() -> None:
498
+ mss = MemorySendStream()
499
+ mrs = MemoryReceiveStream()
500
+
501
+ # no-op if no data present
502
+ memory_stream_pump(mss, mrs)
503
+
504
+ await mss.send_all(b"123")
505
+ memory_stream_pump(mss, mrs)
506
+ assert await mrs.receive_some(10) == b"123"
507
+
508
+ await mss.send_all(b"456")
509
+ assert memory_stream_pump(mss, mrs, max_bytes=1)
510
+ assert await mrs.receive_some(10) == b"4"
511
+ assert memory_stream_pump(mss, mrs, max_bytes=1)
512
+ assert memory_stream_pump(mss, mrs, max_bytes=1)
513
+ assert not memory_stream_pump(mss, mrs, max_bytes=1)
514
+ assert await mrs.receive_some(10) == b"56"
515
+
516
+ mss.close()
517
+ memory_stream_pump(mss, mrs)
518
+ assert await mrs.receive_some(10) == b""
519
+
520
+
521
+ async def test_memory_stream_one_way_pair() -> None:
522
+ s, r = memory_stream_one_way_pair()
523
+ assert s.send_all_hook is not None
524
+ assert s.wait_send_all_might_not_block_hook is None
525
+ assert s.close_hook is not None
526
+ assert r.receive_some_hook is None
527
+ await s.send_all(b"123")
528
+ assert await r.receive_some(10) == b"123"
529
+
530
+ async def receiver(expected: bytes) -> None:
531
+ assert await r.receive_some(10) == expected
532
+
533
+ # This fails if we pump on r.receive_some_hook; we need to pump on s.send_all_hook
534
+ async with _core.open_nursery() as nursery:
535
+ nursery.start_soon(receiver, b"abc")
536
+ await wait_all_tasks_blocked()
537
+ await s.send_all(b"abc")
538
+
539
+ # And this fails if we don't pump from close_hook
540
+ async with _core.open_nursery() as nursery:
541
+ nursery.start_soon(receiver, b"")
542
+ await wait_all_tasks_blocked()
543
+ await s.aclose()
544
+
545
+ s, r = memory_stream_one_way_pair()
546
+
547
+ async with _core.open_nursery() as nursery:
548
+ nursery.start_soon(receiver, b"")
549
+ await wait_all_tasks_blocked()
550
+ s.close()
551
+
552
+ s, r = memory_stream_one_way_pair()
553
+
554
+ old = s.send_all_hook
555
+ s.send_all_hook = None
556
+ await s.send_all(b"456")
557
+
558
+ async def cancel_after_idle(nursery: Nursery) -> None:
559
+ await wait_all_tasks_blocked()
560
+ nursery.cancel_scope.cancel()
561
+
562
+ async def check_for_cancel() -> None:
563
+ with pytest.raises(_core.Cancelled):
564
+ # This should block forever... or until cancelled. Even though we
565
+ # sent some data on the send stream.
566
+ await r.receive_some(10)
567
+
568
+ async with _core.open_nursery() as nursery:
569
+ nursery.start_soon(cancel_after_idle, nursery)
570
+ nursery.start_soon(check_for_cancel)
571
+
572
+ s.send_all_hook = old
573
+ await s.send_all(b"789")
574
+ assert await r.receive_some(10) == b"456789"
575
+
576
+
577
+ async def test_memory_stream_pair() -> None:
578
+ a, b = memory_stream_pair()
579
+ await a.send_all(b"123")
580
+ await b.send_all(b"abc")
581
+ assert await b.receive_some(10) == b"123"
582
+ assert await a.receive_some(10) == b"abc"
583
+
584
+ await a.send_eof()
585
+ assert await b.receive_some(10) == b""
586
+
587
+ async def sender() -> None:
588
+ await wait_all_tasks_blocked()
589
+ await b.send_all(b"xyz")
590
+
591
+ async def receiver() -> None:
592
+ assert await a.receive_some(10) == b"xyz"
593
+
594
+ async with _core.open_nursery() as nursery:
595
+ nursery.start_soon(receiver)
596
+ nursery.start_soon(sender)
597
+
598
+
599
+ async def test_memory_streams_with_generic_tests() -> None:
600
+ async def one_way_stream_maker() -> tuple[MemorySendStream, MemoryReceiveStream]:
601
+ return memory_stream_one_way_pair()
602
+
603
+ await check_one_way_stream(one_way_stream_maker, None)
604
+
605
+ async def half_closeable_stream_maker() -> tuple[
606
+ StapledStream[MemorySendStream, MemoryReceiveStream],
607
+ StapledStream[MemorySendStream, MemoryReceiveStream],
608
+ ]:
609
+ return memory_stream_pair()
610
+
611
+ await check_half_closeable_stream(half_closeable_stream_maker, None)
612
+
613
+
614
+ async def test_lockstep_streams_with_generic_tests() -> None:
615
+ async def one_way_stream_maker() -> tuple[SendStream, ReceiveStream]:
616
+ return lockstep_stream_one_way_pair()
617
+
618
+ await check_one_way_stream(one_way_stream_maker, one_way_stream_maker)
619
+
620
+ async def two_way_stream_maker() -> tuple[
621
+ StapledStream[SendStream, ReceiveStream],
622
+ StapledStream[SendStream, ReceiveStream],
623
+ ]:
624
+ return lockstep_stream_pair()
625
+
626
+ await check_two_way_stream(two_way_stream_maker, two_way_stream_maker)
627
+
628
+
629
+ async def test_open_stream_to_socket_listener() -> None:
630
+ async def check(listener: SocketListener) -> None:
631
+ async with listener:
632
+ client_stream = await open_stream_to_socket_listener(listener)
633
+ async with client_stream:
634
+ server_stream = await listener.accept()
635
+ async with server_stream:
636
+ await client_stream.send_all(b"x")
637
+ assert await server_stream.receive_some(1) == b"x"
638
+
639
+ # Listener bound to localhost
640
+ sock = tsocket.socket()
641
+ await sock.bind(("127.0.0.1", 0))
642
+ sock.listen(10)
643
+ await check(SocketListener(sock))
644
+
645
+ # Listener bound to IPv4 wildcard (needs special handling)
646
+ sock = tsocket.socket()
647
+ await sock.bind(("0.0.0.0", 0))
648
+ sock.listen(10)
649
+ await check(SocketListener(sock))
650
+
651
+ # true on all CI systems
652
+ if can_bind_ipv6: # pragma: no branch
653
+ # Listener bound to IPv6 wildcard (needs special handling)
654
+ sock = tsocket.socket(family=tsocket.AF_INET6)
655
+ await sock.bind(("::", 0))
656
+ sock.listen(10)
657
+ await check(SocketListener(sock))
658
+
659
+ if hasattr(tsocket, "AF_UNIX"):
660
+ # Listener bound to Unix-domain socket
661
+ sock = tsocket.socket(family=tsocket.AF_UNIX)
662
+ # can't use pytest's tmpdir; if we try then macOS says "OSError:
663
+ # AF_UNIX path too long"
664
+ with tempfile.TemporaryDirectory() as tmpdir:
665
+ path = f"{tmpdir}/sock"
666
+ await sock.bind(path)
667
+ sock.listen(10)
668
+ await check(SocketListener(sock))
669
+
670
+
671
+ def test_trio_test() -> None:
672
+ async def busy_kitchen(
673
+ *,
674
+ mock_clock: object,
675
+ autojump_clock: object,
676
+ ) -> None: ... # pragma: no cover
677
+
678
+ with pytest.raises(ValueError, match=r"^too many clocks spoil the broth!$"):
679
+ trio_test(busy_kitchen)(
680
+ mock_clock=MockClock(),
681
+ autojump_clock=MockClock(autojump_threshold=0),
682
+ )