Skip to content
8 changes: 1 addition & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ jobs:
]
include:
# Test minimal supported Rust version
- rust: 1.63.0
- rust: 1.74.0
python-version: "3.13"
platform:
{
Expand Down Expand Up @@ -126,12 +126,6 @@ jobs:
toolchain: ${{ matrix.rust }}
target: ${{ matrix.platform.rust-target }}

- if: ${{ matrix.msrv == 'MSRV' }}
name: Set MSRV dependencies
run: |
cargo add tokio@=1.38.1
cargo update -p once_cell --precise 1.20.3

- name: Build (no features)
run: cargo build --no-default-features --verbose --target ${{ matrix.platform.rust-target }}

Expand Down
10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "pyo3-async-runtimes"
description = "PyO3 bridges from Rust runtimes to Python's Asyncio library"
version = "0.25.0"
version = "0.26.0"
authors = [
"Andrew J Westlake <awestlake87@yahoo.com>",
"David Hewitt <mail@davidhewitt.dev>",
Expand All @@ -15,7 +15,7 @@ categories = ["api-bindings", "development-tools::ffi"]
license = "Apache-2.0"
exclude = ["/.gitignore", "/codecov.yml", "/Makefile"]
edition = "2021"
rust-version = "1.63"
rust-version = "1.74"

[workspace]
members = ["pyo3-async-runtimes-macros"]
Expand Down Expand Up @@ -120,11 +120,11 @@ futures = "0.3"
inventory = { version = "0.3", optional = true }
once_cell = "1.14"
pin-project-lite = "0.2"
pyo3 = "0.25"
pyo3-async-runtimes-macros = { path = "pyo3-async-runtimes-macros", version = "=0.25.0", optional = true }
pyo3 = "0.26"
pyo3-async-runtimes-macros = { path = "pyo3-async-runtimes-macros", version = "=0.26.0", optional = true }

[dev-dependencies]
pyo3 = { version = "0.25", features = ["macros"] }
pyo3 = { version = "0.26", features = ["macros"] }

[dependencies.async-std]
version = "1.12"
Expand Down
46 changes: 23 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ Here we initialize the runtime, import Python's `asyncio` library and run the gi
```toml
# Cargo.toml dependencies
[dependencies]
pyo3 = { version = "0.25" }
pyo3-async-runtimes = { version = "0.25", features = ["attributes", "async-std-runtime"] }
pyo3 = { version = "0.26" }
pyo3-async-runtimes = { version = "0.26", features = ["attributes", "async-std-runtime"] }
async-std = "1.13"
```

Expand All @@ -62,10 +62,10 @@ use pyo3::prelude::*;

#[pyo3_async_runtimes::async_std::main]
async fn main() -> PyResult<()> {
let fut = Python::with_gil(|py| {
let fut = Python::attach(|py| {
let asyncio = py.import("asyncio")?;
// convert asyncio.sleep into a Rust Future
pyo3_async_runtimes::async_std::into_future(asyncio.call_method1("sleep", (1.into_pyobject(py).unwrap(),))?)
pyo3_async_runtimes::async_std::into_future(asyncio.call_method1("sleep", (1,))?)
})?;

fut.await?;
Expand All @@ -80,8 +80,8 @@ attribute.
```toml
# Cargo.toml dependencies
[dependencies]
pyo3 = { version = "0.25" }
pyo3-async-runtimes = { version = "0.25", features = ["attributes", "tokio-runtime"] }
pyo3 = { version = "0.26" }
pyo3-async-runtimes = { version = "0.26", features = ["attributes", "tokio-runtime"] }
tokio = "1.40"
```

Expand All @@ -92,10 +92,10 @@ use pyo3::prelude::*;

#[pyo3_async_runtimes::tokio::main]
async fn main() -> PyResult<()> {
let fut = Python::with_gil(|py| {
let fut = Python::attach(|py| {
let asyncio = py.import("asyncio")?;
// convert asyncio.sleep into a Rust Future
pyo3_async_runtimes::tokio::into_future(asyncio.call_method1("sleep", (1.into_pyobject(py).unwrap(),))?)
pyo3_async_runtimes::tokio::into_future(asyncio.call_method1("sleep", (1,))?)
})?;

fut.await?;
Expand Down Expand Up @@ -126,17 +126,17 @@ For `async-std`:

```toml
[dependencies]
pyo3 = { version = "0.25", features = ["extension-module"] }
pyo3-async-runtimes = { version = "0.25", features = ["async-std-runtime"] }
pyo3 = { version = "0.26", features = ["extension-module"] }
pyo3-async-runtimes = { version = "0.26", features = ["async-std-runtime"] }
async-std = "1.13"
```

For `tokio`:

```toml
[dependencies]
pyo3 = { version = "0.25", features = ["extension-module"] }
pyo3-async-runtimes = { version = "0.25", features = ["tokio-runtime"] }
pyo3 = { version = "0.26", features = ["extension-module"] }
pyo3-async-runtimes = { version = "0.26", features = ["tokio-runtime"] }
tokio = "1.40"
```

Expand Down Expand Up @@ -234,7 +234,7 @@ use pyo3::prelude::*;

#[pyo3_async_runtimes::tokio::main]
async fn main() -> PyResult<()> {
let future = Python::with_gil(|py| -> PyResult<_> {
let future = Python::attach(|py| -> PyResult<_> {
// import the module containing the py_sleep function
let example = py.import("example")?;

Expand Down Expand Up @@ -354,12 +354,12 @@ use pyo3::prelude::*;
async fn main() -> PyResult<()> {
// PyO3 is initialized - Ready to go

let fut = Python::with_gil(|py| -> PyResult<_> {
let fut = Python::attach(|py| -> PyResult<_> {
let asyncio = py.import("asyncio")?;

// convert asyncio.sleep into a Rust Future
pyo3_async_runtimes::async_std::into_future(
asyncio.call_method1("sleep", (1.into_pyobject(py).unwrap(),))?
asyncio.call_method1("sleep", (1,))?
)
})?;

Expand Down Expand Up @@ -430,8 +430,8 @@ name = "my_async_module"
crate-type = ["cdylib"]

[dependencies]
pyo3 = { version = "0.25", features = ["extension-module"] }
pyo3-async-runtimes = { version = "0.25", features = ["tokio-runtime"] }
pyo3 = { version = "0.26", features = ["extension-module"] }
pyo3-async-runtimes = { version = "0.26", features = ["tokio-runtime"] }
async-std = "1.13"
tokio = "1.40"
```
Expand Down Expand Up @@ -490,8 +490,8 @@ event loop before we can install the `uvloop` policy.
```toml
[dependencies]
async-std = "1.13"
pyo3 = "0.25"
pyo3-async-runtimes = { version = "0.25", features = ["async-std-runtime"] }
pyo3 = "0.26"
pyo3-async-runtimes = { version = "0.26", features = ["async-std-runtime"] }
```

```rust no_run
Expand All @@ -500,18 +500,18 @@ pyo3-async-runtimes = { version = "0.25", features = ["async-std-runtime"] }
use pyo3::{prelude::*, types::PyType};

fn main() -> PyResult<()> {
pyo3::prepare_freethreaded_python();
Python::initialize();

Python::with_gil(|py| {
Python::attach(|py| {
let uvloop = py.import("uvloop")?;
uvloop.call_method0("install")?;

// store a reference for the assertion
let uvloop = PyObject::from(uvloop);
let uvloop: Py<PyAny> = uvloop.into();

pyo3_async_runtimes::async_std::run(py, async move {
// verify that we are on a uvloop.Loop
Python::with_gil(|py| -> PyResult<()> {
Python::attach(|py| -> PyResult<()> {
assert!(uvloop
.bind(py)
.getattr("Loop")?
Expand Down
6 changes: 2 additions & 4 deletions examples/async_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ use pyo3::prelude::*;

#[pyo3_async_runtimes::async_std::main]
async fn main() -> PyResult<()> {
let fut = Python::with_gil(|py| {
let fut = Python::attach(|py| {
let asyncio = py.import("asyncio")?;

// convert asyncio.sleep into a Rust Future
pyo3_async_runtimes::async_std::into_future(
asyncio.call_method1("sleep", (1.into_pyobject(py).unwrap(),))?,
)
pyo3_async_runtimes::async_std::into_future(asyncio.call_method1("sleep", (1,))?)
})?;

println!("sleeping for 1s");
Expand Down
6 changes: 2 additions & 4 deletions examples/tokio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ use pyo3::prelude::*;

#[pyo3_async_runtimes::tokio::main]
async fn main() -> PyResult<()> {
let fut = Python::with_gil(|py| {
let fut = Python::attach(|py| {
let asyncio = py.import("asyncio")?;

// convert asyncio.sleep into a Rust Future
pyo3_async_runtimes::tokio::into_future(
asyncio.call_method1("sleep", (1.into_pyobject(py).unwrap(),))?,
)
pyo3_async_runtimes::tokio::into_future(asyncio.call_method1("sleep", (1,))?)
})?;

println!("sleeping for 1s");
Expand Down
6 changes: 2 additions & 4 deletions examples/tokio_current_thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ use pyo3::prelude::*;

#[pyo3_async_runtimes::tokio::main(flavor = "current_thread")]
async fn main() -> PyResult<()> {
let fut = Python::with_gil(|py| {
let fut = Python::attach(|py| {
let asyncio = py.import("asyncio")?;

// convert asyncio.sleep into a Rust Future
pyo3_async_runtimes::tokio::into_future(
asyncio.call_method1("sleep", (1.into_pyobject(py).unwrap(),))?,
)
pyo3_async_runtimes::tokio::into_future(asyncio.call_method1("sleep", (1,))?)
})?;

println!("sleeping for 1s");
Expand Down
6 changes: 2 additions & 4 deletions examples/tokio_multi_thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ use pyo3::prelude::*;

#[pyo3_async_runtimes::tokio::main(flavor = "multi_thread", worker_threads = 10)]
async fn main() -> PyResult<()> {
let fut = Python::with_gil(|py| {
let fut = Python::attach(|py| {
let asyncio = py.import("asyncio")?;

// convert asyncio.sleep into a Rust Future
pyo3_async_runtimes::tokio::into_future(
asyncio.call_method1("sleep", (1.into_pyobject(py).unwrap(),))?,
)
pyo3_async_runtimes::tokio::into_future(asyncio.call_method1("sleep", (1,))?)
})?;

println!("sleeping for 1s");
Expand Down
2 changes: 1 addition & 1 deletion pyo3-async-runtimes-macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "pyo3-async-runtimes-macros"
description = "Proc Macro Attributes for `pyo3-async-runtimes`"
version = "0.25.0"
version = "0.26.0"
authors = [
"Andrew J Westlake <awestlake87@yahoo.com>",
"David Hewitt <mail@davidhewitt.dev>",
Expand Down
12 changes: 6 additions & 6 deletions pyo3-async-runtimes-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ pub fn async_std_main(_attr: TokenStream, item: TokenStream) -> TokenStream {
#body
}

pyo3::prepare_freethreaded_python();
pyo3::Python::initialize();

pyo3::Python::with_gil(|py| {
pyo3::Python::attach(|py| {
pyo3_async_runtimes::async_std::run(py, main())
.map_err(|e| {
e.print_and_set_sys_last_vars(py);
Expand Down Expand Up @@ -129,7 +129,7 @@ pub fn tokio_main(args: TokenStream, item: TokenStream) -> TokenStream {
///
/// // blocking test functions can optionally accept an event_loop parameter
/// #[pyo3_async_runtimes::async_std::test]
/// fn test_blocking_sleep_with_event_loop(event_loop: PyObject) -> PyResult<()> {
/// fn test_blocking_sleep_with_event_loop(event_loop: Py<PyAny>) -> PyResult<()> {
/// thread::sleep(Duration::from_secs(1));
/// Ok(())
/// }
Expand All @@ -154,7 +154,7 @@ pub fn async_std_test(_attr: TokenStream, item: TokenStream) -> TokenStream {
}
} else {
quote! {
let event_loop = Python::with_gil(|py| {
let event_loop = pyo3::Python::attach(|py| {
pyo3_async_runtimes::async_std::get_current_loop(py).unwrap().into()
});
Box::pin(pyo3_async_runtimes::async_std::re_exports::spawn_blocking(move || {
Expand Down Expand Up @@ -226,7 +226,7 @@ pub fn async_std_test(_attr: TokenStream, item: TokenStream) -> TokenStream {
///
/// // blocking test functions can optionally accept an event_loop parameter
/// #[pyo3_async_runtimes::tokio::test]
/// fn test_blocking_sleep_with_event_loop(event_loop: PyObject) -> PyResult<()> {
/// fn test_blocking_sleep_with_event_loop(event_loop: Py<PyAny>) -> PyResult<()> {
/// thread::sleep(Duration::from_secs(1));
/// Ok(())
/// }
Expand Down Expand Up @@ -265,7 +265,7 @@ pub fn tokio_test(_attr: TokenStream, item: TokenStream) -> TokenStream {
}
} else {
quote! {
let event_loop = Python::with_gil(|py| {
let event_loop = pyo3::Python::attach(|py| {
pyo3_async_runtimes::tokio::get_current_loop(py).unwrap().into()
});
Box::pin(async move {
Expand Down
4 changes: 2 additions & 2 deletions pyo3-async-runtimes-macros/src/tokio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ fn parse_knobs(
#body
}

pyo3::prepare_freethreaded_python();
pyo3::Python::initialize();

let mut builder = #builder;
#builder_init;
Expand All @@ -277,7 +277,7 @@ fn parse_knobs(

#rt_init

pyo3::Python::with_gil(|py| {
pyo3::Python::attach(|py| {
pyo3_async_runtimes::tokio::run(py, main())
.map_err(|e| {
e.print_and_set_sys_last_vars(py);
Expand Down
10 changes: 5 additions & 5 deletions pytests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ async def sleep_for_1s(sleep_for):
await sleep_for(1)
"#;

pub(super) async fn test_into_future(event_loop: PyObject) -> PyResult<()> {
let fut = Python::with_gil(|py| {
pub(super) async fn test_into_future(event_loop: Py<PyAny>) -> PyResult<()> {
let fut = Python::attach(|py| {
let test_mod = PyModule::from_code(
py,
&CString::new(TEST_MOD).unwrap(),
Expand All @@ -25,7 +25,7 @@ pub(super) async fn test_into_future(event_loop: PyObject) -> PyResult<()> {

pyo3_async_runtimes::into_future_with_locals(
&TaskLocals::new(event_loop.into_bound(py)),
test_mod.call_method1("py_sleep", (1.into_pyobject(py).unwrap(),))?,
test_mod.call_method1("py_sleep", (1,))?,
)
})?;

Expand All @@ -39,8 +39,8 @@ pub(super) fn test_blocking_sleep() -> PyResult<()> {
Ok(())
}

pub(super) async fn test_other_awaitables(event_loop: PyObject) -> PyResult<()> {
let fut = Python::with_gil(|py| {
pub(super) async fn test_other_awaitables(event_loop: Py<PyAny>) -> PyResult<()> {
let fut = Python::attach(|py| {
let functools = py.import("functools")?;
let time = py.import("time")?;

Expand Down
Loading
Loading