@@ -251,8 +251,24 @@ where
251251
252252/// Convert a Rust Future into a Python awaitable
253253///
254+ /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`,
255+ /// the Rust future will be cancelled as well (new behaviour in `v0.15`).
256+ ///
257+ /// Python `contextvars` are preserved when calling async Python functions within the Rust future
258+ /// via [`into_future`] (new behaviour in `v0.15`).
259+ ///
260+ /// > Although `contextvars` are preserved for async Python functions, synchronous functions will
261+ /// unfortunately fail to resolve them when called within the Rust future. This is because the
262+ /// function is being called from a Rust thread, not inside an actual Python coroutine context.
263+ /// >
264+ /// > As a workaround, you can get the `contextvars` from the current task locals using
265+ /// [`get_current_locals`] and [`TaskLocals::context`](`crate::TaskLocals::context`), then wrap your
266+ /// synchronous function in a call to `contextvars.Context.run`. This will set the context, call the
267+ /// synchronous function, and restore the previous context when it returns or raises an exception.
268+ ///
254269/// # Arguments
255- /// * `event_loop` - The Python event loop that the awaitable should be attached to
270+ /// * `py` - PyO3 GIL guard
271+ /// * `locals` - The task locals for the given future
256272/// * `fut` - The Rust future to be converted
257273///
258274/// # Examples
@@ -330,6 +346,21 @@ where
330346
331347/// Convert a Rust Future into a Python awaitable
332348///
349+ /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`,
350+ /// the Rust future will be cancelled as well (new behaviour in `v0.15`).
351+ ///
352+ /// Python `contextvars` are preserved when calling async Python functions within the Rust future
353+ /// via [`into_future`] (new behaviour in `v0.15`).
354+ ///
355+ /// > Although `contextvars` are preserved for async Python functions, synchronous functions will
356+ /// unfortunately fail to resolve them when called within the Rust future. This is because the
357+ /// function is being called from a Rust thread, not inside an actual Python coroutine context.
358+ /// >
359+ /// > As a workaround, you can get the `contextvars` from the current task locals using
360+ /// [`get_current_locals`] and [`TaskLocals::context`](`crate::TaskLocals::context`), then wrap your
361+ /// synchronous function in a call to `contextvars.Context.run`. This will set the context, call the
362+ /// synchronous function, and restore the previous context when it returns or raises an exception.
363+ ///
333364/// # Arguments
334365/// * `py` - The current PyO3 GIL guard
335366/// * `fut` - The Rust future to be converted
@@ -457,8 +488,24 @@ where
457488
458489/// Convert a `!Send` Rust Future into a Python awaitable
459490///
491+ /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`,
492+ /// the Rust future will be cancelled as well (new behaviour in `v0.15`).
493+ ///
494+ /// Python `contextvars` are preserved when calling async Python functions within the Rust future
495+ /// via [`into_future`] (new behaviour in `v0.15`).
496+ ///
497+ /// > Although `contextvars` are preserved for async Python functions, synchronous functions will
498+ /// unfortunately fail to resolve them when called within the Rust future. This is because the
499+ /// function is being called from a Rust thread, not inside an actual Python coroutine context.
500+ /// >
501+ /// > As a workaround, you can get the `contextvars` from the current task locals using
502+ /// [`get_current_locals`] and [`TaskLocals::context`](`crate::TaskLocals::context`), then wrap your
503+ /// synchronous function in a call to `contextvars.Context.run`. This will set the context, call the
504+ /// synchronous function, and restore the previous context when it returns or raises an exception.
505+ ///
460506/// # Arguments
461- /// * `event_loop` - The Python event loop that the awaitable should be attached to
507+ /// * `py` - PyO3 GIL guard
508+ /// * `locals` - The task locals for the given future
462509/// * `fut` - The Rust future to be converted
463510///
464511/// # Examples
@@ -570,6 +617,21 @@ where
570617
571618/// Convert a `!Send` Rust Future into a Python awaitable
572619///
620+ /// If the `asyncio.Future` returned by this conversion is cancelled via `asyncio.Future.cancel`,
621+ /// the Rust future will be cancelled as well (new behaviour in `v0.15`).
622+ ///
623+ /// Python `contextvars` are preserved when calling async Python functions within the Rust future
624+ /// via [`into_future`] (new behaviour in `v0.15`).
625+ ///
626+ /// > Although `contextvars` are preserved for async Python functions, synchronous functions will
627+ /// unfortunately fail to resolve them when called within the Rust future. This is because the
628+ /// function is being called from a Rust thread, not inside an actual Python coroutine context.
629+ /// >
630+ /// > As a workaround, you can get the `contextvars` from the current task locals using
631+ /// [`get_current_locals`] and [`TaskLocals::context`](`crate::TaskLocals::context`), then wrap your
632+ /// synchronous function in a call to `contextvars.Context.run`. This will set the context, call the
633+ /// synchronous function, and restore the previous context when it returns or raises an exception.
634+ ///
573635/// # Arguments
574636/// * `py` - The current PyO3 GIL guard
575637/// * `fut` - The Rust future to be converted
0 commit comments