Skip to content

Commit

Permalink
Upgrade to pyo3 0.21
Browse files Browse the repository at this point in the history
Fix compilation errors

Migrate off of deprecated methods

Ignore must use false-positive
  • Loading branch information
kcking committed May 17, 2024
1 parent 398ed30 commit ed31a14
Show file tree
Hide file tree
Showing 19 changed files with 288 additions and 260 deletions.
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "pyo3-asyncio"
description = "PyO3 utilities for Python's Asyncio library"
version = "0.20.0"
version = "0.21.0"
authors = ["Andrew J Westlake <[email protected]>"]
readme = "README.md"
keywords = ["pyo3", "python", "ffi", "async", "asyncio"]
Expand Down Expand Up @@ -116,11 +116,11 @@ futures = "0.3"
inventory = { version = "0.3", optional = true }
once_cell = "1.14"
pin-project-lite = "0.2"
pyo3 = "0.20"
pyo3 = "0.21"
pyo3-asyncio-macros = { path = "pyo3-asyncio-macros", version = "=0.20.0", optional = true }

[dev-dependencies]
pyo3 = { version = "0.20", features = ["macros"] }
pyo3 = { version = "0.21", features = ["macros"] }

[dependencies.async-std]
version = "1.12"
Expand Down
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ use pyo3::prelude::*;
#[pyo3_asyncio::async_std::main]
async fn main() -> PyResult<()> {
let fut = Python::with_gil(|py| {
let asyncio = py.import("asyncio")?;
let asyncio = py.import_bound("asyncio")?;
// convert asyncio.sleep into a Rust Future
pyo3_asyncio::async_std::into_future(asyncio.call_method1("sleep", (1.into_py(py),))?)
})?;
Expand Down Expand Up @@ -95,7 +95,7 @@ use pyo3::prelude::*;
#[pyo3_asyncio::tokio::main]
async fn main() -> PyResult<()> {
let fut = Python::with_gil(|py| {
let asyncio = py.import("asyncio")?;
let asyncio = py.import_bound("asyncio")?;
// convert asyncio.sleep into a Rust Future
pyo3_asyncio::tokio::into_future(asyncio.call_method1("sleep", (1.into_py(py),))?)
})?;
Expand Down Expand Up @@ -149,7 +149,7 @@ Export an async function that makes use of `async-std`:
use pyo3::{prelude::*, wrap_pyfunction};

#[pyfunction]
fn rust_sleep(py: Python) -> PyResult<&PyAny> {
fn rust_sleep(py: Python) -> PyResult<Bound<PyAny>> {
pyo3_asyncio::async_std::future_into_py(py, async {
async_std::task::sleep(std::time::Duration::from_secs(1)).await;
Ok(())
Expand All @@ -173,7 +173,7 @@ If you want to use `tokio` instead, here's what your module should look like:
use pyo3::{prelude::*, wrap_pyfunction};

#[pyfunction]
fn rust_sleep(py: Python) -> PyResult<&PyAny> {
fn rust_sleep(py: Python) -> PyResult<Bound<PyAny>> {
pyo3_asyncio::tokio::future_into_py(py, async {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
Ok(())
Expand Down Expand Up @@ -237,7 +237,7 @@ use pyo3::prelude::*;
async fn main() -> PyResult<()> {
let future = Python::with_gil(|py| -> PyResult<_> {
// import the module containing the py_sleep function
let example = py.import("example")?;
let example = py.import_bound("example")?;

// calling the py_sleep method like a normal function
// returns a coroutine
Expand Down Expand Up @@ -289,7 +289,7 @@ async fn rust_sleep() {
}

#[pyfunction]
fn call_rust_sleep(py: Python) -> PyResult<&PyAny> {
fn call_rust_sleep(py: Python) -> PyResult<Bound<PyAny>> {
pyo3_asyncio::async_std::future_into_py(py, async move {
rust_sleep().await;
Ok(())
Expand Down Expand Up @@ -356,7 +356,7 @@ async fn main() -> PyResult<()> {
// PyO3 is initialized - Ready to go
let fut = Python::with_gil(|py| -> PyResult<_> {
let asyncio = py.import("asyncio")?;
let asyncio = py.import_bound("asyncio")?;
// convert asyncio.sleep into a Rust Future
pyo3_asyncio::async_std::into_future(
Expand Down Expand Up @@ -443,7 +443,7 @@ tokio = "1.9"
use pyo3::{prelude::*, wrap_pyfunction};

#[pyfunction]
fn rust_sleep(py: Python) -> PyResult<&PyAny> {
fn rust_sleep(py: Python) -> PyResult<Bound<PyAny>> {
pyo3_asyncio::tokio::future_into_py(py, async {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
Ok(())
Expand Down Expand Up @@ -504,7 +504,7 @@ fn main() -> PyResult<()> {
pyo3::prepare_freethreaded_python();

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

// store a reference for the assertion
Expand All @@ -514,7 +514,7 @@ fn main() -> PyResult<()> {
// verify that we are on a uvloop.Loop
Python::with_gil(|py| -> PyResult<()> {
assert!(uvloop
.as_ref(py)
.bind(py)
.getattr("Loop")?
.downcast::<PyType>()
.unwrap()
Expand Down Expand Up @@ -601,7 +601,7 @@ To make things a bit easier, I decided to keep most of the old API alongside the
pyo3::prepare_freethreaded_python();

Python::with_gil(|py| {
let asyncio = py.import("asyncio")?;
let asyncio = py.import_bound("asyncio")?;

let event_loop = asyncio.call_method0("new_event_loop")?;
asyncio.call_method1("set_event_loop", (event_loop,))?;
Expand All @@ -614,11 +614,11 @@ To make things a bit easier, I decided to keep most of the old API alongside the
// Stop the event loop manually
Python::with_gil(|py| {
event_loop_hdl
.as_ref(py)
.bind(py)
.call_method1(
"call_soon_threadsafe",
(event_loop_hdl
.as_ref(py)
.bind(py)
.getattr("stop")
.unwrap(),),
)
Expand Down
2 changes: 1 addition & 1 deletion examples/async_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use pyo3::prelude::*;
#[pyo3_asyncio::async_std::main]
async fn main() -> PyResult<()> {
let fut = Python::with_gil(|py| {
let asyncio = py.import("asyncio")?;
let asyncio = py.import_bound("asyncio")?;

// convert asyncio.sleep into a Rust Future
pyo3_asyncio::async_std::into_future(asyncio.call_method1("sleep", (1.into_py(py),))?)
Expand Down
2 changes: 1 addition & 1 deletion examples/tokio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use pyo3::prelude::*;
#[pyo3_asyncio::tokio::main]
async fn main() -> PyResult<()> {
let fut = Python::with_gil(|py| {
let asyncio = py.import("asyncio")?;
let asyncio = py.import_bound("asyncio")?;

// convert asyncio.sleep into a Rust Future
pyo3_asyncio::tokio::into_future(asyncio.call_method1("sleep", (1.into_py(py),))?)
Expand Down
2 changes: 1 addition & 1 deletion examples/tokio_current_thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use pyo3::prelude::*;
#[pyo3_asyncio::tokio::main(flavor = "current_thread")]
async fn main() -> PyResult<()> {
let fut = Python::with_gil(|py| {
let asyncio = py.import("asyncio")?;
let asyncio = py.import_bound("asyncio")?;

// convert asyncio.sleep into a Rust Future
pyo3_asyncio::tokio::into_future(asyncio.call_method1("sleep", (1.into_py(py),))?)
Expand Down
2 changes: 1 addition & 1 deletion examples/tokio_multi_thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use pyo3::prelude::*;
#[pyo3_asyncio::tokio::main(flavor = "multi_thread", worker_threads = 10)]
async fn main() -> PyResult<()> {
let fut = Python::with_gil(|py| {
let asyncio = py.import("asyncio")?;
let asyncio = py.import_bound("asyncio")?;

// convert asyncio.sleep into a Rust Future
pyo3_asyncio::tokio::into_future(asyncio.call_method1("sleep", (1.into_py(py),))?)
Expand Down
12 changes: 6 additions & 6 deletions pytests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ async def sleep_for_1s(sleep_for):
pub(super) async fn test_into_future(event_loop: PyObject) -> PyResult<()> {
let fut = Python::with_gil(|py| {
let test_mod =
PyModule::from_code(py, TEST_MOD, "test_rust_coroutine/test_mod.py", "test_mod")?;
PyModule::from_code_bound(py, TEST_MOD, "test_rust_coroutine/test_mod.py", "test_mod")?;

pyo3_asyncio::into_future_with_locals(
&TaskLocals::new(event_loop.as_ref(py)),
&TaskLocals::new(event_loop.into_bound(py)),
test_mod.call_method1("py_sleep", (1.into_py(py),))?,
)
})?;
Expand All @@ -36,19 +36,19 @@ pub(super) fn test_blocking_sleep() -> PyResult<()> {

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

// spawn a blocking sleep in the threadpool executor - returns a task, not a coroutine
let task = event_loop.as_ref(py).call_method1(
let task = event_loop.bind(py).call_method1(
"run_in_executor",
(
py.None(),
functools.call_method1("partial", (time.getattr("sleep")?, 1))?,
),
)?;

pyo3_asyncio::into_future_with_locals(&TaskLocals::new(event_loop.as_ref(py)), task)
pyo3_asyncio::into_future_with_locals(&TaskLocals::new(event_loop.into_bound(py)), task)
})?;

fut.await?;
Expand Down
64 changes: 33 additions & 31 deletions pytests/test_async_std_asyncio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use pyo3_asyncio::TaskLocals;
use futures::{StreamExt, TryStreamExt};

#[pyfunction]
fn sleep<'p>(py: Python<'p>, secs: &'p PyAny) -> PyResult<&'p PyAny> {
fn sleep<'p>(py: Python<'p>, secs: Bound<'p, PyAny>) -> PyResult<Bound<'p, PyAny>> {
let secs = secs.extract()?;

pyo3_asyncio::async_std::future_into_py(py, async move {
Expand All @@ -30,11 +30,11 @@ fn sleep<'p>(py: Python<'p>, secs: &'p PyAny) -> PyResult<&'p PyAny> {
#[pyo3_asyncio::async_std::test]
async fn test_future_into_py() -> PyResult<()> {
let fut = Python::with_gil(|py| {
let sleeper_mod = PyModule::new(py, "rust_sleeper")?;
let sleeper_mod = PyModule::new_bound(py, "rust_sleeper")?;

sleeper_mod.add_wrapped(wrap_pyfunction!(sleep))?;

let test_mod = PyModule::from_code(
let test_mod = PyModule::from_code_bound(
py,
common::TEST_MOD,
"test_future_into_py_mod.py",
Expand All @@ -53,13 +53,15 @@ async fn test_future_into_py() -> PyResult<()> {

#[pyo3_asyncio::async_std::test]
async fn test_async_sleep() -> PyResult<()> {
let asyncio =
Python::with_gil(|py| py.import("asyncio").map(|asyncio| PyObject::from(asyncio)))?;
let asyncio = Python::with_gil(|py| {
py.import_bound("asyncio")
.map(|asyncio| PyObject::from(asyncio))
})?;

task::sleep(Duration::from_secs(1)).await;

Python::with_gil(|py| {
pyo3_asyncio::async_std::into_future(asyncio.as_ref(py).call_method1("sleep", (1.0,))?)
pyo3_asyncio::async_std::into_future(asyncio.bind(py).call_method1("sleep", (1.0,))?)
})?
.await?;

Expand Down Expand Up @@ -146,14 +148,14 @@ async fn test_cancel() -> PyResult<()> {
})?;

if let Err(e) = Python::with_gil(|py| -> PyResult<_> {
py_future.as_ref(py).call_method0("cancel")?;
pyo3_asyncio::async_std::into_future(py_future.as_ref(py))
py_future.bind(py).call_method0("cancel")?;
pyo3_asyncio::async_std::into_future(py_future.into_bound(py))
})?
.await
{
Python::with_gil(|py| -> PyResult<()> {
assert!(e.value(py).is_instance(
py.import("asyncio")?
assert!(e.value_bound(py).is_instance(
py.import_bound("asyncio")?
.getattr("CancelledError")?
.downcast::<PyType>()
.unwrap()
Expand Down Expand Up @@ -186,7 +188,7 @@ async def gen():
#[pyo3_asyncio::async_std::test]
async fn test_async_gen_v1() -> PyResult<()> {
let stream = Python::with_gil(|py| {
let test_mod = PyModule::from_code(
let test_mod = PyModule::from_code_bound(
py,
ASYNC_STD_TEST_MOD,
"test_rust_coroutine/async_std_test_mod.py",
Expand All @@ -197,7 +199,7 @@ async fn test_async_gen_v1() -> PyResult<()> {
})?;

let vals = stream
.map(|item| Python::with_gil(|py| -> PyResult<i32> { Ok(item?.as_ref(py).extract()?) }))
.map(|item| Python::with_gil(|py| -> PyResult<i32> { Ok(item?.bind(py).extract()?) }))
.try_collect::<Vec<i32>>()
.await?;

Expand All @@ -209,7 +211,7 @@ async fn test_async_gen_v1() -> PyResult<()> {
#[pyo3_asyncio::async_std::test]
fn test_local_cancel(event_loop: PyObject) -> PyResult<()> {
let locals = Python::with_gil(|py| -> PyResult<TaskLocals> {
Ok(TaskLocals::new(event_loop.as_ref(py)).copy_context(py)?)
Ok(TaskLocals::new(event_loop.into_bound(py)).copy_context(py)?)
})?;
async_std::task::block_on(pyo3_asyncio::async_std::scope_local(locals, async {
let completed = Arc::new(Mutex::new(false));
Expand All @@ -226,14 +228,14 @@ fn test_local_cancel(event_loop: PyObject) -> PyResult<()> {
})?;

if let Err(e) = Python::with_gil(|py| -> PyResult<_> {
py_future.as_ref(py).call_method0("cancel")?;
pyo3_asyncio::async_std::into_future(py_future.as_ref(py))
py_future.bind(py).call_method0("cancel")?;
pyo3_asyncio::async_std::into_future(py_future.into_bound(py))
})?
.await
{
Python::with_gil(|py| -> PyResult<()> {
assert!(e.value(py).is_instance(
py.import("asyncio")?
assert!(e.value_bound(py).is_instance(
py.import_bound("asyncio")?
.getattr("CancelledError")?
.downcast::<PyType>()
.unwrap()
Expand All @@ -258,7 +260,7 @@ fn test_local_cancel(event_loop: PyObject) -> PyResult<()> {
fn test_mod(_py: Python, m: &PyModule) -> PyResult<()> {
#![allow(deprecated)]
#[pyfunction(name = "sleep")]
fn sleep_(py: Python) -> PyResult<&PyAny> {
fn sleep_(py: Python) -> PyResult<Bound<PyAny>> {
pyo3_asyncio::async_std::future_into_py(py, async move {
async_std::task::sleep(Duration::from_millis(500)).await;
Ok(())
Expand Down Expand Up @@ -290,13 +292,13 @@ fn test_multiple_asyncio_run() -> PyResult<()> {
})?;

let d = [
("asyncio", py.import("asyncio")?.into()),
("asyncio", py.import_bound("asyncio")?.into()),
("test_mod", wrap_pymodule!(test_mod)(py)),
]
.into_py_dict(py);
.into_py_dict_bound(py);

py.run(MULTI_ASYNCIO_CODE, Some(d), None)?;
py.run(MULTI_ASYNCIO_CODE, Some(d), None)?;
py.run_bound(MULTI_ASYNCIO_CODE, Some(&d), None)?;
py.run_bound(MULTI_ASYNCIO_CODE, Some(&d), None)?;
Ok(())
})
}
Expand All @@ -305,10 +307,10 @@ fn test_multiple_asyncio_run() -> PyResult<()> {
fn cvars_mod(_py: Python, m: &PyModule) -> PyResult<()> {
#![allow(deprecated)]
#[pyfunction]
pub(crate) fn async_callback(py: Python, callback: PyObject) -> PyResult<&PyAny> {
pub(crate) fn async_callback(py: Python, callback: PyObject) -> PyResult<Bound<PyAny>> {
pyo3_asyncio::async_std::future_into_py(py, async move {
Python::with_gil(|py| {
pyo3_asyncio::async_std::into_future(callback.as_ref(py).call0()?)
pyo3_asyncio::async_std::into_future(callback.bind(py).call0()?)
})?
.await?;

Expand All @@ -325,7 +327,7 @@ fn cvars_mod(_py: Python, m: &PyModule) -> PyResult<()> {
#[pyo3_asyncio::async_std::test]
async fn test_async_gen_v2() -> PyResult<()> {
let stream = Python::with_gil(|py| {
let test_mod = PyModule::from_code(
let test_mod = PyModule::from_code_bound(
py,
ASYNC_STD_TEST_MOD,
"test_rust_coroutine/async_std_test_mod.py",
Expand All @@ -336,7 +338,7 @@ async fn test_async_gen_v2() -> PyResult<()> {
})?;

let vals = stream
.map(|item| Python::with_gil(|py| -> PyResult<i32> { Ok(item.as_ref(py).extract()?) }))
.map(|item| Python::with_gil(|py| -> PyResult<i32> { Ok(item.bind(py).extract()?) }))
.try_collect::<Vec<i32>>()
.await?;

Expand All @@ -362,14 +364,14 @@ asyncio.run(main())
fn test_contextvars() -> PyResult<()> {
Python::with_gil(|py| {
let d = [
("asyncio", py.import("asyncio")?.into()),
("contextvars", py.import("contextvars")?.into()),
("asyncio", py.import_bound("asyncio")?.into()),
("contextvars", py.import_bound("contextvars")?.into()),
("cvars_mod", wrap_pymodule!(cvars_mod)(py)),
]
.into_py_dict(py);
.into_py_dict_bound(py);

py.run(CONTEXTVARS_CODE, Some(d), None)?;
py.run(CONTEXTVARS_CODE, Some(d), None)?;
py.run_bound(CONTEXTVARS_CODE, Some(&d), None)?;
py.run_bound(CONTEXTVARS_CODE, Some(&d), None)?;
Ok(())
})
}
Expand Down
Loading

0 comments on commit ed31a14

Please sign in to comment.