From ffa957e855ea5a5c4934fea6231c3d1a7bcc4cb4 Mon Sep 17 00:00:00 2001 From: Gyubong Date: Thu, 28 Mar 2024 10:26:20 +0900 Subject: [PATCH 1/5] Migration pyo3 to 0.21 --- Cargo.toml | 8 +- README.md | 8 +- pyo3-asyncio-macros/Cargo.toml | 2 +- pytests/test_async_std_asyncio.rs | 6 +- pytests/test_race_condition_regression.rs | 2 +- pytests/tokio_asyncio/mod.rs | 6 +- src/async_std.rs | 58 ++++++----- src/generic.rs | 115 ++++++++++++---------- src/lib.rs | 79 +++++++-------- src/tokio.rs | 50 +++++----- 10 files changed, 178 insertions(+), 156 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7427320..16df8da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 "] readme = "README.md" keywords = ["pyo3", "python", "ffi", "async", "asyncio"] @@ -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-asyncio-macros = { path = "pyo3-asyncio-macros", version = "=0.20.0", optional = true } +pyo3 = "0.21" +pyo3-asyncio-macros = { path = "pyo3-asyncio-macros", version = "=0.21.0", optional = true } [dev-dependencies] -pyo3 = { version = "0.20", features = ["macros"] } +pyo3 = { version = "0.21", features = ["macros"] } [dependencies.async-std] version = "1.12" diff --git a/README.md b/README.md index cd6cdb3..09166c0 100644 --- a/README.md +++ b/README.md @@ -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> { pyo3_asyncio::async_std::future_into_py(py, async { async_std::task::sleep(std::time::Duration::from_secs(1)).await; Ok(()) @@ -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> { pyo3_asyncio::tokio::future_into_py(py, async { tokio::time::sleep(std::time::Duration::from_secs(1)).await; Ok(()) @@ -289,7 +289,7 @@ async fn rust_sleep() { } #[pyfunction] -fn call_rust_sleep(py: Python) -> PyResult<&PyAny> { +fn call_rust_sleep(py: Python) -> PyResult> { pyo3_asyncio::async_std::future_into_py(py, async move { rust_sleep().await; Ok(()) @@ -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> { pyo3_asyncio::tokio::future_into_py(py, async { tokio::time::sleep(std::time::Duration::from_secs(1)).await; Ok(()) diff --git a/pyo3-asyncio-macros/Cargo.toml b/pyo3-asyncio-macros/Cargo.toml index 1398887..1fd3047 100644 --- a/pyo3-asyncio-macros/Cargo.toml +++ b/pyo3-asyncio-macros/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "pyo3-asyncio-macros" description = "Proc Macro Attributes for PyO3 Asyncio" -version = "0.20.0" +version = "0.21.0" authors = ["Andrew J Westlake "] readme = "../README.md" keywords = ["pyo3", "python", "ffi", "async", "asyncio"] diff --git a/pytests/test_async_std_asyncio.rs b/pytests/test_async_std_asyncio.rs index 9139c06..903e5e8 100644 --- a/pytests/test_async_std_asyncio.rs +++ b/pytests/test_async_std_asyncio.rs @@ -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) -> PyResult> { let secs = secs.extract()?; pyo3_asyncio::async_std::future_into_py(py, async move { @@ -258,7 +258,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> { pyo3_asyncio::async_std::future_into_py(py, async move { async_std::task::sleep(Duration::from_millis(500)).await; Ok(()) @@ -305,7 +305,7 @@ 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> { 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()?) diff --git a/pytests/test_race_condition_regression.rs b/pytests/test_race_condition_regression.rs index d2e6b9e..e1550d0 100644 --- a/pytests/test_race_condition_regression.rs +++ b/pytests/test_race_condition_regression.rs @@ -1,7 +1,7 @@ use pyo3::{prelude::*, wrap_pyfunction}; #[pyfunction] -fn sleep<'p>(py: Python<'p>, secs: &'p PyAny) -> PyResult<&'p PyAny> { +fn sleep<'p>(py: Python<'p>, secs: Bound) -> PyResult> { let secs = secs.extract()?; pyo3_asyncio::async_std::future_into_py(py, async move { diff --git a/pytests/tokio_asyncio/mod.rs b/pytests/tokio_asyncio/mod.rs index f8a14ee..e42895a 100644 --- a/pytests/tokio_asyncio/mod.rs +++ b/pytests/tokio_asyncio/mod.rs @@ -17,7 +17,7 @@ use futures::{StreamExt, TryStreamExt}; use crate::common; #[pyfunction] -fn sleep<'p>(py: Python<'p>, secs: &'p PyAny) -> PyResult<&'p PyAny> { +fn sleep<'p>(py: Python<'p>, secs: Bound) -> PyResult> { let secs = secs.extract()?; pyo3_asyncio::tokio::future_into_py(py, async move { @@ -233,7 +233,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> { pyo3_asyncio::tokio::future_into_py(py, async move { tokio::time::sleep(Duration::from_millis(500)).await; Ok(()) @@ -280,7 +280,7 @@ fn test_multiple_asyncio_run() -> PyResult<()> { fn cvars_mod(_py: Python, m: &PyModule) -> PyResult<()> { #![allow(deprecated)] #[pyfunction] - fn async_callback(py: Python, callback: PyObject) -> PyResult<&PyAny> { + fn async_callback(py: Python, callback: PyObject) -> PyResult> { pyo3_asyncio::tokio::future_into_py(py, async move { Python::with_gil(|py| pyo3_asyncio::tokio::into_future(callback.as_ref(py).call0()?))? .await?; diff --git a/src/async_std.rs b/src/async_std.rs index c8d0861..c86d2f3 100644 --- a/src/async_std.rs +++ b/src/async_std.rs @@ -144,7 +144,7 @@ where /// This function first checks if the runtime has a task-local reference to the Python event loop. /// If not, it calls [`get_running_loop`](`crate::get_running_loop`) to get the event loop /// associated with the current OS thread. -pub fn get_current_loop(py: Python) -> PyResult<&PyAny> { +pub fn get_current_loop(py: Python) -> PyResult> { generic::get_current_loop::(py) } @@ -174,7 +174,7 @@ pub fn get_current_locals(py: Python) -> PyResult { /// # pyo3::prepare_freethreaded_python(); /// # /// # Python::with_gil(|py| -> PyResult<()> { -/// # let event_loop = py.import("asyncio")?.call_method0("new_event_loop")?; +/// # let event_loop = py.import_bound("asyncio")?.call_method0("new_event_loop")?; /// pyo3_asyncio::async_std::run_until_complete(event_loop, async move { /// async_std::task::sleep(Duration::from_secs(1)).await; /// Ok(()) @@ -182,7 +182,7 @@ pub fn get_current_locals(py: Python) -> PyResult { /// # Ok(()) /// # }).unwrap(); /// ``` -pub fn run_until_complete(event_loop: &PyAny, fut: F) -> PyResult +pub fn run_until_complete(event_loop: Bound, fut: F) -> PyResult where F: Future> + Send + 'static, T: Send + Sync + 'static, @@ -258,7 +258,7 @@ where /// /// /// Awaitable sleep function /// #[pyfunction] -/// fn sleep_for<'p>(py: Python<'p>, secs: &'p PyAny) -> PyResult<&'p PyAny> { +/// fn sleep_for<'p>(py: Python<'p>, secs: Bound<'p, PyAny>) -> PyResult> { /// let secs = secs.extract()?; /// pyo3_asyncio::async_std::future_into_py_with_locals( /// py, @@ -270,7 +270,11 @@ where /// ) /// } /// ``` -pub fn future_into_py_with_locals(py: Python, locals: TaskLocals, fut: F) -> PyResult<&PyAny> +pub fn future_into_py_with_locals( + py: Python, + locals: TaskLocals, + fut: F, +) -> PyResult> where F: Future> + Send + 'static, T: IntoPy, @@ -308,7 +312,7 @@ where /// /// /// Awaitable sleep function /// #[pyfunction] -/// fn sleep_for<'p>(py: Python<'p>, secs: &'p PyAny) -> PyResult<&'p PyAny> { +/// fn sleep_for<'p>(py: Python<'p>, secs: Bound<'p, PyAny>) -> PyResult> { /// let secs = secs.extract()?; /// pyo3_asyncio::async_std::future_into_py(py, async move { /// async_std::task::sleep(Duration::from_secs(secs)).await; @@ -316,7 +320,7 @@ where /// }) /// } /// ``` -pub fn future_into_py(py: Python, fut: F) -> PyResult<&PyAny> +pub fn future_into_py(py: Python, fut: F) -> PyResult> where F: Future> + Send + 'static, T: IntoPy, @@ -355,7 +359,7 @@ where /// /// /// Awaitable non-send sleep function /// #[pyfunction] -/// fn sleep_for(py: Python, secs: u64) -> PyResult<&PyAny> { +/// fn sleep_for(py: Python, secs: u64) -> PyResult> { /// // Rc is non-send so it cannot be passed into pyo3_asyncio::async_std::future_into_py /// let secs = Rc::new(secs); /// Ok(pyo3_asyncio::async_std::local_future_into_py_with_locals( @@ -391,7 +395,7 @@ pub fn local_future_into_py_with_locals( py: Python, locals: TaskLocals, fut: F, -) -> PyResult<&PyAny> +) -> PyResult> where F: Future> + 'static, T: IntoPy, @@ -429,7 +433,7 @@ where /// /// /// Awaitable non-send sleep function /// #[pyfunction] -/// fn sleep_for(py: Python, secs: u64) -> PyResult<&PyAny> { +/// fn sleep_for(py: Python, secs: u64) -> PyResult> { /// // Rc is non-send so it cannot be passed into pyo3_asyncio::async_std::future_into_py /// let secs = Rc::new(secs); /// pyo3_asyncio::async_std::local_future_into_py(py, async move { @@ -457,7 +461,7 @@ where note = "Questionable whether these conversions have real-world utility (see https://github.com/awestlake87/pyo3-asyncio/issues/59#issuecomment-1008038497 and let me know if you disagree!)" )] #[allow(deprecated)] -pub fn local_future_into_py(py: Python, fut: F) -> PyResult<&PyAny> +pub fn local_future_into_py(py: Python, fut: F) -> PyResult> where F: Future> + 'static, T: IntoPy, @@ -492,7 +496,7 @@ where /// async fn py_sleep(seconds: f32) -> PyResult<()> { /// let test_mod = Python::with_gil(|py| -> PyResult { /// Ok( -/// PyModule::from_code( +/// PyModule::from_code_bound( /// py, /// PYTHON_CODE, /// "test_into_future/test_mod.py", @@ -506,14 +510,16 @@ where /// pyo3_asyncio::async_std::into_future( /// test_mod /// .call_method1(py, "py_sleep", (seconds.into_py(py),))? -/// .as_ref(py), +/// .into_bound(py), /// ) /// })? /// .await?; /// Ok(()) /// } /// ``` -pub fn into_future(awaitable: &PyAny) -> PyResult> + Send> { +pub fn into_future( + awaitable: Bound, +) -> PyResult> + Send> { generic::into_future::(awaitable) } @@ -544,7 +550,7 @@ pub fn into_future(awaitable: &PyAny) -> PyResult PyResult<()> { /// let stream = Python::with_gil(|py| { -/// let test_mod = PyModule::from_code( +/// let test_mod = PyModule::from_code_bound( /// py, /// TEST_MOD, /// "test_rust_coroutine/test_mod.py", @@ -555,7 +561,7 @@ pub fn into_future(awaitable: &PyAny) -> PyResult PyResult { Ok(item?.as_ref(py).extract()?) })) +/// .map(|item| Python::with_gil(|py| -> PyResult { Ok(item?.bind(py).extract()?) })) /// .try_collect::>() /// .await?; /// @@ -568,7 +574,7 @@ pub fn into_future(awaitable: &PyAny) -> PyResult( - gen: &'p PyAny, + gen: Bound, ) -> PyResult> + 'static> { generic::into_stream_v1::(gen) } @@ -601,7 +607,7 @@ pub fn into_stream_v1<'p>( /// # #[pyo3_asyncio::async_std::main] /// # async fn main() -> PyResult<()> { /// let stream = Python::with_gil(|py| { -/// let test_mod = PyModule::from_code( +/// let test_mod = PyModule::from_code_bound( /// py, /// TEST_MOD, /// "test_rust_coroutine/test_mod.py", @@ -615,7 +621,7 @@ pub fn into_stream_v1<'p>( /// })?; /// /// let vals = stream -/// .map(|item| Python::with_gil(|py| -> PyResult { Ok(item?.as_ref(py).extract()?) })) +/// .map(|item| Python::with_gil(|py| -> PyResult { Ok(item?.bind(py).extract()?) })) /// .try_collect::>() /// .await?; /// @@ -629,7 +635,7 @@ pub fn into_stream_v1<'p>( #[cfg(feature = "unstable-streams")] pub fn into_stream_with_locals_v1<'p>( locals: TaskLocals, - gen: &'p PyAny, + gen: Bound, ) -> PyResult> + 'static> { generic::into_stream_with_locals_v1::(locals, gen) } @@ -662,7 +668,7 @@ pub fn into_stream_with_locals_v1<'p>( /// # #[pyo3_asyncio::async_std::main] /// # async fn main() -> PyResult<()> { /// let stream = Python::with_gil(|py| { -/// let test_mod = PyModule::from_code( +/// let test_mod = PyModule::from_code_bound( /// py, /// TEST_MOD, /// "test_rust_coroutine/test_mod.py", @@ -676,7 +682,7 @@ pub fn into_stream_with_locals_v1<'p>( /// })?; /// /// let vals = stream -/// .map(|item| Python::with_gil(|py| -> PyResult { Ok(item.as_ref(py).extract()?) })) +/// .map(|item| Python::with_gil(|py| -> PyResult { Ok(item.bind(py).extract()?) })) /// .try_collect::>() /// .await?; /// @@ -690,7 +696,7 @@ pub fn into_stream_with_locals_v1<'p>( #[cfg(feature = "unstable-streams")] pub fn into_stream_with_locals_v2<'p>( locals: TaskLocals, - gen: &'p PyAny, + gen: Bound<'p, PyAny>, ) -> PyResult + 'static> { generic::into_stream_with_locals_v2::(locals, gen) } @@ -722,7 +728,7 @@ pub fn into_stream_with_locals_v2<'p>( /// # #[pyo3_asyncio::async_std::main] /// # async fn main() -> PyResult<()> { /// let stream = Python::with_gil(|py| { -/// let test_mod = PyModule::from_code( +/// let test_mod = PyModule::from_code_bound( /// py, /// TEST_MOD, /// "test_rust_coroutine/test_mod.py", @@ -733,7 +739,7 @@ pub fn into_stream_with_locals_v2<'p>( /// })?; /// /// let vals = stream -/// .map(|item| Python::with_gil(|py| -> PyResult { Ok(item.as_ref(py).extract()?) })) +/// .map(|item| Python::with_gil(|py| -> PyResult { Ok(item.bind(py).extract()?) })) /// .try_collect::>() /// .await?; /// @@ -746,7 +752,7 @@ pub fn into_stream_with_locals_v2<'p>( /// ``` #[cfg(feature = "unstable-streams")] pub fn into_stream_v2<'p>( - gen: &'p PyAny, + gen: Bound<'p, PyAny>, ) -> PyResult + 'static> { generic::into_stream_v2::(gen) } diff --git a/src/generic.rs b/src/generic.rs index 3afc462..471104b 100644 --- a/src/generic.rs +++ b/src/generic.rs @@ -87,12 +87,12 @@ pub trait LocalContextExt: Runtime { /// This function first checks if the runtime has a task-local reference to the Python event loop. /// If not, it calls [`get_running_loop`](crate::get_running_loop`) to get the event loop associated /// with the current OS thread. -pub fn get_current_loop(py: Python) -> PyResult<&PyAny> +pub fn get_current_loop(py: Python) -> PyResult> where R: ContextExt, { if let Some(locals) = R::get_task_locals() { - Ok(locals.event_loop.into_ref(py)) + Ok(locals.event_loop.into_bound(py)) } else { get_running_loop(py) } @@ -181,7 +181,7 @@ where /// # use pyo3::prelude::*; /// # /// # Python::with_gil(|py| -> PyResult<()> { -/// # let event_loop = py.import("asyncio")?.call_method0("new_event_loop")?; +/// # let event_loop = py.import_bound("asyncio")?.call_method0("new_event_loop")?; /// # #[cfg(feature = "tokio-runtime")] /// pyo3_asyncio::generic::run_until_complete::(event_loop, async move { /// tokio::time::sleep(Duration::from_secs(1)).await; @@ -190,7 +190,7 @@ where /// # Ok(()) /// # }).unwrap(); /// ``` -pub fn run_until_complete(event_loop: &PyAny, fut: F) -> PyResult +pub fn run_until_complete(event_loop: Bound, fut: F) -> PyResult where R: Runtime + ContextExt, F: Future> + Send + 'static, @@ -201,7 +201,7 @@ where let result_rx = Arc::clone(&result_tx); let coro = future_into_py_with_locals::( py, - TaskLocals::new(event_loop).copy_context(py)?, + TaskLocals::new(event_loop.clone()).copy_context(py)?, async move { let val = fut.await?; if let Ok(mut result) = result_tx.lock() { @@ -306,15 +306,15 @@ where { let event_loop = asyncio(py)?.call_method0("new_event_loop")?; - let result = run_until_complete::(event_loop, fut); + let result = run_until_complete::(event_loop.clone(), fut); close(event_loop)?; result } -fn cancelled(future: &PyAny) -> PyResult { - future.getattr("cancelled")?.call0()?.is_true() +fn cancelled(future: Bound) -> PyResult { + future.getattr("cancelled")?.call0()?.is_truthy() } #[pyclass] @@ -322,7 +322,12 @@ struct CheckedCompletor; #[pymethods] impl CheckedCompletor { - fn __call__(&self, future: &PyAny, complete: &PyAny, value: &PyAny) -> PyResult<()> { + fn __call__( + &self, + future: Bound, + complete: Bound, + value: Bound, + ) -> PyResult<()> { if cancelled(future)? { return Ok(()); } @@ -333,9 +338,13 @@ impl CheckedCompletor { } } -fn set_result(event_loop: &PyAny, future: &PyAny, result: PyResult) -> PyResult<()> { +fn set_result( + event_loop: Bound, + future: Bound, + result: PyResult, +) -> PyResult<()> { let py = event_loop.py(); - let none = py.None().into_ref(py); + let none = py.None().into_bound(py); let (complete, val) = match result { Ok(val) => (future.getattr("set_result")?, val.into_py(py)), @@ -430,7 +439,7 @@ fn set_result(event_loop: &PyAny, future: &PyAny, result: PyResult) -> /// async fn py_sleep(seconds: f32) -> PyResult<()> { /// let test_mod = Python::with_gil(|py| -> PyResult { /// Ok( -/// PyModule::from_code( +/// PyModule::from_code_bound( /// py, /// PYTHON_CODE, /// "test_into_future/test_mod.py", @@ -444,7 +453,7 @@ fn set_result(event_loop: &PyAny, future: &PyAny, result: PyResult) -> /// pyo3_asyncio::generic::into_future::( /// test_mod /// .call_method1(py, "py_sleep", (seconds.into_py(py),))? -/// .as_ref(py), +/// .into_bound(py), /// ) /// })? /// .await?; @@ -452,7 +461,7 @@ fn set_result(event_loop: &PyAny, future: &PyAny, result: PyResult) -> /// } /// ``` pub fn into_future( - awaitable: &PyAny, + awaitable: Bound, ) -> PyResult> + Send> where R: Runtime + ContextExt, @@ -551,7 +560,7 @@ where /// /// /// Awaitable sleep function /// #[pyfunction] -/// fn sleep_for<'p>(py: Python<'p>, secs: &'p PyAny) -> PyResult<&'p PyAny> { +/// fn sleep_for<'p>(py: Python<'p>, secs: Bound) -> PyResult> { /// let secs = secs.extract()?; /// pyo3_asyncio::generic::future_into_py_with_locals::( /// py, @@ -567,7 +576,7 @@ pub fn future_into_py_with_locals( py: Python, locals: TaskLocals, fut: F, -) -> PyResult<&PyAny> +) -> PyResult> where R: Runtime + ContextExt, F: Future> + Send + 'static, @@ -575,7 +584,7 @@ where { let (cancel_tx, cancel_rx) = oneshot::channel(); - let py_fut = create_future(locals.event_loop.clone().into_ref(py))?; + let py_fut = create_future(locals.event_loop.clone().into_bound(py))?; py_fut.call_method1( "add_done_callback", (PyDoneCallback { @@ -583,7 +592,7 @@ where },), )?; - let future_tx1 = PyObject::from(py_fut); + let future_tx1 = PyObject::from(py_fut.clone()); let future_tx2 = future_tx1.clone(); R::spawn(async move { @@ -597,7 +606,7 @@ where .await; Python::with_gil(move |py| { - if cancelled(future_tx1.as_ref(py)) + if cancelled(future_tx1.clone().into_bound(py)) .map_err(dump_err(py)) .unwrap_or(false) { @@ -606,7 +615,7 @@ where let _ = set_result( locals2.event_loop(py), - future_tx1.as_ref(py), + future_tx1.into_bound(py), result.map(|val| val.into_py(py)), ) .map_err(dump_err(py)); @@ -616,7 +625,7 @@ where { if e.is_panic() { Python::with_gil(move |py| { - if cancelled(future_tx2.as_ref(py)) + if cancelled(future_tx2.clone().into_bound(py)) .map_err(dump_err(py)) .unwrap_or(false) { @@ -628,8 +637,8 @@ where get_panic_message(&e.into_panic()) ); let _ = set_result( - locals.event_loop.as_ref(py), - future_tx2.as_ref(py), + locals.event_loop.into_bound(py), + future_tx2.into_bound(py), Err(RustPanic::new_err(panic_message)), ) .map_err(dump_err(py)); @@ -721,7 +730,7 @@ struct PyDoneCallback { #[pymethods] impl PyDoneCallback { - pub fn __call__(&mut self, fut: &PyAny) -> PyResult<()> { + pub fn __call__(&mut self, fut: Bound) -> PyResult<()> { let py = fut.py(); if cancelled(fut).map_err(dump_err(py)).unwrap_or(false) { @@ -822,7 +831,7 @@ impl PyDoneCallback { /// /// /// Awaitable sleep function /// #[pyfunction] -/// fn sleep_for<'p>(py: Python<'p>, secs: &'p PyAny) -> PyResult<&'p PyAny> { +/// fn sleep_for<'p>(py: Python<'p>, secs: Bound<'p, PyAny>) -> PyResult> { /// let secs = secs.extract()?; /// pyo3_asyncio::generic::future_into_py::(py, async move { /// MyCustomRuntime::sleep(Duration::from_secs(secs)).await; @@ -830,7 +839,7 @@ impl PyDoneCallback { /// }) /// } /// ``` -pub fn future_into_py(py: Python, fut: F) -> PyResult<&PyAny> +pub fn future_into_py(py: Python, fut: F) -> PyResult> where R: Runtime + ContextExt, F: Future> + Send + 'static, @@ -949,7 +958,7 @@ where /// /// /// Awaitable sleep function /// #[pyfunction] -/// fn sleep_for(py: Python, secs: u64) -> PyResult<&PyAny> { +/// fn sleep_for(py: Python, secs: u64) -> PyResult> { /// // Rc is !Send so it cannot be passed into pyo3_asyncio::generic::future_into_py /// let secs = Rc::new(secs); /// @@ -971,7 +980,7 @@ pub fn local_future_into_py_with_locals( py: Python, locals: TaskLocals, fut: F, -) -> PyResult<&PyAny> +) -> PyResult> where R: Runtime + SpawnLocalExt + LocalContextExt, F: Future> + 'static, @@ -979,7 +988,7 @@ where { let (cancel_tx, cancel_rx) = oneshot::channel(); - let py_fut = create_future(locals.event_loop.clone().into_ref(py))?; + let py_fut = create_future(locals.event_loop.clone().into_bound(py))?; py_fut.call_method1( "add_done_callback", (PyDoneCallback { @@ -987,7 +996,7 @@ where },), )?; - let future_tx1 = PyObject::from(py_fut); + let future_tx1 = PyObject::from(py_fut.clone()); let future_tx2 = future_tx1.clone(); R::spawn_local(async move { @@ -1001,7 +1010,7 @@ where .await; Python::with_gil(move |py| { - if cancelled(future_tx1.as_ref(py)) + if cancelled(future_tx1.clone().into_bound(py)) .map_err(dump_err(py)) .unwrap_or(false) { @@ -1009,8 +1018,8 @@ where } let _ = set_result( - locals2.event_loop.as_ref(py), - future_tx1.as_ref(py), + locals2.event_loop.into_bound(py), + future_tx1.into_bound(py), result.map(|val| val.into_py(py)), ) .map_err(dump_err(py)); @@ -1020,7 +1029,7 @@ where { if e.is_panic() { Python::with_gil(move |py| { - if cancelled(future_tx2.as_ref(py)) + if cancelled(future_tx2.clone().into_bound(py)) .map_err(dump_err(py)) .unwrap_or(false) { @@ -1032,8 +1041,8 @@ where get_panic_message(&e.into_panic()) ); let _ = set_result( - locals.event_loop.as_ref(py), - future_tx2.as_ref(py), + locals.event_loop.into_bound(py), + future_tx2.into_bound(py), Err(RustPanic::new_err(panic_message)), ) .map_err(dump_err(py)); @@ -1153,7 +1162,7 @@ where /// /// /// Awaitable sleep function /// #[pyfunction] -/// fn sleep_for(py: Python, secs: u64) -> PyResult<&PyAny> { +/// fn sleep_for(py: Python, secs: u64) -> PyResult> { /// // Rc is !Send so it cannot be passed into pyo3_asyncio::generic::future_into_py /// let secs = Rc::new(secs); /// @@ -1168,7 +1177,7 @@ where note = "Questionable whether these conversions have real-world utility (see https://github.com/awestlake87/pyo3-asyncio/issues/59#issuecomment-1008038497 and let me know if you disagree!)" )] #[allow(deprecated)] -pub fn local_future_into_py(py: Python, fut: F) -> PyResult<&PyAny> +pub fn local_future_into_py(py: Python, fut: F) -> PyResult> where R: Runtime + ContextExt + SpawnLocalExt + LocalContextExt, F: Future> + 'static, @@ -1257,7 +1266,7 @@ where /// /// # async fn test_async_gen() -> PyResult<()> { /// let stream = Python::with_gil(|py| { -/// let test_mod = PyModule::from_code( +/// let test_mod = PyModule::from_code_bound( /// py, /// TEST_MOD, /// "test_rust_coroutine/test_mod.py", @@ -1271,7 +1280,7 @@ where /// })?; /// /// let vals = stream -/// .map(|item| Python::with_gil(|py| -> PyResult { Ok(item?.as_ref(py).extract()?) })) +/// .map(|item| Python::with_gil(|py| -> PyResult { Ok(item?.bind(py).extract()?) })) /// .try_collect::>() /// .await?; /// @@ -1283,7 +1292,7 @@ where #[cfg(feature = "unstable-streams")] pub fn into_stream_with_locals_v1<'p, R>( locals: TaskLocals, - gen: &'p PyAny, + gen: Bound, ) -> PyResult> + 'static> where R: Runtime, @@ -1294,7 +1303,7 @@ where R::spawn(async move { loop { let fut = Python::with_gil(|py| -> PyResult<_> { - into_future_with_locals(&locals, anext.as_ref(py).call0()?) + into_future_with_locals(&locals, anext.bind(py).call0()?) }); let item = match fut { Ok(fut) => match fut.await { @@ -1404,7 +1413,7 @@ where /// /// # async fn test_async_gen() -> PyResult<()> { /// let stream = Python::with_gil(|py| { -/// let test_mod = PyModule::from_code( +/// let test_mod = PyModule::from_code_bound( /// py, /// TEST_MOD, /// "test_rust_coroutine/test_mod.py", @@ -1415,7 +1424,7 @@ where /// })?; /// /// let vals = stream -/// .map(|item| Python::with_gil(|py| -> PyResult { Ok(item?.as_ref(py).extract()?) })) +/// .map(|item| Python::with_gil(|py| -> PyResult { Ok(item?.bind(py).extract()?) })) /// .try_collect::>() /// .await?; /// @@ -1426,7 +1435,7 @@ where /// ``` #[cfg(feature = "unstable-streams")] pub fn into_stream_v1<'p, R>( - gen: &'p PyAny, + gen: Bound, ) -> PyResult> + 'static> where R: Runtime + ContextExt, @@ -1611,7 +1620,7 @@ async def forward(gen, sender): /// /// # async fn test_async_gen() -> PyResult<()> { /// let stream = Python::with_gil(|py| { -/// let test_mod = PyModule::from_code( +/// let test_mod = PyModule::from_code_bound( /// py, /// TEST_MOD, /// "test_rust_coroutine/test_mod.py", @@ -1625,7 +1634,7 @@ async def forward(gen, sender): /// })?; /// /// let vals = stream -/// .map(|item| Python::with_gil(|py| -> PyResult { Ok(item.as_ref(py).extract()?) })) +/// .map(|item| Python::with_gil(|py| -> PyResult { Ok(item.bind(py).extract()?) })) /// .try_collect::>() /// .await?; /// @@ -1637,7 +1646,7 @@ async def forward(gen, sender): #[cfg(feature = "unstable-streams")] pub fn into_stream_with_locals_v2<'p, R>( locals: TaskLocals, - gen: &'p PyAny, + gen: Bound<'_, PyAny>, ) -> PyResult + 'static> where R: Runtime + ContextExt, @@ -1646,7 +1655,7 @@ where let py = gen.py(); let glue = GLUE_MOD .get_or_try_init(|| -> PyResult { - Ok(PyModule::from_code( + Ok(PyModule::from_code_bound( py, STREAM_GLUE, "pyo3_asyncio/pyo3_asyncio_glue.py", @@ -1654,7 +1663,7 @@ where )? .into()) })? - .as_ref(py); + .bind(py); let (tx, rx) = mpsc::channel(10); @@ -1759,7 +1768,7 @@ where /// /// # async fn test_async_gen() -> PyResult<()> { /// let stream = Python::with_gil(|py| { -/// let test_mod = PyModule::from_code( +/// let test_mod = PyModule::from_code_bound( /// py, /// TEST_MOD, /// "test_rust_coroutine/test_mod.py", @@ -1770,7 +1779,7 @@ where /// })?; /// /// let vals = stream -/// .map(|item| Python::with_gil(|py| -> PyResult { Ok(item.as_ref(py).extract()?) })) +/// .map(|item| Python::with_gil(|py| -> PyResult { Ok(item.bind(py).extract()?) })) /// .try_collect::>() /// .await?; /// @@ -1781,7 +1790,7 @@ where /// ``` #[cfg(feature = "unstable-streams")] pub fn into_stream_v2<'p, R>( - gen: &'p PyAny, + gen: Bound, ) -> PyResult + 'static> where R: Runtime + ContextExt, diff --git a/src/lib.rs b/src/lib.rs index 1570522..233a2e3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -88,7 +88,7 @@ //! //! # #[cfg(feature = "tokio-runtime")] //! #[pyfunction] -//! fn sleep(py: Python) -> PyResult<&PyAny> { +//! fn sleep(py: Python) -> PyResult> { //! // Construct the task locals structure with the current running loop and context //! let locals = pyo3_asyncio::TaskLocals::with_running_loop(py)?.copy_context(py)?; //! @@ -100,7 +100,7 @@ //! // event loop from earlier. //! pyo3_asyncio::into_future_with_locals( //! &locals, -//! py.import("asyncio")?.call_method1("sleep", (1,))? +//! py.import_bound("asyncio")?.call_method1("sleep", (1,))? //! ) //! })?; //! @@ -155,7 +155,7 @@ //! //! # #[cfg(feature = "tokio-runtime")] //! #[pyfunction] -//! fn sleep(py: Python) -> PyResult<&PyAny> { +//! fn sleep(py: Python) -> PyResult> { //! // get the current event loop through task-local data //! // OR `asyncio.get_running_loop` and `contextvars.copy_context` //! let locals = pyo3_asyncio::tokio::get_current_locals(py)?; @@ -169,7 +169,7 @@ //! pyo3_asyncio::into_future_with_locals( //! // Now we can get the current locals through task-local data //! &pyo3_asyncio::tokio::get_current_locals(py)?, -//! py.import("asyncio")?.call_method1("sleep", (1,))? +//! py.import_bound("asyncio")?.call_method1("sleep", (1,))? //! ) //! })?; //! @@ -182,7 +182,7 @@ //! //! # #[cfg(feature = "tokio-runtime")] //! #[pyfunction] -//! fn wrap_sleep(py: Python) -> PyResult<&PyAny> { +//! fn wrap_sleep(py: Python) -> PyResult> { //! // get the current event loop through task-local data //! // OR `asyncio.get_running_loop` and `contextvars.copy_context` //! let locals = pyo3_asyncio::tokio::get_current_locals(py)?; @@ -240,11 +240,11 @@ //! //! # #[cfg(feature = "tokio-runtime")] //! #[pyfunction] -//! fn sleep(py: Python) -> PyResult<&PyAny> { +//! fn sleep(py: Python) -> PyResult> { //! pyo3_asyncio::tokio::future_into_py(py, async move { //! let py_sleep = Python::with_gil(|py| { //! pyo3_asyncio::tokio::into_future( -//! py.import("asyncio")?.call_method1("sleep", (1,))? +//! py.import_bound("asyncio")?.call_method1("sleep", (1,))? //! ) //! })?; //! @@ -256,7 +256,7 @@ //! //! # #[cfg(feature = "tokio-runtime")] //! #[pyfunction] -//! fn wrap_sleep(py: Python) -> PyResult<&PyAny> { +//! fn wrap_sleep(py: Python) -> PyResult> { //! pyo3_asyncio::tokio::future_into_py(py, async move { //! let py_sleep = Python::with_gil(|py| { //! pyo3_asyncio::tokio::into_future(sleep(py)?) @@ -363,8 +363,8 @@ pub mod err; pub mod generic; #[pymodule] -fn pyo3_asyncio(py: Python, m: &PyModule) -> PyResult<()> { - m.add("RustPanic", py.get_type::())?; +fn pyo3_asyncio(py: Python, m: Bound) -> PyResult<()> { + m.add("RustPanic", py.get_type_bound::())?; Ok(()) } @@ -408,20 +408,20 @@ static CONTEXTVARS: OnceCell = OnceCell::new(); static ENSURE_FUTURE: OnceCell = OnceCell::new(); static GET_RUNNING_LOOP: OnceCell = OnceCell::new(); -fn ensure_future<'p>(py: Python<'p>, awaitable: &'p PyAny) -> PyResult<&'p PyAny> { +fn ensure_future<'p>(py: Python<'p>, awaitable: Bound<'p, PyAny>) -> PyResult> { ENSURE_FUTURE .get_or_try_init(|| -> PyResult { Ok(asyncio(py)?.getattr("ensure_future")?.into()) })? - .as_ref(py) + .bind(py) .call1((awaitable,)) } -fn create_future(event_loop: &PyAny) -> PyResult<&PyAny> { +fn create_future(event_loop: Bound) -> PyResult> { event_loop.call_method0("create_future") } -fn close(event_loop: &PyAny) -> PyResult<()> { +fn close(event_loop: Bound) -> PyResult<()> { event_loop.call_method1( "run_until_complete", (event_loop.call_method0("shutdown_asyncgens")?,), @@ -440,16 +440,16 @@ fn close(event_loop: &PyAny) -> PyResult<()> { Ok(()) } -fn asyncio(py: Python) -> PyResult<&PyAny> { +fn asyncio(py: Python) -> PyResult> { ASYNCIO - .get_or_try_init(|| Ok(py.import("asyncio")?.into())) - .map(|asyncio| asyncio.as_ref(py)) + .get_or_try_init(|| Ok(py.import_bound("asyncio")?.into())) + .map(|asyncio| asyncio.clone().into_bound(py)) } /// Get a reference to the Python Event Loop from Rust /// /// Equivalent to `asyncio.get_running_loop()` in Python 3.7+. -pub fn get_running_loop(py: Python) -> PyResult<&PyAny> { +pub fn get_running_loop(py: Python) -> PyResult> { // Ideally should call get_running_loop, but calls get_event_loop for compatibility when // get_running_loop is not available. GET_RUNNING_LOOP @@ -458,17 +458,18 @@ pub fn get_running_loop(py: Python) -> PyResult<&PyAny> { Ok(asyncio.getattr("get_running_loop")?.into()) })? - .as_ref(py) + .bind(py) .call0() } -fn contextvars(py: Python) -> PyResult<&PyAny> { +fn contextvars(py: Python) -> PyResult> { Ok(CONTEXTVARS - .get_or_try_init(|| py.import("contextvars").map(|m| m.into()))? - .as_ref(py)) + .get_or_try_init(|| py.import_bound("contextvars").map(|m| m.into()))? + .clone() + .into_bound(py)) } -fn copy_context(py: Python) -> PyResult<&PyAny> { +fn copy_context(py: Python) -> PyResult> { contextvars(py)?.call_method0("copy_context") } @@ -483,9 +484,9 @@ pub struct TaskLocals { impl TaskLocals { /// At a minimum, TaskLocals must store the event loop. - pub fn new(event_loop: &PyAny) -> Self { + pub fn new(event_loop: Bound) -> Self { Self { - event_loop: event_loop.into(), + event_loop: event_loop.clone().into(), context: event_loop.py().None(), } } @@ -496,7 +497,7 @@ impl TaskLocals { } /// Manually provide the contextvars for the current task. - pub fn with_context(self, context: &PyAny) -> Self { + pub fn with_context(self, context: Bound) -> Self { Self { context: context.into(), ..self @@ -509,13 +510,13 @@ impl TaskLocals { } /// Get a reference to the event loop - pub fn event_loop<'p>(&self, py: Python<'p>) -> &'p PyAny { - self.event_loop.clone().into_ref(py) + pub fn event_loop<'p>(&self, py: Python<'p>) -> Bound<'p, PyAny> { + self.event_loop.clone().into_bound(py) } /// Get a reference to the python context - pub fn context<'p>(&self, py: Python<'p>) -> &'p PyAny { - self.context.clone().into_ref(py) + pub fn context<'p>(&self, py: Python<'p>) -> Bound<'p, PyAny> { + self.context.clone().into_bound(py) } } @@ -527,7 +528,7 @@ struct PyTaskCompleter { #[pymethods] impl PyTaskCompleter { #[pyo3(signature = (task))] - pub fn __call__(&mut self, task: &PyAny) -> PyResult<()> { + pub fn __call__(&mut self, task: Bound) -> PyResult<()> { debug_assert!(task.call_method0("done")?.extract()?); let result = match task.call_method0("result") { Ok(val) => Ok(val.into()), @@ -558,7 +559,7 @@ struct PyEnsureFuture { impl PyEnsureFuture { pub fn __call__(&mut self) -> PyResult<()> { Python::with_gil(|py| { - let task = ensure_future(py, self.awaitable.as_ref(py))?; + let task = ensure_future(py, self.awaitable.clone().into_bound(py))?; let on_complete = PyTaskCompleter { tx: self.tx.take() }; task.call_method1("add_done_callback", (on_complete,))?; @@ -568,16 +569,16 @@ impl PyEnsureFuture { } fn call_soon_threadsafe( - event_loop: &PyAny, - context: &PyAny, + event_loop: Bound, + context: Bound, args: impl IntoPy>, ) -> PyResult<()> { let py = event_loop.py(); - let kwargs = PyDict::new(py); + let kwargs = PyDict::new_bound(py); kwargs.set_item("context", context)?; - event_loop.call_method("call_soon_threadsafe", args, Some(kwargs))?; + event_loop.call_method("call_soon_threadsafe", args, Some(&kwargs))?; Ok(()) } @@ -625,7 +626,7 @@ fn call_soon_threadsafe( /// &pyo3_asyncio::tokio::get_current_locals(py)?, /// test_mod /// .call_method1(py, "py_sleep", (seconds.into_py(py),))? -/// .as_ref(py), +/// .into_bound(py), /// ) /// })? /// .await?; @@ -634,7 +635,7 @@ fn call_soon_threadsafe( /// ``` pub fn into_future_with_locals( locals: &TaskLocals, - awaitable: &PyAny, + awaitable: Bound, ) -> PyResult> + Send> { let py = awaitable.py(); let (tx, rx) = oneshot::channel(); @@ -652,7 +653,7 @@ pub fn into_future_with_locals( match rx.await { Ok(item) => item, Err(_) => Python::with_gil(|py| { - Err(PyErr::from_value( + Err(PyErr::from_value_bound( asyncio(py)?.call_method0("CancelledError")?, )) }), diff --git a/src/tokio.rs b/src/tokio.rs index 804b2a6..05ed074 100644 --- a/src/tokio.rs +++ b/src/tokio.rs @@ -158,7 +158,7 @@ where /// This function first checks if the runtime has a task-local reference to the Python event loop. /// If not, it calls [`get_running_loop`](`crate::get_running_loop`) to get the event loop /// associated with the current OS thread. -pub fn get_current_loop(py: Python) -> PyResult<&PyAny> { +pub fn get_current_loop(py: Python) -> PyResult> { generic::get_current_loop::(py) } @@ -219,7 +219,7 @@ fn multi_thread() -> Builder { /// # /// # pyo3::prepare_freethreaded_python(); /// # Python::with_gil(|py| -> PyResult<()> { -/// # let event_loop = py.import("asyncio")?.call_method0("new_event_loop")?; +/// # let event_loop = py.import_bound("asyncio")?.call_method0("new_event_loop")?; /// pyo3_asyncio::tokio::run_until_complete(event_loop, async move { /// tokio::time::sleep(Duration::from_secs(1)).await; /// Ok(()) @@ -227,7 +227,7 @@ fn multi_thread() -> Builder { /// # Ok(()) /// # }).unwrap(); /// ``` -pub fn run_until_complete(event_loop: &PyAny, fut: F) -> PyResult +pub fn run_until_complete(event_loop: Bound, fut: F) -> PyResult where F: Future> + Send + 'static, T: Send + Sync + 'static, @@ -300,7 +300,7 @@ where /// /// /// Awaitable sleep function /// #[pyfunction] -/// fn sleep_for<'p>(py: Python<'p>, secs: &'p PyAny) -> PyResult<&'p PyAny> { +/// fn sleep_for<'p>(py: Python<'p>, secs: Bound<'p, PyAny>) -> PyResult> { /// let secs = secs.extract()?; /// pyo3_asyncio::tokio::future_into_py_with_locals( /// py, @@ -312,7 +312,11 @@ where /// ) /// } /// ``` -pub fn future_into_py_with_locals(py: Python, locals: TaskLocals, fut: F) -> PyResult<&PyAny> +pub fn future_into_py_with_locals( + py: Python, + locals: TaskLocals, + fut: F, +) -> PyResult> where F: Future> + Send + 'static, T: IntoPy, @@ -350,7 +354,7 @@ where /// /// /// Awaitable sleep function /// #[pyfunction] -/// fn sleep_for<'p>(py: Python<'p>, secs: &'p PyAny) -> PyResult<&'p PyAny> { +/// fn sleep_for<'p>(py: Python<'p>, secs: Bound<'p, PyAny>) -> PyResult> { /// let secs = secs.extract()?; /// pyo3_asyncio::tokio::future_into_py(py, async move { /// tokio::time::sleep(Duration::from_secs(secs)).await; @@ -358,7 +362,7 @@ where /// }) /// } /// ``` -pub fn future_into_py(py: Python, fut: F) -> PyResult<&PyAny> +pub fn future_into_py(py: Python, fut: F) -> PyResult> where F: Future> + Send + 'static, T: IntoPy, @@ -397,7 +401,7 @@ where /// /// /// Awaitable non-send sleep function /// #[pyfunction] -/// fn sleep_for(py: Python, secs: u64) -> PyResult<&PyAny> { +/// fn sleep_for(py: Python, secs: u64) -> PyResult> { /// // Rc is non-send so it cannot be passed into pyo3_asyncio::tokio::future_into_py /// let secs = Rc::new(secs); /// @@ -449,7 +453,7 @@ pub fn local_future_into_py_with_locals( py: Python, locals: TaskLocals, fut: F, -) -> PyResult<&PyAny> +) -> PyResult> where F: Future> + 'static, T: IntoPy, @@ -487,7 +491,7 @@ where /// /// /// Awaitable non-send sleep function /// #[pyfunction] -/// fn sleep_for(py: Python, secs: u64) -> PyResult<&PyAny> { +/// fn sleep_for(py: Python, secs: u64) -> PyResult> { /// // Rc is non-send so it cannot be passed into pyo3_asyncio::tokio::future_into_py /// let secs = Rc::new(secs); /// pyo3_asyncio::tokio::local_future_into_py(py, async move { @@ -530,7 +534,7 @@ where note = "Questionable whether these conversions have real-world utility (see https://github.com/awestlake87/pyo3-asyncio/issues/59#issuecomment-1008038497 and let me know if you disagree!)" )] #[allow(deprecated)] -pub fn local_future_into_py(py: Python, fut: F) -> PyResult<&PyAny> +pub fn local_future_into_py(py: Python, fut: F) -> PyResult> where F: Future> + 'static, T: IntoPy, @@ -565,7 +569,7 @@ where /// async fn py_sleep(seconds: f32) -> PyResult<()> { /// let test_mod = Python::with_gil(|py| -> PyResult { /// Ok( -/// PyModule::from_code( +/// PyModule::from_code_bound( /// py, /// PYTHON_CODE, /// "test_into_future/test_mod.py", @@ -579,14 +583,16 @@ where /// pyo3_asyncio::tokio::into_future( /// test_mod /// .call_method1(py, "py_sleep", (seconds.into_py(py),))? -/// .as_ref(py), +/// .into_bound(py), /// ) /// })? /// .await?; /// Ok(()) /// } /// ``` -pub fn into_future(awaitable: &PyAny) -> PyResult> + Send> { +pub fn into_future( + awaitable: Bound, +) -> PyResult> + Send> { generic::into_future::(awaitable) } @@ -618,7 +624,7 @@ pub fn into_future(awaitable: &PyAny) -> PyResult PyResult<()> { /// let stream = Python::with_gil(|py| { -/// let test_mod = PyModule::from_code( +/// let test_mod = PyModule::from_code_bound( /// py, /// TEST_MOD, /// "test_rust_coroutine/test_mod.py", @@ -646,7 +652,7 @@ pub fn into_future(awaitable: &PyAny) -> PyResult( locals: TaskLocals, - gen: &'p PyAny, + gen: Bound, ) -> PyResult> + 'static> { generic::into_stream_with_locals_v1::(locals, gen) } @@ -678,7 +684,7 @@ pub fn into_stream_with_locals_v1<'p>( /// # #[pyo3_asyncio::tokio::main] /// # async fn main() -> PyResult<()> { /// let stream = Python::with_gil(|py| { -/// let test_mod = PyModule::from_code( +/// let test_mod = PyModule::from_code_bound( /// py, /// TEST_MOD, /// "test_rust_coroutine/test_mod.py", @@ -702,7 +708,7 @@ pub fn into_stream_with_locals_v1<'p>( /// ``` #[cfg(feature = "unstable-streams")] pub fn into_stream_v1<'p>( - gen: &'p PyAny, + gen: Bound, ) -> PyResult> + 'static> { generic::into_stream_v1::(gen) } @@ -735,7 +741,7 @@ pub fn into_stream_v1<'p>( /// # #[pyo3_asyncio::tokio::main] /// # async fn main() -> PyResult<()> { /// let stream = Python::with_gil(|py| { -/// let test_mod = PyModule::from_code( +/// let test_mod = PyModule::from_code_bound( /// py, /// TEST_MOD, /// "test_rust_coroutine/test_mod.py", @@ -763,7 +769,7 @@ pub fn into_stream_v1<'p>( #[cfg(feature = "unstable-streams")] pub fn into_stream_with_locals_v2<'p>( locals: TaskLocals, - gen: &'p PyAny, + gen: Bound, ) -> PyResult + 'static> { generic::into_stream_with_locals_v2::(locals, gen) } @@ -795,7 +801,7 @@ pub fn into_stream_with_locals_v2<'p>( /// # #[pyo3_asyncio::tokio::main] /// # async fn main() -> PyResult<()> { /// let stream = Python::with_gil(|py| { -/// let test_mod = PyModule::from_code( +/// let test_mod = PyModule::from_code_bound( /// py, /// TEST_MOD, /// "test_rust_coroutine/test_mod.py", @@ -819,7 +825,7 @@ pub fn into_stream_with_locals_v2<'p>( /// ``` #[cfg(feature = "unstable-streams")] pub fn into_stream_v2<'p>( - gen: &'p PyAny, + gen: Bound, ) -> PyResult + 'static> { generic::into_stream_v2::(gen) } From 896e72d1aff61c48beb27dcdf8b2f7718b2f8dd1 Mon Sep 17 00:00:00 2001 From: Gyubong Date: Thu, 28 Mar 2024 10:34:27 +0900 Subject: [PATCH 2/5] Fix deprecated methods of README --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 09166c0..9eff528 100644 --- a/README.md +++ b/README.md @@ -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),))?) })?; @@ -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),))?) })?; @@ -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 @@ -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( @@ -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 @@ -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::() .unwrap() @@ -569,7 +569,7 @@ To make things a bit easier, I decided to keep most of the old API alongside the ### Upgrading Your Code to 0.14 1. Fix PyO3 0.14 initialization. - - PyO3 0.14 feature gated its automatic initialization behaviour behind "auto-initialize". You can either enable the "auto-initialize" behaviour in your project or add a call to `pyo3::prepare_freethreaded_python()` to the start of your program. + - PyO3 0.14 feature gated its automatic initialization behavior behind "auto-initialize". You can either enable the "auto-initialize" behavior in your project or add a call to `pyo3::prepare_freethreaded_python()` to the start of your program. - If you're using the `#[pyo3_asyncio::::main]` proc macro attributes, then you can skip this step. `#[pyo3_asyncio::::main]` will call `pyo3::prepare_freethreaded_python()` at the start regardless of your project's "auto-initialize" feature. 2. Fix the tokio initialization. @@ -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,))?; @@ -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(),), ) @@ -646,7 +646,7 @@ To make things a bit easier, I decided to keep most of the old API alongside the There have been a few changes to the API in order to support proper cancellation from Python and the `contextvars` module. - Any instance of `cancellable_future_into_py` and `local_cancellable_future_into_py` conversions can be replaced with their`future_into_py` and `local_future_into_py` counterparts. - > Cancellation support became the default behaviour in 0.15. + > Cancellation support became the default behavior in 0.15. - Instances of `*_with_loop` conversions should be replaced with the newer `*_with_locals` conversions. ```rust no_run From a6ea8f845a1090d6531b414b6d8806723cc26f56 Mon Sep 17 00:00:00 2001 From: Gyubong Date: Thu, 28 Mar 2024 10:40:56 +0900 Subject: [PATCH 3/5] Fix typos --- README.md | 4 ++-- src/async_std.rs | 16 ++++++++-------- src/generic.rs | 16 ++++++++-------- src/tokio.rs | 16 ++++++++-------- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 9eff528..ae11863 100644 --- a/README.md +++ b/README.md @@ -396,7 +396,7 @@ RuntimeError: no running event loop ``` What's happening here is that we are calling `rust_sleep` _before_ the future is -actually running on the event loop created by `asyncio.run`. This is counter-intuitive, but expected behaviour, and unfortunately there doesn't seem to be a good way of solving this problem within PyO3 Asyncio itself. +actually running on the event loop created by `asyncio.run`. This is counter-intuitive, but expected behavior, and unfortunately there doesn't seem to be a good way of solving this problem within PyO3 Asyncio itself. However, we can make this example work with a simple workaround: @@ -541,7 +541,7 @@ fn main() -> PyResult<()> { So what's changed from `v0.13` to `v0.14`? -Well, a lot actually. There were some pretty major flaws in the initialization behaviour of `v0.13`. While it would have been nicer to address these issues without changing the public API, I decided it'd be better to break some of the old API rather than completely change the underlying behaviour of the existing functions. I realize this is going to be a bit of a headache, so hopefully this section will help you through it. +Well, a lot actually. There were some pretty major flaws in the initialization behavior of `v0.13`. While it would have been nicer to address these issues without changing the public API, I decided it'd be better to break some of the old API rather than completely change the underlying behavior of the existing functions. I realize this is going to be a bit of a headache, so hopefully this section will help you through it. To make things a bit easier, I decided to keep most of the old API alongside the new one (with some deprecation warnings to encourage users to move away from it). It should be possible to use the `v0.13` API alongside the newer `v0.14` API, which should allow you to upgrade your application piecemeal rather than all at once. diff --git a/src/async_std.rs b/src/async_std.rs index c86d2f3..e4947f7 100644 --- a/src/async_std.rs +++ b/src/async_std.rs @@ -230,10 +230,10 @@ where /// Convert a Rust Future into a Python awaitable /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behaviour in `v0.15`). +/// the Rust future will be cancelled as well (new behavior in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behaviour in `v0.15`). +/// via [`into_future`] (new behavior 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 @@ -285,10 +285,10 @@ where /// Convert a Rust Future into a Python awaitable /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behaviour in `v0.15`). +/// the Rust future will be cancelled as well (new behavior in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behaviour in `v0.15`). +/// via [`into_future`] (new behavior 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 @@ -331,10 +331,10 @@ where /// Convert a `!Send` Rust Future into a Python awaitable /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behaviour in `v0.15`). +/// the Rust future will be cancelled as well (new behavior in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behaviour in `v0.15`). +/// via [`into_future`] (new behavior 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 @@ -406,10 +406,10 @@ where /// Convert a `!Send` Rust Future into a Python awaitable /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behaviour in `v0.15`). +/// the Rust future will be cancelled as well (new behavior in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behaviour in `v0.15`). +/// via [`into_future`] (new behavior 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 diff --git a/src/generic.rs b/src/generic.rs index 471104b..f3aa07a 100644 --- a/src/generic.rs +++ b/src/generic.rs @@ -472,10 +472,10 @@ where /// Convert a Rust Future into a Python awaitable with a generic runtime /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behaviour in `v0.15`). +/// the Rust future will be cancelled as well (new behavior in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behaviour in `v0.15`). +/// via [`into_future`] (new behavior 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 @@ -744,10 +744,10 @@ impl PyDoneCallback { /// Convert a Rust Future into a Python awaitable with a generic runtime /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behaviour in `v0.15`). +/// the Rust future will be cancelled as well (new behavior in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behaviour in `v0.15`). +/// via [`into_future`] (new behavior 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 @@ -852,10 +852,10 @@ where /// specification of task locals. /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behaviour in `v0.15`). +/// the Rust future will be cancelled as well (new behavior in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behaviour in `v0.15`). +/// via [`into_future`] (new behavior 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 @@ -1057,10 +1057,10 @@ where /// Convert a `!Send` Rust Future into a Python awaitable with a generic runtime /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behaviour in `v0.15`). +/// the Rust future will be cancelled as well (new behavior in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behaviour in `v0.15`). +/// via [`into_future`] (new behavior 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 diff --git a/src/tokio.rs b/src/tokio.rs index 05ed074..5a6eb5f 100644 --- a/src/tokio.rs +++ b/src/tokio.rs @@ -272,10 +272,10 @@ where /// Convert a Rust Future into a Python awaitable /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behaviour in `v0.15`). +/// the Rust future will be cancelled as well (new behavior in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behaviour in `v0.15`). +/// via [`into_future`] (new behavior 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 @@ -327,10 +327,10 @@ where /// Convert a Rust Future into a Python awaitable /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behaviour in `v0.15`). +/// the Rust future will be cancelled as well (new behavior in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behaviour in `v0.15`). +/// via [`into_future`] (new behavior 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 @@ -373,10 +373,10 @@ where /// Convert a `!Send` Rust Future into a Python awaitable /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behaviour in `v0.15`). +/// the Rust future will be cancelled as well (new behavior in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behaviour in `v0.15`). +/// via [`into_future`] (new behavior 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 @@ -464,10 +464,10 @@ where /// Convert a `!Send` Rust Future into a Python awaitable /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behaviour in `v0.15`). +/// the Rust future will be cancelled as well (new behavior in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behaviour in `v0.15`). +/// via [`into_future`] (new behavior 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 From df5f8920e2149db5e42404c075bac16d3e04a7e2 Mon Sep 17 00:00:00 2001 From: Gyubong Date: Thu, 28 Mar 2024 11:57:04 +0900 Subject: [PATCH 4/5] Reverted words misunderstood as typo --- Code-of-Conduct.md | 12 ++++++------ README.md | 8 ++++---- src/async_std.rs | 16 ++++++++-------- src/generic.rs | 16 ++++++++-------- src/tokio.rs | 16 ++++++++-------- 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/Code-of-Conduct.md b/Code-of-Conduct.md index c06c625..d571769 100644 --- a/Code-of-Conduct.md +++ b/Code-of-Conduct.md @@ -11,7 +11,7 @@ appearance, race, religion, or sexual identity and orientation. ## Our Standards -Examples of behavior that contributes to creating a positive environment +Examples of behaviour that contributes to creating a positive environment include: * Using welcoming and inclusive language @@ -20,7 +20,7 @@ include: * Focusing on what is best for the community * Showing empathy towards other community members -Examples of unacceptable behavior by participants include: +Examples of unacceptable behaviour by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances @@ -34,13 +34,13 @@ Examples of unacceptable behavior by participants include: ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. +behaviour and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behaviour. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, +permanently any contributor for other behaviours that they deem inappropriate, threatening, offensive, or harmful. ## Scope @@ -54,7 +54,7 @@ further defined and clarified by project maintainers. ## Enforcement -Instances of abusive, harassing, or otherwise unacceptable behavior may be +Instances of abusive, harassing, or otherwise unacceptable behaviour may be reported by contacting the project team. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is diff --git a/README.md b/README.md index ae11863..f7655e6 100644 --- a/README.md +++ b/README.md @@ -396,7 +396,7 @@ RuntimeError: no running event loop ``` What's happening here is that we are calling `rust_sleep` _before_ the future is -actually running on the event loop created by `asyncio.run`. This is counter-intuitive, but expected behavior, and unfortunately there doesn't seem to be a good way of solving this problem within PyO3 Asyncio itself. +actually running on the event loop created by `asyncio.run`. This is counter-intuitive, but expected behaviour, and unfortunately there doesn't seem to be a good way of solving this problem within PyO3 Asyncio itself. However, we can make this example work with a simple workaround: @@ -541,7 +541,7 @@ fn main() -> PyResult<()> { So what's changed from `v0.13` to `v0.14`? -Well, a lot actually. There were some pretty major flaws in the initialization behavior of `v0.13`. While it would have been nicer to address these issues without changing the public API, I decided it'd be better to break some of the old API rather than completely change the underlying behavior of the existing functions. I realize this is going to be a bit of a headache, so hopefully this section will help you through it. +Well, a lot actually. There were some pretty major flaws in the initialization behaviour of `v0.13`. While it would have been nicer to address these issues without changing the public API, I decided it'd be better to break some of the old API rather than completely change the underlying behaviour of the existing functions. I realize this is going to be a bit of a headache, so hopefully this section will help you through it. To make things a bit easier, I decided to keep most of the old API alongside the new one (with some deprecation warnings to encourage users to move away from it). It should be possible to use the `v0.13` API alongside the newer `v0.14` API, which should allow you to upgrade your application piecemeal rather than all at once. @@ -569,7 +569,7 @@ To make things a bit easier, I decided to keep most of the old API alongside the ### Upgrading Your Code to 0.14 1. Fix PyO3 0.14 initialization. - - PyO3 0.14 feature gated its automatic initialization behavior behind "auto-initialize". You can either enable the "auto-initialize" behavior in your project or add a call to `pyo3::prepare_freethreaded_python()` to the start of your program. + - PyO3 0.14 feature gated its automatic initialization behaviour behind "auto-initialize". You can either enable the "auto-initialize" behaviour in your project or add a call to `pyo3::prepare_freethreaded_python()` to the start of your program. - If you're using the `#[pyo3_asyncio::::main]` proc macro attributes, then you can skip this step. `#[pyo3_asyncio::::main]` will call `pyo3::prepare_freethreaded_python()` at the start regardless of your project's "auto-initialize" feature. 2. Fix the tokio initialization. @@ -646,7 +646,7 @@ To make things a bit easier, I decided to keep most of the old API alongside the There have been a few changes to the API in order to support proper cancellation from Python and the `contextvars` module. - Any instance of `cancellable_future_into_py` and `local_cancellable_future_into_py` conversions can be replaced with their`future_into_py` and `local_future_into_py` counterparts. - > Cancellation support became the default behavior in 0.15. + > Cancellation support became the default behaviour in 0.15. - Instances of `*_with_loop` conversions should be replaced with the newer `*_with_locals` conversions. ```rust no_run diff --git a/src/async_std.rs b/src/async_std.rs index e4947f7..c86d2f3 100644 --- a/src/async_std.rs +++ b/src/async_std.rs @@ -230,10 +230,10 @@ where /// Convert a Rust Future into a Python awaitable /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behavior in `v0.15`). +/// the Rust future will be cancelled as well (new behaviour in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behavior in `v0.15`). +/// 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 @@ -285,10 +285,10 @@ where /// Convert a Rust Future into a Python awaitable /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behavior in `v0.15`). +/// the Rust future will be cancelled as well (new behaviour in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behavior in `v0.15`). +/// 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 @@ -331,10 +331,10 @@ where /// Convert a `!Send` Rust Future into a Python awaitable /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behavior in `v0.15`). +/// the Rust future will be cancelled as well (new behaviour in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behavior in `v0.15`). +/// 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 @@ -406,10 +406,10 @@ where /// Convert a `!Send` Rust Future into a Python awaitable /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behavior in `v0.15`). +/// the Rust future will be cancelled as well (new behaviour in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behavior in `v0.15`). +/// 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 diff --git a/src/generic.rs b/src/generic.rs index f3aa07a..471104b 100644 --- a/src/generic.rs +++ b/src/generic.rs @@ -472,10 +472,10 @@ where /// Convert a Rust Future into a Python awaitable with a generic runtime /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behavior in `v0.15`). +/// the Rust future will be cancelled as well (new behaviour in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behavior in `v0.15`). +/// 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 @@ -744,10 +744,10 @@ impl PyDoneCallback { /// Convert a Rust Future into a Python awaitable with a generic runtime /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behavior in `v0.15`). +/// the Rust future will be cancelled as well (new behaviour in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behavior in `v0.15`). +/// 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 @@ -852,10 +852,10 @@ where /// specification of task locals. /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behavior in `v0.15`). +/// the Rust future will be cancelled as well (new behaviour in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behavior in `v0.15`). +/// 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 @@ -1057,10 +1057,10 @@ where /// Convert a `!Send` Rust Future into a Python awaitable with a generic runtime /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behavior in `v0.15`). +/// the Rust future will be cancelled as well (new behaviour in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behavior in `v0.15`). +/// 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 diff --git a/src/tokio.rs b/src/tokio.rs index 5a6eb5f..05ed074 100644 --- a/src/tokio.rs +++ b/src/tokio.rs @@ -272,10 +272,10 @@ where /// Convert a Rust Future into a Python awaitable /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behavior in `v0.15`). +/// the Rust future will be cancelled as well (new behaviour in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behavior in `v0.15`). +/// 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 @@ -327,10 +327,10 @@ where /// Convert a Rust Future into a Python awaitable /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behavior in `v0.15`). +/// the Rust future will be cancelled as well (new behaviour in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behavior in `v0.15`). +/// 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 @@ -373,10 +373,10 @@ where /// Convert a `!Send` Rust Future into a Python awaitable /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behavior in `v0.15`). +/// the Rust future will be cancelled as well (new behaviour in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behavior in `v0.15`). +/// 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 @@ -464,10 +464,10 @@ where /// Convert a `!Send` Rust Future into a Python awaitable /// /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`, -/// the Rust future will be cancelled as well (new behavior in `v0.15`). +/// the Rust future will be cancelled as well (new behaviour in `v0.15`). /// /// Python `contextvars` are preserved when calling async Python functions within the Rust future -/// via [`into_future`] (new behavior in `v0.15`). +/// 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 From d1ec64076dd1b5c797db4b7b811f588466956d20 Mon Sep 17 00:00:00 2001 From: Gyubong Date: Mon, 29 Apr 2024 12:45:22 +0900 Subject: [PATCH 5/5] Reverted words misunderstood as typo --- Code-of-Conduct.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Code-of-Conduct.md b/Code-of-Conduct.md index d571769..c06c625 100644 --- a/Code-of-Conduct.md +++ b/Code-of-Conduct.md @@ -11,7 +11,7 @@ appearance, race, religion, or sexual identity and orientation. ## Our Standards -Examples of behaviour that contributes to creating a positive environment +Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language @@ -20,7 +20,7 @@ include: * Focusing on what is best for the community * Showing empathy towards other community members -Examples of unacceptable behaviour by participants include: +Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances @@ -34,13 +34,13 @@ Examples of unacceptable behaviour by participants include: ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable -behaviour and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behaviour. +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviours that they deem inappropriate, +permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope @@ -54,7 +54,7 @@ further defined and clarified by project maintainers. ## Enforcement -Instances of abusive, harassing, or otherwise unacceptable behaviour may be +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is