rsloop 0.1.0__tar.gz → 0.1.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.
- {rsloop-0.1.0 → rsloop-0.1.2}/.github/workflows/wheels.yml +7 -2
- {rsloop-0.1.0 → rsloop-0.1.2}/Cargo.lock +1 -1
- {rsloop-0.1.0 → rsloop-0.1.2}/Cargo.toml +1 -1
- {rsloop-0.1.0 → rsloop-0.1.2}/LICENSE +1 -1
- {rsloop-0.1.0 → rsloop-0.1.2}/PKG-INFO +36 -22
- {rsloop-0.1.0 → rsloop-0.1.2}/README.md +35 -21
- {rsloop-0.1.0 → rsloop-0.1.2}/examples/03_streams.py +2 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/examples/04_unix_and_accepted_socket.py +2 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/examples/05_pipes_signals_subprocesses.py +2 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/pyproject.toml +1 -1
- {rsloop-0.1.0 → rsloop-0.1.2}/python/rsloop/__init__.py +25 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/scripts/build-wheels.sh +32 -10
- {rsloop-0.1.0 → rsloop-0.1.2}/src/callbacks.rs +0 -17
- {rsloop-0.1.0 → rsloop-0.1.2}/src/python_api.rs +2 -15
- rsloop-0.1.2/tests/test_run.py +25 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/uv.lock +1 -1
- {rsloop-0.1.0 → rsloop-0.1.2}/.gitignore +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/benchmarks/README.md +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/benchmarks/compare_event_loops.py +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/build.rs +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/demo/README.md +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/demo/fastapi_service.py +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/examples/01_basics.py +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/examples/02_fd_and_sockets.py +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/rsloop.png +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/src/async_event.rs +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/src/blocking.rs +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/src/context.rs +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/src/errors.rs +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/src/fast_streams.rs +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/src/fd_ops.rs +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/src/lib.rs +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/src/loop_core.rs +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/src/process_transport.rs +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/src/profiler.rs +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/src/python_names.rs +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/src/runtime.rs +0 -0
- {rsloop-0.1.0 → rsloop-0.1.2}/src/stream_transport.rs +0 -0
|
@@ -19,8 +19,13 @@ jobs:
|
|
|
19
19
|
include:
|
|
20
20
|
- os_name: linux
|
|
21
21
|
runner: ubuntu-latest
|
|
22
|
-
|
|
22
|
+
rust_target: x86_64-unknown-linux-gnu
|
|
23
|
+
- os_name: macos-intel
|
|
23
24
|
runner: macos-15-intel
|
|
25
|
+
rust_target: x86_64-apple-darwin
|
|
26
|
+
- os_name: macos-arm64
|
|
27
|
+
runner: macos-15
|
|
28
|
+
rust_target: aarch64-apple-darwin
|
|
24
29
|
|
|
25
30
|
steps:
|
|
26
31
|
- name: Check out repository
|
|
@@ -45,7 +50,7 @@ jobs:
|
|
|
45
50
|
uses: Swatinem/rust-cache@v2
|
|
46
51
|
|
|
47
52
|
- name: Build wheels
|
|
48
|
-
run: scripts/build-wheels.sh --out dist
|
|
53
|
+
run: scripts/build-wheels.sh --out dist --target "${{ matrix.rust_target }}"
|
|
49
54
|
|
|
50
55
|
- name: Upload wheel artifacts
|
|
51
56
|
uses: actions/upload-artifact@v4
|
|
@@ -186,7 +186,7 @@
|
|
|
186
186
|
same "printed page" as the copyright notice for easier
|
|
187
187
|
identification within third-party archives.
|
|
188
188
|
|
|
189
|
-
Copyright
|
|
189
|
+
Copyright 2026 Yehor Smoliakov
|
|
190
190
|
|
|
191
191
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
192
|
you may not use this file except in compliance with the License.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rsloop
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Classifier: Development Status :: 3 - Alpha
|
|
5
5
|
Classifier: Intended Audience :: Developers
|
|
6
6
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
@@ -32,16 +32,35 @@ Project-URL: Repository, https://github.com/RustedBytes/rsloop
|
|
|
32
32
|
|
|
33
33
|
<img src="./rsloop.png" alt="rsloop logo" align="center">
|
|
34
34
|
|
|
35
|
-
#
|
|
35
|
+
# An event loop for asyncio written in Rust
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
[](https://pypi.org/project/rsloop/)
|
|
38
|
+
[](https://pepy.tech/projects/rsloop)
|
|
39
|
+
|
|
40
|
+
`rsloop` is a PyO3-based `asyncio` event loop. Each `rsloop.Loop` owns a
|
|
41
|
+
dedicated Rust runtime thread that handles loop coordination and I/O-related
|
|
42
|
+
runtime work, while Python callbacks, tasks, and coroutines are executed on
|
|
43
|
+
the thread that calls `run_forever()` / `run_until_complete()` (typically the
|
|
44
|
+
main thread). The package exposes a Python module at
|
|
42
45
|
`rsloop._loop` plus a small Python wrapper in `python/rsloop/__init__.py`.
|
|
43
46
|
|
|
44
|
-
The project metadata currently targets Python `>=3.8`.
|
|
47
|
+
The project metadata currently targets Python `>=3.8`. The current
|
|
48
|
+
implementation is Unix-focused and intended for Linux and macOS; Windows is
|
|
49
|
+
not supported by this codebase.
|
|
50
|
+
|
|
51
|
+
## Install
|
|
52
|
+
|
|
53
|
+
Install the published package from PyPI:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install rsloop
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
With `uv`:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
uv add rsloop
|
|
63
|
+
```
|
|
45
64
|
|
|
46
65
|
## Current Surface Area
|
|
47
66
|
|
|
@@ -93,7 +112,8 @@ Today’s codebase provides:
|
|
|
93
112
|
- `create_unix_connection`
|
|
94
113
|
- `connect_accepted_socket`
|
|
95
114
|
- returned `Server` and `StreamTransport` objects
|
|
96
|
-
- `transport.close()` / `transport.abort()`
|
|
115
|
+
- `transport.close()` / `transport.abort()` are implemented for socket
|
|
116
|
+
transports
|
|
97
117
|
- pipe transports:
|
|
98
118
|
- `connect_read_pipe`
|
|
99
119
|
- `connect_write_pipe`
|
|
@@ -145,6 +165,12 @@ level transport implementation lives in `src/stream_transport.rs`.
|
|
|
145
165
|
- `get_write_buffer_size()` returns `0`
|
|
146
166
|
- `get_write_buffer_limits()` returns `(0, 0)`
|
|
147
167
|
- `set_write_buffer_limits()` is a no-op
|
|
168
|
+
- several asyncio compatibility parameters are currently accepted only for API
|
|
169
|
+
shape and are not implemented:
|
|
170
|
+
- `create_connection(..., server_hostname=..., happy_eyeballs_delay=..., interleave=..., all_errors=...)`
|
|
171
|
+
- TLS timeout parameters such as `ssl_handshake_timeout` /
|
|
172
|
+
`ssl_shutdown_timeout`
|
|
173
|
+
- `shutdown_default_executor(timeout=...)`
|
|
148
174
|
- subprocess support is intentionally incomplete:
|
|
149
175
|
- `preexec_fn` is unsupported
|
|
150
176
|
- text mode is rejected for higher-level
|
|
@@ -180,19 +206,6 @@ Build release wheels for CPython 3.8 through 3.14, plus the free-threaded
|
|
|
180
206
|
scripts/build-wheels.sh
|
|
181
207
|
```
|
|
182
208
|
|
|
183
|
-
## Publishing
|
|
184
|
-
|
|
185
|
-
PyPI releases are published from Git tags that start with `v`, for example
|
|
186
|
-
`v0.1.0`. The GitHub Actions workflow builds wheels by calling
|
|
187
|
-
`scripts/build-wheels.sh`, builds an `sdist`, and then publishes the combined
|
|
188
|
-
artifacts to PyPI with GitHub trusted publishing.
|
|
189
|
-
|
|
190
|
-
Before the first release, configure the `rsloop` project on PyPI as a trusted
|
|
191
|
-
publisher for this repository/workflow.
|
|
192
|
-
|
|
193
|
-
Use a release build for benchmarks and runtime comparisons. A debug extension
|
|
194
|
-
will make the Rust loop look much slower than it really is.
|
|
195
|
-
|
|
196
209
|
## Profiling
|
|
197
210
|
|
|
198
211
|
Profiling support is behind the Cargo feature `profiler` and is disabled by
|
|
@@ -228,6 +241,7 @@ This writes an SVG flamegraph that you can open directly in a browser. Run the
|
|
|
228
241
|
profile against a release build or the stack samples will be dominated by debug
|
|
229
242
|
overhead. If the extension was built without `--features profiler`,
|
|
230
243
|
`start_profiler()` and `profile()` will raise a runtime error.
|
|
244
|
+
Only `format="flamegraph"` is currently implemented.
|
|
231
245
|
|
|
232
246
|
## Usage
|
|
233
247
|
|
|
@@ -1,15 +1,34 @@
|
|
|
1
1
|
<img src="./rsloop.png" alt="rsloop logo" align="center">
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# An event loop for asyncio written in Rust
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
[](https://pypi.org/project/rsloop/)
|
|
6
|
+
[](https://pepy.tech/projects/rsloop)
|
|
7
|
+
|
|
8
|
+
`rsloop` is a PyO3-based `asyncio` event loop. Each `rsloop.Loop` owns a
|
|
9
|
+
dedicated Rust runtime thread that handles loop coordination and I/O-related
|
|
10
|
+
runtime work, while Python callbacks, tasks, and coroutines are executed on
|
|
11
|
+
the thread that calls `run_forever()` / `run_until_complete()` (typically the
|
|
12
|
+
main thread). The package exposes a Python module at
|
|
10
13
|
`rsloop._loop` plus a small Python wrapper in `python/rsloop/__init__.py`.
|
|
11
14
|
|
|
12
|
-
The project metadata currently targets Python `>=3.8`.
|
|
15
|
+
The project metadata currently targets Python `>=3.8`. The current
|
|
16
|
+
implementation is Unix-focused and intended for Linux and macOS; Windows is
|
|
17
|
+
not supported by this codebase.
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
Install the published package from PyPI:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install rsloop
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
With `uv`:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
uv add rsloop
|
|
31
|
+
```
|
|
13
32
|
|
|
14
33
|
## Current Surface Area
|
|
15
34
|
|
|
@@ -61,7 +80,8 @@ Today’s codebase provides:
|
|
|
61
80
|
- `create_unix_connection`
|
|
62
81
|
- `connect_accepted_socket`
|
|
63
82
|
- returned `Server` and `StreamTransport` objects
|
|
64
|
-
- `transport.close()` / `transport.abort()`
|
|
83
|
+
- `transport.close()` / `transport.abort()` are implemented for socket
|
|
84
|
+
transports
|
|
65
85
|
- pipe transports:
|
|
66
86
|
- `connect_read_pipe`
|
|
67
87
|
- `connect_write_pipe`
|
|
@@ -113,6 +133,12 @@ level transport implementation lives in `src/stream_transport.rs`.
|
|
|
113
133
|
- `get_write_buffer_size()` returns `0`
|
|
114
134
|
- `get_write_buffer_limits()` returns `(0, 0)`
|
|
115
135
|
- `set_write_buffer_limits()` is a no-op
|
|
136
|
+
- several asyncio compatibility parameters are currently accepted only for API
|
|
137
|
+
shape and are not implemented:
|
|
138
|
+
- `create_connection(..., server_hostname=..., happy_eyeballs_delay=..., interleave=..., all_errors=...)`
|
|
139
|
+
- TLS timeout parameters such as `ssl_handshake_timeout` /
|
|
140
|
+
`ssl_shutdown_timeout`
|
|
141
|
+
- `shutdown_default_executor(timeout=...)`
|
|
116
142
|
- subprocess support is intentionally incomplete:
|
|
117
143
|
- `preexec_fn` is unsupported
|
|
118
144
|
- text mode is rejected for higher-level
|
|
@@ -148,19 +174,6 @@ Build release wheels for CPython 3.8 through 3.14, plus the free-threaded
|
|
|
148
174
|
scripts/build-wheels.sh
|
|
149
175
|
```
|
|
150
176
|
|
|
151
|
-
## Publishing
|
|
152
|
-
|
|
153
|
-
PyPI releases are published from Git tags that start with `v`, for example
|
|
154
|
-
`v0.1.0`. The GitHub Actions workflow builds wheels by calling
|
|
155
|
-
`scripts/build-wheels.sh`, builds an `sdist`, and then publishes the combined
|
|
156
|
-
artifacts to PyPI with GitHub trusted publishing.
|
|
157
|
-
|
|
158
|
-
Before the first release, configure the `rsloop` project on PyPI as a trusted
|
|
159
|
-
publisher for this repository/workflow.
|
|
160
|
-
|
|
161
|
-
Use a release build for benchmarks and runtime comparisons. A debug extension
|
|
162
|
-
will make the Rust loop look much slower than it really is.
|
|
163
|
-
|
|
164
177
|
## Profiling
|
|
165
178
|
|
|
166
179
|
Profiling support is behind the Cargo feature `profiler` and is disabled by
|
|
@@ -196,6 +209,7 @@ This writes an SVG flamegraph that you can open directly in a browser. Run the
|
|
|
196
209
|
profile against a release build or the stack samples will be dominated by debug
|
|
197
210
|
overhead. If the extension was built without `--features profiler`,
|
|
198
211
|
`start_profiler()` and `profile()` will raise a runtime error.
|
|
212
|
+
Only `format="flamegraph"` is currently implemented.
|
|
199
213
|
|
|
200
214
|
## Usage
|
|
201
215
|
|
|
@@ -25,6 +25,31 @@ __all__: tuple[str, ...] = (
|
|
|
25
25
|
"stop_profiler",
|
|
26
26
|
)
|
|
27
27
|
_T = __typing.TypeVar("_T")
|
|
28
|
+
__ORIG_SET_EVENT_LOOP = __asyncio.set_event_loop
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def __set_event_loop(loop: Loop | None) -> None:
|
|
32
|
+
try:
|
|
33
|
+
__ORIG_SET_EVENT_LOOP(loop)
|
|
34
|
+
return
|
|
35
|
+
except (AssertionError, TypeError):
|
|
36
|
+
if loop is None or not isinstance(loop, Loop):
|
|
37
|
+
raise
|
|
38
|
+
|
|
39
|
+
# Python 3.8 rejects non-stdlib loop objects in set_event_loop() with a
|
|
40
|
+
# hard isinstance() assertion. Mirror the stdlib policy bookkeeping so
|
|
41
|
+
# get_event_loop() still returns the current rsloop instance.
|
|
42
|
+
policy = __asyncio.get_event_loop_policy()
|
|
43
|
+
local = getattr(policy, "_local", None)
|
|
44
|
+
if local is None:
|
|
45
|
+
raise
|
|
46
|
+
local._set_called = True
|
|
47
|
+
local._loop = loop
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
if __asyncio.set_event_loop is __ORIG_SET_EVENT_LOOP:
|
|
51
|
+
__asyncio.set_event_loop = __set_event_loop
|
|
52
|
+
__asyncio.events.set_event_loop = __set_event_loop
|
|
28
53
|
|
|
29
54
|
|
|
30
55
|
def new_event_loop() -> Loop:
|
|
@@ -10,10 +10,11 @@ usage() {
|
|
|
10
10
|
Build release wheels for rsloop with uv-managed Python interpreters.
|
|
11
11
|
|
|
12
12
|
Usage:
|
|
13
|
-
scripts/build-wheels.sh [--out DIR] [--skip-python-install] [-- maturin args...]
|
|
13
|
+
scripts/build-wheels.sh [--out DIR] [--target TRIPLE] [--skip-python-install] [-- maturin args...]
|
|
14
14
|
|
|
15
15
|
Options:
|
|
16
16
|
-o, --out DIR Output directory for built wheels (default: dist/wheels)
|
|
17
|
+
-t, --target TRIPLE Rust compilation target to pass to maturin
|
|
17
18
|
--skip-python-install
|
|
18
19
|
Reuse installed interpreters instead of running `uv python install`
|
|
19
20
|
-h, --help Show this help
|
|
@@ -21,10 +22,12 @@ Options:
|
|
|
21
22
|
Environment:
|
|
22
23
|
RSLOOP_PYTHON_VERSIONS Space-separated version list to override the defaults
|
|
23
24
|
(default: 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.14t)
|
|
25
|
+
RSLOOP_RUST_TARGET Rust compilation target to pass to maturin
|
|
24
26
|
|
|
25
27
|
Examples:
|
|
26
28
|
scripts/build-wheels.sh
|
|
27
29
|
scripts/build-wheels.sh --out wheelhouse
|
|
30
|
+
scripts/build-wheels.sh --target aarch64-apple-darwin
|
|
28
31
|
RSLOOP_PYTHON_VERSIONS="3.12 3.13 3.14t" scripts/build-wheels.sh -- --features profiler
|
|
29
32
|
EOF
|
|
30
33
|
}
|
|
@@ -40,6 +43,7 @@ resolve_path() {
|
|
|
40
43
|
|
|
41
44
|
OUTPUT_DIR="$DEFAULT_OUTPUT_DIR"
|
|
42
45
|
INSTALL_PYTHONS=1
|
|
46
|
+
RUST_TARGET="${RSLOOP_RUST_TARGET:-}"
|
|
43
47
|
MATURIN_ARGS=()
|
|
44
48
|
|
|
45
49
|
while (($#)); do
|
|
@@ -52,6 +56,14 @@ while (($#)); do
|
|
|
52
56
|
OUTPUT_DIR="$2"
|
|
53
57
|
shift 2
|
|
54
58
|
;;
|
|
59
|
+
-t|--target)
|
|
60
|
+
if (($# < 2)); then
|
|
61
|
+
echo "missing value for $1" >&2
|
|
62
|
+
exit 1
|
|
63
|
+
fi
|
|
64
|
+
RUST_TARGET="$2"
|
|
65
|
+
shift 2
|
|
66
|
+
;;
|
|
55
67
|
--skip-python-install)
|
|
56
68
|
INSTALL_PYTHONS=0
|
|
57
69
|
shift
|
|
@@ -92,15 +104,25 @@ fi
|
|
|
92
104
|
for version in "${PYTHON_VERSIONS[@]}"; do
|
|
93
105
|
interpreter="$(uv python find "$version")"
|
|
94
106
|
echo "Building release wheel for Python ${version} (${interpreter})"
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
--
|
|
98
|
-
--
|
|
99
|
-
maturin
|
|
100
|
-
|
|
101
|
-
--
|
|
102
|
-
--
|
|
103
|
-
"$
|
|
107
|
+
maturin_cmd=(
|
|
108
|
+
uv run
|
|
109
|
+
--no-project
|
|
110
|
+
--python "$interpreter"
|
|
111
|
+
--with maturin
|
|
112
|
+
maturin build
|
|
113
|
+
--release
|
|
114
|
+
--interpreter "$interpreter"
|
|
115
|
+
--out "$OUTPUT_DIR"
|
|
116
|
+
)
|
|
117
|
+
if [[ -n "$RUST_TARGET" ]]; then
|
|
118
|
+
maturin_cmd+=(
|
|
119
|
+
--target "$RUST_TARGET"
|
|
120
|
+
)
|
|
121
|
+
fi
|
|
122
|
+
if ((${#MATURIN_ARGS[@]})); then
|
|
123
|
+
maturin_cmd+=("${MATURIN_ARGS[@]}")
|
|
124
|
+
fi
|
|
125
|
+
"${maturin_cmd[@]}"
|
|
104
126
|
done
|
|
105
127
|
|
|
106
128
|
echo "Wheels written to $OUTPUT_DIR"
|
|
@@ -13,7 +13,6 @@ pub type CallbackId = u64;
|
|
|
13
13
|
|
|
14
14
|
enum CallbackArgs {
|
|
15
15
|
None,
|
|
16
|
-
One(Py<PyAny>),
|
|
17
16
|
Many(Py<PyTuple>),
|
|
18
17
|
}
|
|
19
18
|
|
|
@@ -50,12 +49,6 @@ impl ReadyCallback {
|
|
|
50
49
|
) -> Self {
|
|
51
50
|
let args = match args.bind(py).len() {
|
|
52
51
|
0 => CallbackArgs::None,
|
|
53
|
-
1 => CallbackArgs::One(
|
|
54
|
-
args.bind(py)
|
|
55
|
-
.get_item(0)
|
|
56
|
-
.expect("single callback arg missing")
|
|
57
|
-
.unbind(),
|
|
58
|
-
),
|
|
59
52
|
_ => CallbackArgs::Many(args),
|
|
60
53
|
};
|
|
61
54
|
|
|
@@ -127,13 +120,6 @@ impl ReadyCallback {
|
|
|
127
120
|
)
|
|
128
121
|
.map(Bound::unbind)
|
|
129
122
|
},
|
|
130
|
-
CallbackArgs::One(arg) => unsafe {
|
|
131
|
-
Bound::from_owned_ptr_or_err(
|
|
132
|
-
py,
|
|
133
|
-
ffi::PyObject_CallOneArg(self.callback.as_ptr(), arg.as_ptr()),
|
|
134
|
-
)
|
|
135
|
-
.map(Bound::unbind)
|
|
136
|
-
},
|
|
137
123
|
CallbackArgs::Many(args) => self.callback.call1(py, args.clone_ref(py)),
|
|
138
124
|
}
|
|
139
125
|
}
|
|
@@ -141,9 +127,6 @@ impl ReadyCallback {
|
|
|
141
127
|
pub fn clone_args_tuple(&self, py: Python<'_>) -> Py<PyTuple> {
|
|
142
128
|
match &self.args {
|
|
143
129
|
CallbackArgs::None => PyTuple::empty(py).unbind(),
|
|
144
|
-
CallbackArgs::One(arg) => PyTuple::new(py, [arg.clone_ref(py)])
|
|
145
|
-
.expect("failed to clone single callback arg")
|
|
146
|
-
.unbind(),
|
|
147
130
|
CallbackArgs::Many(args) => args.clone_ref(py),
|
|
148
131
|
}
|
|
149
132
|
}
|
|
@@ -8,7 +8,6 @@ use std::sync::OnceLock;
|
|
|
8
8
|
use std::time::Duration;
|
|
9
9
|
|
|
10
10
|
use pyo3::exceptions::{PyNotImplementedError, PyRuntimeError, PyTypeError, PyValueError};
|
|
11
|
-
use pyo3::ffi;
|
|
12
11
|
use pyo3::prelude::*;
|
|
13
12
|
use pyo3::types::{PyDict, PyModule, PySlice, PyTuple};
|
|
14
13
|
use pyo3_async_runtimes::TaskLocals;
|
|
@@ -123,13 +122,7 @@ fn create_asyncio_future_for_loop(py: Python<'_>, loop_obj: &Py<PyAny>) -> PyRes
|
|
|
123
122
|
}
|
|
124
123
|
|
|
125
124
|
fn create_asyncio_future_for_running_loop(py: Python<'_>) -> PyResult<Py<PyAny>> {
|
|
126
|
-
|
|
127
|
-
Bound::from_owned_ptr_or_err(
|
|
128
|
-
py,
|
|
129
|
-
ffi::compat::PyObject_CallNoArgs(asyncio_future_cls(py)?.as_ptr()),
|
|
130
|
-
)
|
|
131
|
-
.map(Bound::unbind)
|
|
132
|
-
}
|
|
125
|
+
asyncio_future_cls(py)?.call0(py)
|
|
133
126
|
}
|
|
134
127
|
|
|
135
128
|
fn create_asyncio_task_for_loop(
|
|
@@ -151,13 +144,7 @@ fn create_asyncio_task_for_loop(
|
|
|
151
144
|
}
|
|
152
145
|
|
|
153
146
|
fn create_asyncio_task_for_running_loop(py: Python<'_>, coro: Py<PyAny>) -> PyResult<Py<PyAny>> {
|
|
154
|
-
|
|
155
|
-
Bound::from_owned_ptr_or_err(
|
|
156
|
-
py,
|
|
157
|
-
ffi::PyObject_CallOneArg(asyncio_task_cls(py)?.as_ptr(), coro.as_ptr()),
|
|
158
|
-
)
|
|
159
|
-
.map(Bound::unbind)
|
|
160
|
-
}
|
|
147
|
+
asyncio_task_cls(py)?.call1(py, (coro,))
|
|
161
148
|
}
|
|
162
149
|
|
|
163
150
|
fn call_protocol_factory(
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import unittest
|
|
3
|
+
|
|
4
|
+
import rsloop
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class RunTests(unittest.TestCase):
|
|
8
|
+
def test_set_event_loop_accepts_rsloop_loop(self) -> None:
|
|
9
|
+
loop = rsloop.new_event_loop()
|
|
10
|
+
try:
|
|
11
|
+
asyncio.set_event_loop(loop)
|
|
12
|
+
self.assertIs(asyncio.get_event_loop(), loop)
|
|
13
|
+
finally:
|
|
14
|
+
asyncio.set_event_loop(None)
|
|
15
|
+
loop.close()
|
|
16
|
+
|
|
17
|
+
def test_run_executes_coroutine(self) -> None:
|
|
18
|
+
async def main() -> str:
|
|
19
|
+
return "ok"
|
|
20
|
+
|
|
21
|
+
self.assertEqual(rsloop.run(main()), "ok")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
if __name__ == "__main__":
|
|
25
|
+
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|