Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/cargo/clap-4.5
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt authored Oct 11, 2024
2 parents 14ee6ff + aec0c26 commit 0eb883a
Show file tree
Hide file tree
Showing 10 changed files with 205 additions and 210 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ name: CI
on:
push:
branches:
- master
- main
pull_request:
branches:
- master
- main

env:
CARGO_TERM_COLOR: always
Expand Down
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,17 @@ harness = false
required-features = ["async-std-runtime", "testing"]

[dependencies]
async-channel = { version = "1.6", optional = true }
async-channel = { version = "2.3", optional = true }
clap = { version = "4.5", optional = true }
futures = "0.3"
inventory = { version = "0.3", optional = true }
once_cell = "1.14"
pin-project-lite = "0.2"
pyo3 = "0.21"
pyo3 = "0.22"
pyo3-async-runtimes-macros = { path = "pyo3-asyncio-macros", version = "=0.21.0", optional = true }

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

[dependencies.async-std]
version = "1.12"
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ fn rust_sleep(py: Python) -> PyResult<Bound<PyAny>> {
}

#[pymodule]
fn my_async_module(py: Python, m: &PyModule) -> PyResult<()> {
fn my_async_module(py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(rust_sleep, m)?)?;

Ok(())
Expand All @@ -183,7 +183,7 @@ fn rust_sleep(py: Python) -> PyResult<Bound<PyAny>> {
}

#[pymodule]
fn my_async_module(py: Python, m: &PyModule) -> PyResult<()> {
fn my_async_module(py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(rust_sleep, m)?)?;
Ok(())
}
Expand Down Expand Up @@ -453,7 +453,7 @@ fn rust_sleep(py: Python) -> PyResult<Bound<PyAny>> {
}

#[pymodule]
fn my_async_module(_py: Python, m: &PyModule) -> PyResult<()> {
fn my_async_module(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(rust_sleep, m)?)?;

Ok(())
Expand Down
19 changes: 10 additions & 9 deletions pytests/test_async_std_asyncio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,11 @@ async fn test_other_awaitables() -> PyResult<()> {
#[pyo3_async_runtimes::async_std::test]
async fn test_panic() -> PyResult<()> {
let fut = Python::with_gil(|py| -> PyResult<_> {
pyo3_async_runtimes::async_std::into_future(pyo3_async_runtimes::async_std::future_into_py::<
_,
(),
>(py, async {
panic!("this panic was intentional!")
})?)
pyo3_async_runtimes::async_std::into_future(
pyo3_async_runtimes::async_std::future_into_py::<_, ()>(py, async {
panic!("this panic was intentional!")
})?,
)
})?;

match fut.await {
Expand Down Expand Up @@ -263,7 +262,7 @@ fn test_local_cancel(event_loop: PyObject) -> PyResult<()> {

/// This module is implemented in Rust.
#[pymodule]
fn test_mod(_py: Python, m: &PyModule) -> PyResult<()> {
fn test_mod(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
#![allow(deprecated)]
#[pyfunction(name = "sleep")]
fn sleep_(py: Python) -> PyResult<Bound<PyAny>> {
Expand Down Expand Up @@ -310,7 +309,7 @@ fn test_multiple_asyncio_run() -> PyResult<()> {
}

#[pymodule]
fn cvars_mod(_py: Python, m: &PyModule) -> PyResult<()> {
fn cvars_mod(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
#![allow(deprecated)]
#[pyfunction]
pub(crate) fn async_callback(py: Python, callback: PyObject) -> PyResult<Bound<PyAny>> {
Expand Down Expand Up @@ -385,5 +384,7 @@ fn test_contextvars() -> PyResult<()> {
fn main() -> pyo3::PyResult<()> {
pyo3::prepare_freethreaded_python();

Python::with_gil(|py| pyo3_async_runtimes::async_std::run(py, pyo3_async_runtimes::testing::main()))
Python::with_gil(|py| {
pyo3_async_runtimes::async_std::run(py, pyo3_async_runtimes::testing::main())
})
}
13 changes: 7 additions & 6 deletions pytests/tokio_asyncio/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,11 @@ fn test_local_future_into_py(event_loop: PyObject) -> PyResult<()> {
#[pyo3_async_runtimes::tokio::test]
async fn test_panic() -> PyResult<()> {
let fut = Python::with_gil(|py| -> PyResult<_> {
pyo3_async_runtimes::tokio::into_future(pyo3_async_runtimes::tokio::future_into_py::<_, ()>(
py,
async { panic!("this panic was intentional!") },
)?)
pyo3_async_runtimes::tokio::into_future(
pyo3_async_runtimes::tokio::future_into_py::<_, ()>(py, async {
panic!("this panic was intentional!")
})?,
)
})?;

match fut.await {
Expand Down Expand Up @@ -239,7 +240,7 @@ fn test_local_cancel(event_loop: PyObject) -> PyResult<()> {

/// This module is implemented in Rust.
#[pymodule]
fn test_mod(_py: Python, m: &PyModule) -> PyResult<()> {
fn test_mod(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
#![allow(deprecated)]
#[pyfunction(name = "sleep")]
fn sleep_(py: Python) -> PyResult<Bound<PyAny>> {
Expand Down Expand Up @@ -286,7 +287,7 @@ fn test_multiple_asyncio_run() -> PyResult<()> {
}

#[pymodule]
fn cvars_mod(_py: Python, m: &PyModule) -> PyResult<()> {
fn cvars_mod(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
#![allow(deprecated)]
#[pyfunction]
fn async_callback(py: Python, callback: PyObject) -> PyResult<Bound<PyAny>> {
Expand Down
76 changes: 39 additions & 37 deletions src/async_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@
//! features = ["unstable-streams"]
//! ```
use std::{any::Any, cell::RefCell, future::Future, panic::AssertUnwindSafe, pin::Pin};

use async_std::task;
use futures::FutureExt;
use pyo3::prelude::*;
use std::{any::Any, cell::RefCell, future::Future, panic::AssertUnwindSafe, pin::Pin};

use crate::{
generic::{self, ContextExt, JoinError, LocalContextExt, Runtime, SpawnLocalExt},
Expand All @@ -34,13 +33,13 @@ pub mod re_exports {

/// <span class="module-item stab portability" style="display: inline; border-radius: 3px; padding: 2px; font-size: 80%; line-height: 1.2;"><code>attributes</code></span> Provides the boilerplate for the `async-std` runtime and runs an async fn as main
#[cfg(feature = "attributes")]
pub use pyo3_asyncio_macros_0_21::async_std_main as main;
pub use pyo3_async_runtimes_macros::async_std_main as main;

/// <span class="module-item stab portability" style="display: inline; border-radius: 3px; padding: 2px; font-size: 80%; line-height: 1.2;"><code>attributes</code></span>
/// <span class="module-item stab portability" style="display: inline; border-radius: 3px; padding: 2px; font-size: 80%; line-height: 1.2;"><code>testing</code></span>
/// Registers an `async-std` test with the `pyo3-asyncio` test harness
#[cfg(all(feature = "attributes", feature = "testing"))]
pub use pyo3_asyncio_macros_0_21::async_std_test as test;
pub use pyo3_async_runtimes_macros::async_std_test as test;

struct AsyncStdJoinErr(Box<dyn Any + Send + 'static>);

Expand Down Expand Up @@ -71,7 +70,7 @@ impl Runtime for AsyncStdRuntime {
AssertUnwindSafe(fut)
.catch_unwind()
.await
.map_err(|e| AsyncStdJoinErr(e))
.map_err(AsyncStdJoinErr)
})
}
}
Expand All @@ -90,10 +89,13 @@ impl ContextExt for AsyncStdRuntime {
}

fn get_task_locals() -> Option<TaskLocals> {
match TASK_LOCALS.try_with(|c| c.borrow().clone()) {
Ok(locals) => locals,
Err(_) => None,
}
TASK_LOCALS
.try_with(|c| {
c.borrow()
.as_ref()
.map(|locals| Python::with_gil(|py| locals.clone_ref(py)))
})
.unwrap_or_default()
}
}

Expand Down Expand Up @@ -236,13 +238,13 @@ where
/// via [`into_future`] (new behaviour in `v0.15`).
///
/// > Although `contextvars` are preserved for async Python functions, synchronous functions will
/// unfortunately fail to resolve them when called within the Rust future. This is because the
/// function is being called from a Rust thread, not inside an actual Python coroutine context.
/// > unfortunately fail to resolve them when called within the Rust future. This is because the
/// > function is being called from a Rust thread, not inside an actual Python coroutine context.
/// >
/// > As a workaround, you can get the `contextvars` from the current task locals using
/// [`get_current_locals`] and [`TaskLocals::context`](`crate::TaskLocals::context`), then wrap your
/// synchronous function in a call to `contextvars.Context.run`. This will set the context, call the
/// synchronous function, and restore the previous context when it returns or raises an exception.
/// > [`get_current_locals`] and [`TaskLocals::context`](`crate::TaskLocals::context`), then wrap your
/// > synchronous function in a call to `contextvars.Context.run`. This will set the context, call the
/// > synchronous function, and restore the previous context when it returns or raises an exception.
///
/// # Arguments
/// * `py` - PyO3 GIL guard
Expand Down Expand Up @@ -291,13 +293,13 @@ where
/// via [`into_future`] (new behaviour in `v0.15`).
///
/// > Although `contextvars` are preserved for async Python functions, synchronous functions will
/// unfortunately fail to resolve them when called within the Rust future. This is because the
/// function is being called from a Rust thread, not inside an actual Python coroutine context.
/// > unfortunately fail to resolve them when called within the Rust future. This is because the
/// > function is being called from a Rust thread, not inside an actual Python coroutine context.
/// >
/// > As a workaround, you can get the `contextvars` from the current task locals using
/// [`get_current_locals`] and [`TaskLocals::context`](`crate::TaskLocals::context`), then wrap your
/// synchronous function in a call to `contextvars.Context.run`. This will set the context, call the
/// synchronous function, and restore the previous context when it returns or raises an exception.
/// > [`get_current_locals`] and [`TaskLocals::context`](`crate::TaskLocals::context`), then wrap your
/// > synchronous function in a call to `contextvars.Context.run`. This will set the context, call the
/// > synchronous function, and restore the previous context when it returns or raises an exception.
///
/// # Arguments
/// * `py` - The current PyO3 GIL guard
Expand Down Expand Up @@ -337,13 +339,13 @@ where
/// via [`into_future`] (new behaviour in `v0.15`).
///
/// > Although `contextvars` are preserved for async Python functions, synchronous functions will
/// unfortunately fail to resolve them when called within the Rust future. This is because the
/// function is being called from a Rust thread, not inside an actual Python coroutine context.
/// > unfortunately fail to resolve them when called within the Rust future. This is because the
/// > function is being called from a Rust thread, not inside an actual Python coroutine context.
/// >
/// > As a workaround, you can get the `contextvars` from the current task locals using
/// [`get_current_locals`] and [`TaskLocals::context`](`crate::TaskLocals::context`), then wrap your
/// synchronous function in a call to `contextvars.Context.run`. This will set the context, call the
/// synchronous function, and restore the previous context when it returns or raises an exception.
/// > [`get_current_locals`] and [`TaskLocals::context`](`crate::TaskLocals::context`), then wrap your
/// > synchronous function in a call to `contextvars.Context.run`. This will set the context, call the
/// > synchronous function, and restore the previous context when it returns or raises an exception.
///
/// # Arguments
/// * `py` - PyO3 GIL guard
Expand Down Expand Up @@ -412,13 +414,13 @@ where
/// via [`into_future`] (new behaviour in `v0.15`).
///
/// > Although `contextvars` are preserved for async Python functions, synchronous functions will
/// unfortunately fail to resolve them when called within the Rust future. This is because the
/// function is being called from a Rust thread, not inside an actual Python coroutine context.
/// > unfortunately fail to resolve them when called within the Rust future. This is because the
/// > function is being called from a Rust thread, not inside an actual Python coroutine context.
/// >
/// > As a workaround, you can get the `contextvars` from the current task locals using
/// [`get_current_locals`] and [`TaskLocals::context`](`crate::TaskLocals::context`), then wrap your
/// synchronous function in a call to `contextvars.Context.run`. This will set the context, call the
/// synchronous function, and restore the previous context when it returns or raises an exception.
/// > [`get_current_locals`] and [`TaskLocals::context`](`crate::TaskLocals::context`), then wrap your
/// > synchronous function in a call to `contextvars.Context.run`. This will set the context, call the
/// > synchronous function, and restore the previous context when it returns or raises an exception.
///
/// # Arguments
/// * `py` - The current PyO3 GIL guard
Expand Down Expand Up @@ -573,8 +575,8 @@ pub fn into_future(
/// # fn main() {}
/// ```
#[cfg(feature = "unstable-streams")]
pub fn into_stream_v1<'p>(
gen: Bound<'p, PyAny>,
pub fn into_stream_v1(
gen: Bound<'_, PyAny>,
) -> PyResult<impl futures::Stream<Item = PyResult<PyObject>> + 'static> {
generic::into_stream_v1::<AsyncStdRuntime>(gen)
}
Expand Down Expand Up @@ -633,9 +635,9 @@ pub fn into_stream_v1<'p>(
/// # fn main() {}
/// ```
#[cfg(feature = "unstable-streams")]
pub fn into_stream_with_locals_v1<'p>(
pub fn into_stream_with_locals_v1(
locals: TaskLocals,
gen: Bound<'p, PyAny>,
gen: Bound<'_, PyAny>,
) -> PyResult<impl futures::Stream<Item = PyResult<PyObject>> + 'static> {
generic::into_stream_with_locals_v1::<AsyncStdRuntime>(locals, gen)
}
Expand Down Expand Up @@ -694,9 +696,9 @@ pub fn into_stream_with_locals_v1<'p>(
/// # fn main() {}
/// ```
#[cfg(feature = "unstable-streams")]
pub fn into_stream_with_locals_v2<'p>(
pub fn into_stream_with_locals_v2(
locals: TaskLocals,
gen: Bound<'p, PyAny>,
gen: Bound<'_, PyAny>,
) -> PyResult<impl futures::Stream<Item = PyObject> + 'static> {
generic::into_stream_with_locals_v2::<AsyncStdRuntime>(locals, gen)
}
Expand Down Expand Up @@ -751,8 +753,8 @@ pub fn into_stream_with_locals_v2<'p>(
/// # fn main() {}
/// ```
#[cfg(feature = "unstable-streams")]
pub fn into_stream_v2<'p>(
gen: Bound<'p, PyAny>,
pub fn into_stream_v2(
gen: Bound<'_, PyAny>,
) -> PyResult<impl futures::Stream<Item = PyObject> + 'static> {
generic::into_stream_v2::<AsyncStdRuntime>(gen)
}
Loading

0 comments on commit 0eb883a

Please sign in to comment.