You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Cooperative concurrency via `async def` coroutines and `await` / `yield`. No preemption, a coroutine runs until it yields, sleeps, awaits, or returns. Single-threaded scheduler; concurrency by interleaving, not parallelism.
6
+
Cooperative concurrency via `async def` coroutines and `await` / `yield`. No preemption: a coroutine runs until it yields, sleeps, awaits, or returns. Single-threaded scheduler; concurrency by interleaving, not parallelism.
7
7
8
-
No `asyncio` module. Primitives,`run`, `sleep`, `frame`, `gather`, `with_timeout`, `cancel`, `receive`, are top-level builtins.
8
+
No `asyncio` module. Primitives:`run`, `sleep`, `frame`, `gather`, `with_timeout`, `cancel`, `receive` — are top-level builtins.
9
9
10
10
```python
11
-
import asyncio # ModuleNotFoundError: there is no asyncio
11
+
import asyncio # ModuleNotFoundError: It was decided not to use asyncio and introduce the asynchrony within the virtual machine.
12
12
```
13
13
14
14
```python
@@ -28,7 +28,7 @@ ok
28
28
29
29
A `def` body executes immediately. An `async def` body returns a coroutine value that does nothing until driven with `run` / `gather`. Only coroutines are cancellable (`cancel`) and can suspend on real time (`sleep`).
30
30
31
-
A plain `def` inside a coroutine (or at module top-level) can still call yielding builtins (`sleep`, `receive`, deferred host calls), the scheduler snapshots the helper's frame, suspends the call chain, re-enters the helper on resume so its return value lands at the original call site. The module body runs as an implicit coroutine, so top-level statements suspend the same way. From the caller, a sync helper that internally sleeps is indistinguishable from one that doesn't.
31
+
A plain `def` inside a coroutine (or at module top-level) can still call yielding builtins (`sleep`, `receive`, deferred host calls): the scheduler snapshots the helper's frame, suspends the call chain, and re-enters the helper on resume so its return value lands at the original call site. The module body runs as an implicit coroutine, so top-level statements suspend the same way. From the caller, a sync helper that internally sleeps is indistinguishable from one that doesn't.
32
32
33
33
```python
34
34
defroutine():
@@ -37,9 +37,9 @@ def routine():
37
37
asyncdefcoro():
38
38
return1
39
39
40
-
print(routine()) # 1
41
-
print(coro()) # <coroutine> (does not run yet)
42
-
print(run(coro())) # 1 (run drives it to completion)
40
+
print(routine()) # 1
41
+
print(coro()) # <coroutine> (does not run yet)
42
+
print(run(coro())) # 1 (run drives it to completion)
43
43
```
44
44
45
45
## Driving coroutines
@@ -61,7 +61,7 @@ print(run(square(5)))
61
61
62
62
## Sleeping
63
63
64
-
`sleep(seconds)` suspends until `seconds` of wall time pass. Without a host time hook, a virtual clock advances logically, coroutines interleave deterministically with no real wait (useful for tests).
64
+
`sleep(seconds)` suspends until `seconds` of wall time pass. Without a host time hook, a virtual clock advances logically; coroutines interleave deterministically with no real wait (useful for tests).
The total wall time is `max(delays)`, not the sum,`b` and `c` overlap with `a`'s sleep.
98
+
The total wall time is `max(delays)`, not the sum —`b` and `c` overlap with `a`'s sleep.
99
99
100
100
### Errors
101
101
@@ -154,11 +154,11 @@ except TimeoutError:
154
154
timed out
155
155
```
156
156
157
-
`with_timeout` evaluates the coroutine eagerly, it's a call, not an awaitable.
157
+
`with_timeout` evaluates the coroutine eagerly — it's a call, not an awaitable.
158
158
159
159
## cancel
160
160
161
-
`cancel(coro)` flags a registered coroutine for cancellation. On its next scheduler tick it transitions to `Cancelled` and stops. The body does not observe a `CancelledError`, cancellation is cooperative and silent.
161
+
`cancel(coro)` flags a registered coroutine for cancellation. On its next scheduler tick it transitions to `Cancelled` and stops. The body does not observe a `CancelledError`; cancellation is cooperative and silent.
162
162
163
163
A coroutine in a tight synchronous loop without `await`/`sleep` cannot be cancelled until it yields:
164
164
@@ -184,8 +184,8 @@ Both live in the built-in exception namespace and match `except` clauses normall
184
184
185
185
***No preemption**, `while True: pass` inside a coroutine blocks the scheduler.
186
186
***Silent cancellation**, `cancel(coro)` stops the coro; the body doesn't see `CancelledError`. Use `with_timeout` for deadline-as-exception.
187
-
***Cooperative host loop**, scheduler suspends to the host when it can't progress synchronously (pending timer/frame/event); embedder resumes via `run_start` / `run_resume` / `run_push_event`. The legacy non-suspending `run` cannot resume, code using `sleep(n>0)`, `frame()`, or an empty `receive()` must run via the driver loop; statements after a top-level `run()` don't execute after a yield.
188
-
***`async for`** works against any `for`-iterable plus coroutines and async generators (`async def` with `yield`). Each iteration resumes to the next yield. No `__aiter__` / `__anext__` dispatch on user classes, write an `async def` generator. Behaviour over lists/tuples/dicts is identical to regular `for`.
187
+
***Cooperative host loop**, scheduler suspends to the host when it can't progress synchronously (pending timer/frame/event); embedder resumes via `run_start` / `run_resume` / `run_push_event`. The legacy non-suspending `run` cannot resume. Code using `sleep(n>0)`, `frame()`, or an empty `receive()` must run via the driver loop; statements after a top-level `run()` don't execute after a yield.
188
+
***`async for`** works against any `for`-iterable plus coroutines and async generators (`async def` with `yield`). Each iteration resumes to the next yield. No `__aiter__` / `__anext__` dispatch on user classes; write an `async def` generator instead. Behaviour over lists/tuples/dicts is identical to regular `for`.
189
189
***`async with`** reuses sync dispatch (`__enter__` / `__exit__`); `__aenter__` / `__aexit__` aren't consulted. For async setup/teardown, use `try` / `finally` with explicit `await`.
190
190
***No async comprehensions**, `[x async for x in it]` unsupported.
191
191
***No `gen.send` / `throw` / `close`**, generators and coroutines are one-way producers. For bidirectional flow, use `run` / `gather` and pass messages via args.
0 commit comments