Skip to content

Commit cf5720d

Browse files
committed
add Python::try_attach
1 parent 12a1792 commit cf5720d

File tree

3 files changed

+14
-7
lines changed

3 files changed

+14
-7
lines changed

pytests/src/misc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fn hammer_gil_in_thread() -> LockHolder {
2424
// now the interpreter has shut down, so hammer the GIL. In buggy
2525
// versions of PyO3 this will cause a crash.
2626
loop {
27-
Python::attach(|_py| ());
27+
Python::try_attach(|_py| ());
2828
}
2929
});
3030
LockHolder { sender }

src/internal/state.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ impl AttachGuard {
6262
}
6363

6464
/// Variant of the above which will will return `None` if the interpreter cannot be attached to.
65-
#[cfg(any(not(Py_LIMITED_API), Py_3_11, test))] // see Python::try_attach
6665
pub(crate) fn try_acquire() -> Option<Self> {
6766
match ATTACH_COUNT.try_with(|c| c.get()) {
6867
Ok(i) if i > 0 => {

src/marker.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,9 @@ impl Python<'_> {
393393
/// - If the [`auto-initialize`] feature is not enabled and the Python interpreter is not
394394
/// initialized.
395395
///
396+
/// To avoid possible initialization or panics if calling in a context where the Python
397+
/// interpreter might be unavailable, consider using [`Python::try_attach`].
398+
///
396399
/// # Examples
397400
///
398401
/// ```
@@ -419,15 +422,20 @@ impl Python<'_> {
419422
f(guard.python())
420423
}
421424

422-
/// Variant of [`Python::attach`] which will do no work if the interpreter is in a
423-
/// state where it cannot be attached to:
425+
/// Variant of [`Python::attach`] which will return without attaching to the Python
426+
/// interpreter if the interpreter is in a state where it cannot be attached to:
424427
/// - in the middle of GC traversal
425428
/// - not initialized
429+
///
430+
/// Note that due to the nature of the underlying Python APIs used to implement this,
431+
/// the behavior is currently provided on a best-effort basis; it is expected that a
432+
/// future CPython version will introduce APIs which guarantee this behaviour. This
433+
/// function is still recommended for use in the meanwhile as it provides the best
434+
/// possible behaviour and should transparently change to an optimal implementation
435+
/// once such APIs are available.
426436
#[inline]
427437
#[track_caller]
428-
#[cfg(any(not(Py_LIMITED_API), Py_3_11, test))] // only used in buffer.rs for now, allow in test cfg for simplicity
429-
// TODO: make this API public?
430-
pub(crate) fn try_attach<F, R>(f: F) -> Option<R>
438+
pub fn try_attach<F, R>(f: F) -> Option<R>
431439
where
432440
F: for<'py> FnOnce(Python<'py>) -> R,
433441
{

0 commit comments

Comments
 (0)