@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.
- package/bin/kgraph-launcher +15 -3
- package/lib/kgraph/scripts/build-bundle.sh +17 -4
- package/lib/site-packages/outcome/__init__.py +20 -0
- package/lib/site-packages/outcome/_impl.py +239 -0
- package/lib/site-packages/outcome/_util.py +33 -0
- package/lib/site-packages/outcome/_version.py +7 -0
- package/lib/site-packages/outcome/py.typed +0 -0
- package/lib/site-packages/outcome-1.3.0.post0.dist-info/INSTALLER +1 -0
- package/lib/site-packages/outcome-1.3.0.post0.dist-info/LICENSE +3 -0
- package/lib/site-packages/outcome-1.3.0.post0.dist-info/LICENSE.APACHE2 +202 -0
- package/lib/site-packages/outcome-1.3.0.post0.dist-info/LICENSE.MIT +20 -0
- package/lib/site-packages/outcome-1.3.0.post0.dist-info/METADATA +63 -0
- package/lib/site-packages/outcome-1.3.0.post0.dist-info/RECORD +13 -0
- package/lib/site-packages/outcome-1.3.0.post0.dist-info/WHEEL +6 -0
- package/lib/site-packages/outcome-1.3.0.post0.dist-info/top_level.txt +1 -0
- package/lib/site-packages/sniffio/__init__.py +17 -0
- package/lib/site-packages/sniffio/_impl.py +95 -0
- package/lib/site-packages/sniffio/_tests/__init__.py +0 -0
- package/lib/site-packages/sniffio/_tests/test_sniffio.py +84 -0
- package/lib/site-packages/sniffio/_version.py +3 -0
- package/lib/site-packages/sniffio/py.typed +0 -0
- package/lib/site-packages/sniffio-1.3.1.dist-info/INSTALLER +1 -0
- package/lib/site-packages/sniffio-1.3.1.dist-info/LICENSE +3 -0
- package/lib/site-packages/sniffio-1.3.1.dist-info/LICENSE.APACHE2 +202 -0
- package/lib/site-packages/sniffio-1.3.1.dist-info/LICENSE.MIT +20 -0
- package/lib/site-packages/sniffio-1.3.1.dist-info/METADATA +104 -0
- package/lib/site-packages/sniffio-1.3.1.dist-info/RECORD +14 -0
- package/lib/site-packages/sniffio-1.3.1.dist-info/WHEEL +5 -0
- package/lib/site-packages/sniffio-1.3.1.dist-info/top_level.txt +1 -0
- package/lib/site-packages/sortedcontainers/__init__.py +74 -0
- package/lib/site-packages/sortedcontainers/sorteddict.py +812 -0
- package/lib/site-packages/sortedcontainers/sortedlist.py +2646 -0
- package/lib/site-packages/sortedcontainers/sortedset.py +733 -0
- package/lib/site-packages/sortedcontainers-2.4.0.dist-info/INSTALLER +1 -0
- package/lib/site-packages/sortedcontainers-2.4.0.dist-info/LICENSE +13 -0
- package/lib/site-packages/sortedcontainers-2.4.0.dist-info/METADATA +264 -0
- package/lib/site-packages/sortedcontainers-2.4.0.dist-info/RECORD +10 -0
- package/lib/site-packages/sortedcontainers-2.4.0.dist-info/WHEEL +6 -0
- package/lib/site-packages/sortedcontainers-2.4.0.dist-info/top_level.txt +1 -0
- package/lib/site-packages/trio/__init__.py +133 -0
- package/lib/site-packages/trio/__main__.py +3 -0
- package/lib/site-packages/trio/_abc.py +714 -0
- package/lib/site-packages/trio/_channel.py +610 -0
- package/lib/site-packages/trio/_core/__init__.py +94 -0
- package/lib/site-packages/trio/_core/_asyncgens.py +243 -0
- package/lib/site-packages/trio/_core/_concat_tb.py +26 -0
- package/lib/site-packages/trio/_core/_entry_queue.py +223 -0
- package/lib/site-packages/trio/_core/_exceptions.py +169 -0
- package/lib/site-packages/trio/_core/_generated_instrumentation.py +50 -0
- package/lib/site-packages/trio/_core/_generated_io_epoll.py +98 -0
- package/lib/site-packages/trio/_core/_generated_io_kqueue.py +153 -0
- package/lib/site-packages/trio/_core/_generated_io_windows.py +204 -0
- package/lib/site-packages/trio/_core/_generated_run.py +269 -0
- package/lib/site-packages/trio/_core/_generated_windows_ffi.py +10 -0
- package/lib/site-packages/trio/_core/_instrumentation.py +117 -0
- package/lib/site-packages/trio/_core/_io_common.py +31 -0
- package/lib/site-packages/trio/_core/_io_epoll.py +385 -0
- package/lib/site-packages/trio/_core/_io_kqueue.py +292 -0
- package/lib/site-packages/trio/_core/_io_windows.py +1036 -0
- package/lib/site-packages/trio/_core/_ki.py +271 -0
- package/lib/site-packages/trio/_core/_local.py +104 -0
- package/lib/site-packages/trio/_core/_mock_clock.py +165 -0
- package/lib/site-packages/trio/_core/_parking_lot.py +317 -0
- package/lib/site-packages/trio/_core/_run.py +3148 -0
- package/lib/site-packages/trio/_core/_run_context.py +15 -0
- package/lib/site-packages/trio/_core/_tests/__init__.py +0 -0
- package/lib/site-packages/trio/_core/_tests/test_asyncgen.py +339 -0
- package/lib/site-packages/trio/_core/_tests/test_cancelled.py +222 -0
- package/lib/site-packages/trio/_core/_tests/test_exceptiongroup_gc.py +103 -0
- package/lib/site-packages/trio/_core/_tests/test_guest_mode.py +755 -0
- package/lib/site-packages/trio/_core/_tests/test_instrumentation.py +315 -0
- package/lib/site-packages/trio/_core/_tests/test_io.py +522 -0
- package/lib/site-packages/trio/_core/_tests/test_ki.py +703 -0
- package/lib/site-packages/trio/_core/_tests/test_local.py +118 -0
- package/lib/site-packages/trio/_core/_tests/test_mock_clock.py +193 -0
- package/lib/site-packages/trio/_core/_tests/test_parking_lot.py +389 -0
- package/lib/site-packages/trio/_core/_tests/test_run.py +3024 -0
- package/lib/site-packages/trio/_core/_tests/test_thread_cache.py +227 -0
- package/lib/site-packages/trio/_core/_tests/test_tutil.py +13 -0
- package/lib/site-packages/trio/_core/_tests/test_unbounded_queue.py +154 -0
- package/lib/site-packages/trio/_core/_tests/test_windows.py +305 -0
- package/lib/site-packages/trio/_core/_tests/tutil.py +117 -0
- package/lib/site-packages/trio/_core/_tests/type_tests/nursery_start.py +79 -0
- package/lib/site-packages/trio/_core/_tests/type_tests/run.py +51 -0
- package/lib/site-packages/trio/_core/_thread_cache.py +317 -0
- package/lib/site-packages/trio/_core/_traps.py +318 -0
- package/lib/site-packages/trio/_core/_unbounded_queue.py +163 -0
- package/lib/site-packages/trio/_core/_wakeup_socketpair.py +75 -0
- package/lib/site-packages/trio/_core/_windows_cffi.py +313 -0
- package/lib/site-packages/trio/_deprecate.py +171 -0
- package/lib/site-packages/trio/_dtls.py +1380 -0
- package/lib/site-packages/trio/_file_io.py +513 -0
- package/lib/site-packages/trio/_highlevel_generic.py +125 -0
- package/lib/site-packages/trio/_highlevel_open_tcp_listeners.py +251 -0
- package/lib/site-packages/trio/_highlevel_open_tcp_stream.py +397 -0
- package/lib/site-packages/trio/_highlevel_open_unix_stream.py +65 -0
- package/lib/site-packages/trio/_highlevel_serve_listeners.py +148 -0
- package/lib/site-packages/trio/_highlevel_socket.py +423 -0
- package/lib/site-packages/trio/_highlevel_ssl_helpers.py +180 -0
- package/lib/site-packages/trio/_path.py +289 -0
- package/lib/site-packages/trio/_repl.py +159 -0
- package/lib/site-packages/trio/_signals.py +185 -0
- package/lib/site-packages/trio/_socket.py +1326 -0
- package/lib/site-packages/trio/_ssl.py +964 -0
- package/lib/site-packages/trio/_subprocess.py +1178 -0
- package/lib/site-packages/trio/_subprocess_platform/__init__.py +123 -0
- package/lib/site-packages/trio/_subprocess_platform/kqueue.py +48 -0
- package/lib/site-packages/trio/_subprocess_platform/waitid.py +113 -0
- package/lib/site-packages/trio/_subprocess_platform/windows.py +11 -0
- package/lib/site-packages/trio/_sync.py +908 -0
- package/lib/site-packages/trio/_tests/__init__.py +0 -0
- package/lib/site-packages/trio/_tests/astrill-codesigning-cert.cer +0 -0
- package/lib/site-packages/trio/_tests/check_type_completeness.py +247 -0
- package/lib/site-packages/trio/_tests/module_with_deprecations.py +22 -0
- package/lib/site-packages/trio/_tests/pytest_plugin.py +54 -0
- package/lib/site-packages/trio/_tests/test_abc.py +72 -0
- package/lib/site-packages/trio/_tests/test_channel.py +750 -0
- package/lib/site-packages/trio/_tests/test_contextvars.py +56 -0
- package/lib/site-packages/trio/_tests/test_deprecate.py +277 -0
- package/lib/site-packages/trio/_tests/test_deprecate_strict_exception_groups_false.py +64 -0
- package/lib/site-packages/trio/_tests/test_dtls.py +950 -0
- package/lib/site-packages/trio/_tests/test_exports.py +626 -0
- package/lib/site-packages/trio/_tests/test_fakenet.py +317 -0
- package/lib/site-packages/trio/_tests/test_file_io.py +269 -0
- package/lib/site-packages/trio/_tests/test_highlevel_generic.py +98 -0
- package/lib/site-packages/trio/_tests/test_highlevel_open_tcp_listeners.py +419 -0
- package/lib/site-packages/trio/_tests/test_highlevel_open_tcp_stream.py +693 -0
- package/lib/site-packages/trio/_tests/test_highlevel_open_unix_stream.py +86 -0
- package/lib/site-packages/trio/_tests/test_highlevel_serve_listeners.py +186 -0
- package/lib/site-packages/trio/_tests/test_highlevel_socket.py +336 -0
- package/lib/site-packages/trio/_tests/test_highlevel_ssl_helpers.py +169 -0
- package/lib/site-packages/trio/_tests/test_path.py +279 -0
- package/lib/site-packages/trio/_tests/test_repl.py +428 -0
- package/lib/site-packages/trio/_tests/test_scheduler_determinism.py +47 -0
- package/lib/site-packages/trio/_tests/test_signals.py +186 -0
- package/lib/site-packages/trio/_tests/test_socket.py +1253 -0
- package/lib/site-packages/trio/_tests/test_ssl.py +1371 -0
- package/lib/site-packages/trio/_tests/test_subprocess.py +767 -0
- package/lib/site-packages/trio/_tests/test_sync.py +735 -0
- package/lib/site-packages/trio/_tests/test_testing.py +682 -0
- package/lib/site-packages/trio/_tests/test_testing_raisesgroup.py +1128 -0
- package/lib/site-packages/trio/_tests/test_threads.py +1173 -0
- package/lib/site-packages/trio/_tests/test_timeouts.py +281 -0
- package/lib/site-packages/trio/_tests/test_tracing.py +88 -0
- package/lib/site-packages/trio/_tests/test_trio.py +8 -0
- package/lib/site-packages/trio/_tests/test_unix_pipes.py +288 -0
- package/lib/site-packages/trio/_tests/test_util.py +349 -0
- package/lib/site-packages/trio/_tests/test_wait_for_object.py +225 -0
- package/lib/site-packages/trio/_tests/test_windows_pipes.py +112 -0
- package/lib/site-packages/trio/_tests/tools/__init__.py +0 -0
- package/lib/site-packages/trio/_tests/tools/test_gen_exports.py +179 -0
- package/lib/site-packages/trio/_tests/tools/test_mypy_annotate.py +140 -0
- package/lib/site-packages/trio/_tests/tools/test_sync_requirements.py +80 -0
- package/lib/site-packages/trio/_tests/type_tests/check_wraps.py +9 -0
- package/lib/site-packages/trio/_tests/type_tests/open_memory_channel.py +4 -0
- package/lib/site-packages/trio/_tests/type_tests/path.py +140 -0
- package/lib/site-packages/trio/_tests/type_tests/subprocesses.py +23 -0
- package/lib/site-packages/trio/_tests/type_tests/task_status.py +29 -0
- package/lib/site-packages/trio/_threads.py +610 -0
- package/lib/site-packages/trio/_timeouts.py +197 -0
- package/lib/site-packages/trio/_tools/__init__.py +0 -0
- package/lib/site-packages/trio/_tools/gen_exports.py +401 -0
- package/lib/site-packages/trio/_tools/mypy_annotate.py +126 -0
- package/lib/site-packages/trio/_tools/sync_requirements.py +98 -0
- package/lib/site-packages/trio/_tools/windows_ffi_build.py +220 -0
- package/lib/site-packages/trio/_unix_pipes.py +197 -0
- package/lib/site-packages/trio/_util.py +385 -0
- package/lib/site-packages/trio/_version.py +3 -0
- package/lib/site-packages/trio/_wait_for_object.py +67 -0
- package/lib/site-packages/trio/_windows_pipes.py +144 -0
- package/lib/site-packages/trio/abc.py +23 -0
- package/lib/site-packages/trio/from_thread.py +13 -0
- package/lib/site-packages/trio/lowlevel.py +95 -0
- package/lib/site-packages/trio/py.typed +0 -0
- package/lib/site-packages/trio/socket.py +602 -0
- package/lib/site-packages/trio/testing/__init__.py +58 -0
- package/lib/site-packages/trio/testing/_check_streams.py +570 -0
- package/lib/site-packages/trio/testing/_checkpoints.py +69 -0
- package/lib/site-packages/trio/testing/_fake_net.py +584 -0
- package/lib/site-packages/trio/testing/_memory_streams.py +633 -0
- package/lib/site-packages/trio/testing/_network.py +36 -0
- package/lib/site-packages/trio/testing/_raises_group.py +1015 -0
- package/lib/site-packages/trio/testing/_sequencer.py +87 -0
- package/lib/site-packages/trio/testing/_trio_test.py +50 -0
- package/lib/site-packages/trio/to_thread.py +4 -0
- package/lib/site-packages/trio-0.33.0.dist-info/INSTALLER +1 -0
- package/lib/site-packages/trio-0.33.0.dist-info/METADATA +186 -0
- package/lib/site-packages/trio-0.33.0.dist-info/RECORD +156 -0
- package/lib/site-packages/trio-0.33.0.dist-info/REQUESTED +0 -0
- package/lib/site-packages/trio-0.33.0.dist-info/WHEEL +5 -0
- package/lib/site-packages/trio-0.33.0.dist-info/entry_points.txt +2 -0
- package/lib/site-packages/trio-0.33.0.dist-info/licenses/LICENSE +3 -0
- package/lib/site-packages/trio-0.33.0.dist-info/licenses/LICENSE.APACHE2 +202 -0
- package/lib/site-packages/trio-0.33.0.dist-info/licenses/LICENSE.MIT +22 -0
- package/lib/site-packages/trio-0.33.0.dist-info/top_level.txt +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
# ***********************************************************
|
|
2
|
+
# ******* WARNING: AUTOGENERATED! ALL EDITS WILL BE LOST ******
|
|
3
|
+
# *************************************************************
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
from ._ki import enable_ki_protection
|
|
9
|
+
from ._run import _NO_SEND, GLOBAL_RUN_CONTEXT, RunStatistics, Task
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
import contextvars
|
|
13
|
+
from collections.abc import Awaitable, Callable
|
|
14
|
+
|
|
15
|
+
import outcome
|
|
16
|
+
from typing_extensions import Unpack
|
|
17
|
+
|
|
18
|
+
from .._abc import Clock
|
|
19
|
+
from ._entry_queue import TrioToken
|
|
20
|
+
from ._run import PosArgT
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
"current_clock",
|
|
25
|
+
"current_root_task",
|
|
26
|
+
"current_statistics",
|
|
27
|
+
"current_time",
|
|
28
|
+
"current_trio_token",
|
|
29
|
+
"reschedule",
|
|
30
|
+
"spawn_system_task",
|
|
31
|
+
"wait_all_tasks_blocked",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@enable_ki_protection
|
|
36
|
+
def current_statistics() -> RunStatistics:
|
|
37
|
+
"""Returns ``RunStatistics``, which contains run-loop-level debugging information.
|
|
38
|
+
|
|
39
|
+
Currently, the following fields are defined:
|
|
40
|
+
|
|
41
|
+
* ``tasks_living`` (int): The number of tasks that have been spawned
|
|
42
|
+
and not yet exited.
|
|
43
|
+
* ``tasks_runnable`` (int): The number of tasks that are currently
|
|
44
|
+
queued on the run queue (as opposed to blocked waiting for something
|
|
45
|
+
to happen).
|
|
46
|
+
* ``seconds_to_next_deadline`` (float): The time until the next
|
|
47
|
+
pending cancel scope deadline. May be negative if the deadline has
|
|
48
|
+
expired but we haven't yet processed cancellations. May be
|
|
49
|
+
:data:`~math.inf` if there are no pending deadlines.
|
|
50
|
+
* ``run_sync_soon_queue_size`` (int): The number of
|
|
51
|
+
unprocessed callbacks queued via
|
|
52
|
+
:meth:`trio.lowlevel.TrioToken.run_sync_soon`.
|
|
53
|
+
* ``io_statistics`` (object): Some statistics from Trio's I/O
|
|
54
|
+
backend. This always has an attribute ``backend`` which is a string
|
|
55
|
+
naming which operating-system-specific I/O backend is in use; the
|
|
56
|
+
other attributes vary between backends.
|
|
57
|
+
|
|
58
|
+
"""
|
|
59
|
+
try:
|
|
60
|
+
return GLOBAL_RUN_CONTEXT.runner.current_statistics()
|
|
61
|
+
except AttributeError:
|
|
62
|
+
raise RuntimeError("must be called from async context") from None
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@enable_ki_protection
|
|
66
|
+
def current_time() -> float:
|
|
67
|
+
"""Returns the current time according to Trio's internal clock.
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
float: The current time.
|
|
71
|
+
|
|
72
|
+
Raises:
|
|
73
|
+
RuntimeError: if not inside a call to :func:`trio.run`.
|
|
74
|
+
|
|
75
|
+
"""
|
|
76
|
+
try:
|
|
77
|
+
return GLOBAL_RUN_CONTEXT.runner.current_time()
|
|
78
|
+
except AttributeError:
|
|
79
|
+
raise RuntimeError("must be called from async context") from None
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@enable_ki_protection
|
|
83
|
+
def current_clock() -> Clock:
|
|
84
|
+
"""Returns the current :class:`~trio.abc.Clock`."""
|
|
85
|
+
try:
|
|
86
|
+
return GLOBAL_RUN_CONTEXT.runner.current_clock()
|
|
87
|
+
except AttributeError:
|
|
88
|
+
raise RuntimeError("must be called from async context") from None
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@enable_ki_protection
|
|
92
|
+
def current_root_task() -> Task | None:
|
|
93
|
+
"""Returns the current root :class:`Task`.
|
|
94
|
+
|
|
95
|
+
This is the task that is the ultimate parent of all other tasks.
|
|
96
|
+
|
|
97
|
+
"""
|
|
98
|
+
try:
|
|
99
|
+
return GLOBAL_RUN_CONTEXT.runner.current_root_task()
|
|
100
|
+
except AttributeError:
|
|
101
|
+
raise RuntimeError("must be called from async context") from None
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@enable_ki_protection
|
|
105
|
+
def reschedule(task: Task, next_send: outcome.Outcome[object] = _NO_SEND) -> None:
|
|
106
|
+
"""Reschedule the given task with the given
|
|
107
|
+
:class:`outcome.Outcome`.
|
|
108
|
+
|
|
109
|
+
See :func:`wait_task_rescheduled` for the gory details.
|
|
110
|
+
|
|
111
|
+
There must be exactly one call to :func:`reschedule` for every call to
|
|
112
|
+
:func:`wait_task_rescheduled`. (And when counting, keep in mind that
|
|
113
|
+
returning :data:`Abort.SUCCEEDED` from an abort callback is equivalent
|
|
114
|
+
to calling :func:`reschedule` once.)
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
task (trio.lowlevel.Task): the task to be rescheduled. Must be blocked
|
|
118
|
+
in a call to :func:`wait_task_rescheduled`.
|
|
119
|
+
next_send (outcome.Outcome): the value (or error) to return (or
|
|
120
|
+
raise) from :func:`wait_task_rescheduled`.
|
|
121
|
+
|
|
122
|
+
"""
|
|
123
|
+
try:
|
|
124
|
+
return GLOBAL_RUN_CONTEXT.runner.reschedule(task, next_send)
|
|
125
|
+
except AttributeError:
|
|
126
|
+
raise RuntimeError("must be called from async context") from None
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
@enable_ki_protection
|
|
130
|
+
def spawn_system_task(
|
|
131
|
+
async_fn: Callable[[Unpack[PosArgT]], Awaitable[object]],
|
|
132
|
+
*args: Unpack[PosArgT],
|
|
133
|
+
name: object = None,
|
|
134
|
+
context: contextvars.Context | None = None,
|
|
135
|
+
) -> Task:
|
|
136
|
+
"""Spawn a "system" task.
|
|
137
|
+
|
|
138
|
+
System tasks have a few differences from regular tasks:
|
|
139
|
+
|
|
140
|
+
* They don't need an explicit nursery; instead they go into the
|
|
141
|
+
internal "system nursery".
|
|
142
|
+
|
|
143
|
+
* If a system task raises an exception, then it's converted into a
|
|
144
|
+
:exc:`~trio.TrioInternalError` and *all* tasks are cancelled. If you
|
|
145
|
+
write a system task, you should be careful to make sure it doesn't
|
|
146
|
+
crash.
|
|
147
|
+
|
|
148
|
+
* System tasks are automatically cancelled when the main task exits.
|
|
149
|
+
|
|
150
|
+
* By default, system tasks have :exc:`KeyboardInterrupt` protection
|
|
151
|
+
*enabled*. If you want your task to be interruptible by control-C,
|
|
152
|
+
then you need to use :func:`disable_ki_protection` explicitly (and
|
|
153
|
+
come up with some plan for what to do with a
|
|
154
|
+
:exc:`KeyboardInterrupt`, given that system tasks aren't allowed to
|
|
155
|
+
raise exceptions).
|
|
156
|
+
|
|
157
|
+
* System tasks do not inherit context variables from their creator.
|
|
158
|
+
|
|
159
|
+
Towards the end of a call to :meth:`trio.run`, after the main
|
|
160
|
+
task and all system tasks have exited, the system nursery
|
|
161
|
+
becomes closed. At this point, new calls to
|
|
162
|
+
:func:`spawn_system_task` will raise ``RuntimeError("Nursery
|
|
163
|
+
is closed to new arrivals")`` instead of creating a system
|
|
164
|
+
task. It's possible to encounter this state either in
|
|
165
|
+
a ``finally`` block in an async generator, or in a callback
|
|
166
|
+
passed to :meth:`TrioToken.run_sync_soon` at the right moment.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
async_fn: An async callable.
|
|
170
|
+
args: Positional arguments for ``async_fn``. If you want to pass
|
|
171
|
+
keyword arguments, use :func:`functools.partial`.
|
|
172
|
+
name: The name for this task. Only used for debugging/introspection
|
|
173
|
+
(e.g. ``repr(task_obj)``). If this isn't a string,
|
|
174
|
+
:func:`spawn_system_task` will try to make it one. A common use
|
|
175
|
+
case is if you're wrapping a function before spawning a new
|
|
176
|
+
task, you might pass the original function as the ``name=`` to
|
|
177
|
+
make debugging easier.
|
|
178
|
+
context: An optional ``contextvars.Context`` object with context variables
|
|
179
|
+
to use for this task. You would normally get a copy of the current
|
|
180
|
+
context with ``context = contextvars.copy_context()`` and then you would
|
|
181
|
+
pass that ``context`` object here.
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
Task: the newly spawned task
|
|
185
|
+
|
|
186
|
+
"""
|
|
187
|
+
try:
|
|
188
|
+
return GLOBAL_RUN_CONTEXT.runner.spawn_system_task(
|
|
189
|
+
async_fn, *args, name=name, context=context
|
|
190
|
+
)
|
|
191
|
+
except AttributeError:
|
|
192
|
+
raise RuntimeError("must be called from async context") from None
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
@enable_ki_protection
|
|
196
|
+
def current_trio_token() -> TrioToken:
|
|
197
|
+
"""Retrieve the :class:`TrioToken` for the current call to
|
|
198
|
+
:func:`trio.run`.
|
|
199
|
+
|
|
200
|
+
"""
|
|
201
|
+
try:
|
|
202
|
+
return GLOBAL_RUN_CONTEXT.runner.current_trio_token()
|
|
203
|
+
except AttributeError:
|
|
204
|
+
raise RuntimeError("must be called from async context") from None
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
@enable_ki_protection
|
|
208
|
+
async def wait_all_tasks_blocked(cushion: float = 0.0) -> None:
|
|
209
|
+
"""Block until there are no runnable tasks.
|
|
210
|
+
|
|
211
|
+
This is useful in testing code when you want to give other tasks a
|
|
212
|
+
chance to "settle down". The calling task is blocked, and doesn't wake
|
|
213
|
+
up until all other tasks are also blocked for at least ``cushion``
|
|
214
|
+
seconds. (Setting a non-zero ``cushion`` is intended to handle cases
|
|
215
|
+
like two tasks talking to each other over a local socket, where we
|
|
216
|
+
want to ignore the potential brief moment between a send and receive
|
|
217
|
+
when all tasks are blocked.)
|
|
218
|
+
|
|
219
|
+
Note that ``cushion`` is measured in *real* time, not the Trio clock
|
|
220
|
+
time.
|
|
221
|
+
|
|
222
|
+
If there are multiple tasks blocked in :func:`wait_all_tasks_blocked`,
|
|
223
|
+
then the one with the shortest ``cushion`` is the one woken (and
|
|
224
|
+
this task becoming unblocked resets the timers for the remaining
|
|
225
|
+
tasks). If there are multiple tasks that have exactly the same
|
|
226
|
+
``cushion``, then all are woken.
|
|
227
|
+
|
|
228
|
+
You should also consider :class:`trio.testing.Sequencer`, which
|
|
229
|
+
provides a more explicit way to control execution ordering within a
|
|
230
|
+
test, and will often produce more readable tests.
|
|
231
|
+
|
|
232
|
+
Example:
|
|
233
|
+
Here's an example of one way to test that Trio's locks are fair: we
|
|
234
|
+
take the lock in the parent, start a child, wait for the child to be
|
|
235
|
+
blocked waiting for the lock (!), and then check that we can't
|
|
236
|
+
release and immediately re-acquire the lock::
|
|
237
|
+
|
|
238
|
+
async def lock_taker(lock):
|
|
239
|
+
await lock.acquire()
|
|
240
|
+
lock.release()
|
|
241
|
+
|
|
242
|
+
async def test_lock_fairness():
|
|
243
|
+
lock = trio.Lock()
|
|
244
|
+
await lock.acquire()
|
|
245
|
+
async with trio.open_nursery() as nursery:
|
|
246
|
+
nursery.start_soon(lock_taker, lock)
|
|
247
|
+
# child hasn't run yet, we have the lock
|
|
248
|
+
assert lock.locked()
|
|
249
|
+
assert lock._owner is trio.lowlevel.current_task()
|
|
250
|
+
await trio.testing.wait_all_tasks_blocked()
|
|
251
|
+
# now the child has run and is blocked on lock.acquire(), we
|
|
252
|
+
# still have the lock
|
|
253
|
+
assert lock.locked()
|
|
254
|
+
assert lock._owner is trio.lowlevel.current_task()
|
|
255
|
+
lock.release()
|
|
256
|
+
try:
|
|
257
|
+
# The child has a prior claim, so we can't have it
|
|
258
|
+
lock.acquire_nowait()
|
|
259
|
+
except trio.WouldBlock:
|
|
260
|
+
assert lock._owner is not trio.lowlevel.current_task()
|
|
261
|
+
print("PASS")
|
|
262
|
+
else:
|
|
263
|
+
print("FAIL")
|
|
264
|
+
|
|
265
|
+
"""
|
|
266
|
+
try:
|
|
267
|
+
return await GLOBAL_RUN_CONTEXT.runner.wait_all_tasks_blocked(cushion)
|
|
268
|
+
except AttributeError:
|
|
269
|
+
raise RuntimeError("must be called from async context") from None
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# auto-generated file
|
|
2
|
+
import _cffi_backend
|
|
3
|
+
|
|
4
|
+
ffi = _cffi_backend.FFI('trio._core._generated_windows_ffi',
|
|
5
|
+
_version = 0x2601,
|
|
6
|
+
_types = b'\x00\x00\x39\x0D\x00\x00\x1A\x01\x00\x00\x0A\x01\x00\x00\x72\x03\x00\x00\x0A\x01\x00\x00\x03\x11\x00\x00\x0A\x01\x00\x00\x02\x03\x00\x00\x6D\x03\x00\x00\x03\x11\x00\x00\x00\x0F\x00\x00\x39\x0D\x00\x00\x03\x11\x00\x00\x00\x0F\x00\x00\x39\x0D\x00\x00\x03\x11\x00\x00\x04\x01\x00\x00\x00\x0F\x00\x00\x39\x0D\x00\x00\x03\x11\x00\x00\x0A\x01\x00\x00\x03\x11\x00\x00\x0A\x01\x00\x00\x03\x11\x00\x00\x0A\x01\x00\x00\x07\x11\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x00\x39\x0D\x00\x00\x03\x11\x00\x00\x03\x11\x00\x00\x0A\x01\x00\x00\x07\x11\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x00\x39\x0D\x00\x00\x03\x11\x00\x00\x72\x03\x00\x00\x0A\x01\x00\x00\x07\x11\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x00\x39\x0D\x00\x00\x00\x0F\x00\x00\x39\x0D\x00\x00\x03\x11\x00\x00\x02\x0F\x00\x00\x39\x0D\x00\x00\x03\x11\x00\x00\x08\x11\x00\x00\x02\x0F\x00\x00\x39\x0D\x00\x00\x03\x11\x00\x00\x6E\x03\x00\x00\x0A\x01\x00\x00\x07\x11\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x39\x0D\x00\x00\x03\x11\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x39\x0D\x00\x00\x03\x11\x00\x00\x0A\x01\x00\x00\x1A\x01\x00\x00\x08\x11\x00\x00\x02\x0F\x00\x00\x02\x0D\x00\x00\x08\x01\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x0A\x01\x00\x00\x03\x03\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x03\x11\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x03\x0D\x00\x00\x03\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x03\x11\x00\x00\x00\x0F\x00\x00\x03\x0D\x00\x00\x73\x03\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x03\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x03\x11\x00\x00\x00\x0F\x00\x00\x03\x0D\x00\x00\x03\x11\x00\x00\x03\x11\x00\x00\x1A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x68\x03\x00\x00\x02\x09\x00\x00\x68\x05\x00\x00\x00\x01\x00\x00\x6C\x03\x00\x00\x03\x09\x00\x00\x04\x09\x00\x00\x05\x09\x00\x00\x17\x01\x00\x00\x01\x09\x00\x00\x00\x09\x00\x00\x00\x01\x00\x00\x10\x01',
|
|
7
|
+
_globals = (b'\x00\x00\x2F\x23CancelIoEx',0,b'\x00\x00\x2C\x23CloseHandle',0,b'\x00\x00\x52\x23CreateEventA',0,b'\x00\x00\x58\x23CreateFileW',0,b'\x00\x00\x61\x23CreateIoCompletionPort',0,b'\x00\x00\x12\x23DeviceIoControl',0,b'\x00\x00\x33\x23GetQueuedCompletionStatusEx',0,b'\x00\x00\x3F\x23PostQueuedCompletionStatus',0,b'\x00\x00\x1C\x23ReadFile',0,b'\x00\x00\x0B\x23ResetEvent',0,b'\x00\x00\x45\x23RtlNtStatusToDosError',0,b'\x00\x00\x3B\x23SetConsoleCtrlHandler',0,b'\x00\x00\x0B\x23SetEvent',0,b'\x00\x00\x0E\x23SetFileCompletionNotificationModes',0,b'\x00\x00\x2A\x23WSAGetLastError',0,b'\x00\x00\x00\x23WSAIoctl',0,b'\x00\x00\x48\x23WaitForMultipleObjects',0,b'\x00\x00\x4E\x23WaitForSingleObject',0,b'\x00\x00\x23\x23WriteFile',0),
|
|
8
|
+
_struct_unions = ((b'\x00\x00\x00\x71\x00\x00\x00\x03$1',b'\x00\x00\x70\x11DUMMYSTRUCTNAME',b'\x00\x00\x03\x11Pointer'),(b'\x00\x00\x00\x70\x00\x00\x00\x02$2',b'\x00\x00\x02\x11Offset',b'\x00\x00\x02\x11OffsetHigh'),(b'\x00\x00\x00\x68\x00\x00\x00\x02_AFD_POLL_HANDLE_INFO',b'\x00\x00\x03\x11Handle',b'\x00\x00\x02\x11Events',b'\x00\x00\x46\x11Status'),(b'\x00\x00\x00\x6C\x00\x00\x00\x02_AFD_POLL_INFO',b'\x00\x00\x6F\x11Timeout',b'\x00\x00\x02\x11NumberOfHandles',b'\x00\x00\x02\x11Exclusive',b'\x00\x00\x69\x11Handles'),(b'\x00\x00\x00\x6D\x00\x00\x00\x02_OVERLAPPED',b'\x00\x00\x01\x11Internal',b'\x00\x00\x01\x11InternalHigh',b'\x00\x00\x71\x11DUMMYUNIONNAME',b'\x00\x00\x03\x11hEvent'),(b'\x00\x00\x00\x6E\x00\x00\x00\x02_OVERLAPPED_ENTRY',b'\x00\x00\x01\x11lpCompletionKey',b'\x00\x00\x08\x11lpOverlapped',b'\x00\x00\x01\x11Internal',b'\x00\x00\x02\x11dwNumberOfBytesTransferred')),
|
|
9
|
+
_typenames = (b'\x00\x00\x00\x68AFD_POLL_HANDLE_INFO',b'\x00\x00\x00\x6CAFD_POLL_INFO',b'\x00\x00\x00\x39BOOL',b'\x00\x00\x00\x10BOOLEAN',b'\x00\x00\x00\x10BYTE',b'\x00\x00\x00\x02DWORD',b'\x00\x00\x00\x03HANDLE',b'\x00\x00\x00\x6FLARGE_INTEGER',b'\x00\x00\x00\x03LPCSTR',b'\x00\x00\x00\x25LPCVOID',b'\x00\x00\x00\x59LPCWSTR',b'\x00\x00\x00\x07LPDWORD',b'\x00\x00\x00\x08LPOVERLAPPED',b'\x00\x00\x00\x35LPOVERLAPPED_ENTRY',b'\x00\x00\x00\x03LPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x03LPVOID',b'\x00\x00\x00\x08LPWSAOVERLAPPED',b'\x00\x00\x00\x46NTSTATUS',b'\x00\x00\x00\x6DOVERLAPPED',b'\x00\x00\x00\x6EOVERLAPPED_ENTRY',b'\x00\x00\x00\x67PAFD_POLL_HANDLE_INFO',b'\x00\x00\x00\x6BPAFD_POLL_INFO',b'\x00\x00\x00\x07PULONG',b'\x00\x00\x00\x03PVOID',b'\x00\x00\x00\x01SOCKET',b'\x00\x00\x00\x10UCHAR',b'\x00\x00\x00\x01UINT_PTR',b'\x00\x00\x00\x02ULONG',b'\x00\x00\x00\x01ULONG_PTR',b'\x00\x00\x00\x6DWSAOVERLAPPED',b'\x00\x00\x00\x02u_long'),
|
|
10
|
+
)
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import types
|
|
5
|
+
from collections import UserDict
|
|
6
|
+
from typing import TYPE_CHECKING, TypeVar
|
|
7
|
+
|
|
8
|
+
from .._abc import Instrument
|
|
9
|
+
|
|
10
|
+
# Used to log exceptions in instruments
|
|
11
|
+
INSTRUMENT_LOGGER = logging.getLogger("trio.abc.Instrument")
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from collections.abc import Sequence
|
|
15
|
+
|
|
16
|
+
T = TypeVar("T")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# Decorator to mark methods public. This does nothing by itself, but
|
|
20
|
+
# trio/_tools/gen_exports.py looks for it.
|
|
21
|
+
def _public(fn: T) -> T:
|
|
22
|
+
return fn
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class Instruments(UserDict[str, dict[Instrument, None]]):
|
|
26
|
+
"""A collection of `trio.abc.Instrument` organized by hook.
|
|
27
|
+
|
|
28
|
+
Instrumentation calls are rather expensive, and we don't want a
|
|
29
|
+
rarely-used instrument (like before_run()) to slow down hot
|
|
30
|
+
operations (like before_task_step()). Thus, we cache the set of
|
|
31
|
+
instruments to be called for each hook, and skip the instrumentation
|
|
32
|
+
call if there's nothing currently installed for that hook.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
__slots__ = ()
|
|
36
|
+
|
|
37
|
+
def __init__(self, incoming: Sequence[Instrument]) -> None:
|
|
38
|
+
super().__init__({"_all": {}})
|
|
39
|
+
for instrument in incoming:
|
|
40
|
+
self.add_instrument(instrument)
|
|
41
|
+
|
|
42
|
+
@_public
|
|
43
|
+
def add_instrument(self, instrument: Instrument) -> None:
|
|
44
|
+
"""Start instrumenting the current run loop with the given instrument.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
instrument (trio.abc.Instrument): The instrument to activate.
|
|
48
|
+
|
|
49
|
+
If ``instrument`` is already active, does nothing.
|
|
50
|
+
|
|
51
|
+
"""
|
|
52
|
+
if instrument in self.data["_all"]:
|
|
53
|
+
return
|
|
54
|
+
self.data["_all"][instrument] = None
|
|
55
|
+
try:
|
|
56
|
+
for name in dir(instrument):
|
|
57
|
+
if name.startswith("_"):
|
|
58
|
+
continue
|
|
59
|
+
try:
|
|
60
|
+
prototype = getattr(Instrument, name)
|
|
61
|
+
except AttributeError:
|
|
62
|
+
continue
|
|
63
|
+
impl = getattr(instrument, name)
|
|
64
|
+
if isinstance(impl, types.MethodType) and impl.__func__ is prototype:
|
|
65
|
+
# Inherited unchanged from _abc.Instrument
|
|
66
|
+
continue
|
|
67
|
+
self.data.setdefault(name, {})[instrument] = None
|
|
68
|
+
except:
|
|
69
|
+
self.remove_instrument(instrument)
|
|
70
|
+
raise
|
|
71
|
+
|
|
72
|
+
@_public
|
|
73
|
+
def remove_instrument(self, instrument: Instrument) -> None:
|
|
74
|
+
"""Stop instrumenting the current run loop with the given instrument.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
instrument (trio.abc.Instrument): The instrument to de-activate.
|
|
78
|
+
|
|
79
|
+
Raises:
|
|
80
|
+
KeyError: if the instrument is not currently active. This could
|
|
81
|
+
occur either because you never added it, or because you added it
|
|
82
|
+
and then it raised an unhandled exception and was automatically
|
|
83
|
+
deactivated.
|
|
84
|
+
|
|
85
|
+
"""
|
|
86
|
+
# If instrument isn't present, the KeyError propagates out
|
|
87
|
+
self.data["_all"].pop(instrument)
|
|
88
|
+
for hookname, instruments in list(self.data.items()):
|
|
89
|
+
if instrument in instruments:
|
|
90
|
+
del instruments[instrument]
|
|
91
|
+
if not instruments:
|
|
92
|
+
del self.data[hookname]
|
|
93
|
+
|
|
94
|
+
def call(
|
|
95
|
+
self,
|
|
96
|
+
hookname: str,
|
|
97
|
+
*args: object,
|
|
98
|
+
) -> None:
|
|
99
|
+
"""Call hookname(*args) on each applicable instrument.
|
|
100
|
+
|
|
101
|
+
You must first check whether there are any instruments installed for
|
|
102
|
+
that hook, e.g.::
|
|
103
|
+
|
|
104
|
+
if "before_task_step" in instruments:
|
|
105
|
+
instruments.call("before_task_step", task)
|
|
106
|
+
"""
|
|
107
|
+
for instrument in list(self.data[hookname]):
|
|
108
|
+
try:
|
|
109
|
+
getattr(instrument, hookname)(*args)
|
|
110
|
+
except BaseException:
|
|
111
|
+
self.remove_instrument(instrument)
|
|
112
|
+
INSTRUMENT_LOGGER.exception(
|
|
113
|
+
"Exception raised when calling %r on instrument %r. "
|
|
114
|
+
"Instrument has been disabled.",
|
|
115
|
+
hookname,
|
|
116
|
+
instrument,
|
|
117
|
+
)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import copy
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
import outcome
|
|
7
|
+
|
|
8
|
+
from .. import _core
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from ._io_epoll import EpollWaiters
|
|
12
|
+
from ._io_windows import AFDWaiters
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# Utility function shared between _io_epoll and _io_windows
|
|
16
|
+
def wake_all(waiters: EpollWaiters | AFDWaiters, exc: BaseException) -> None:
|
|
17
|
+
try:
|
|
18
|
+
current_task = _core.current_task()
|
|
19
|
+
except RuntimeError:
|
|
20
|
+
current_task = None
|
|
21
|
+
raise_at_end = False
|
|
22
|
+
for attr_name in ["read_task", "write_task"]:
|
|
23
|
+
task = getattr(waiters, attr_name)
|
|
24
|
+
if task is not None:
|
|
25
|
+
if task is current_task:
|
|
26
|
+
raise_at_end = True
|
|
27
|
+
else:
|
|
28
|
+
_core.reschedule(task, outcome.Error(copy.copy(exc)))
|
|
29
|
+
setattr(waiters, attr_name, None)
|
|
30
|
+
if raise_at_end:
|
|
31
|
+
raise exc
|