Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion guide/src/free-threading.md
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ Python::attach(|py| {

### `GILProtected` is not exposed

[`GILProtected`] is a PyO3 type that allows mutable access to static data by
[`GILProtected`] is a (deprecated) PyO3 type that allows mutable access to static data by
leveraging the GIL to lock concurrent access from other threads. In
free-threaded Python there is no GIL, so you will need to replace this type with
some other form of locking. In many cases, a type from
Expand All @@ -348,6 +348,7 @@ be sufficient.
Before:

```rust
# #![allow(deprecated)]
# fn main() {
# #[cfg(not(Py_GIL_DISABLED))] {
# use pyo3::prelude::*;
Expand Down
43 changes: 43 additions & 0 deletions guide/src/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ For a detailed list of all changes, see the [CHANGELOG](changelog.md).
### Rename of `Python::with_gil`, `Python::allow_threads`, and `pyo3::prepare_freethreaded_python`
<details open>
<summary><small>Click to expand</small></summary>

The names for these APIs were created when the global interpreter lock (GIL) was mandatory. With the introduction of free-threading in Python 3.13 this is no longer the case, and the naming does not has no universal meaning anymore.
For this reason we chose to rename these to more modern terminology introduced in free-threading:

Expand All @@ -15,6 +16,48 @@ For this reason we chose to rename these to more modern terminology introduced i
- `pyo3::prepare_freethreaded_python` is now called `Python::initialize`.
</details>

### Deprecation of `GILProtected`
<details open>
<summary><small>Click to expand</small></summary>

As another cleanup related to concurrency primitives designed for a Python constrained by the GIL, the `GILProtected` type is now deprecated. Prefer to use concurrency primitives which are compatible with free-threaded Python, such as [`std::sync::Mutex`](https://doc.rust-lang.org/std/sync/struct.Mutex.html) (in combination with PyO3's [`MutexExt`]({{#PYO3_DOCS_URL}}/pyo3/sync/trait.MutexExt.html) trait).

Before:

```rust
# #![allow(deprecated)]
# use pyo3::prelude::*;
# fn main() {
# #[cfg(not(Py_GIL_DISABLED))] {
use pyo3::sync::GILProtected;
use std::cell::RefCell;
# Python::attach(|py| {
static NUMBERS: GILProtected<RefCell<Vec<i32>>> = GILProtected::new(RefCell::new(Vec::new()));
Python::attach(|py| {
NUMBERS.get(py).borrow_mut().push(42);
});
# })
# }
# }
```

After:

```rust
# use pyo3::prelude::*;
use pyo3::sync::MutexExt;
use std::sync::Mutex;
# fn main() {
# Python::attach(|py| {
static NUMBERS: Mutex<Vec<i32>> = Mutex::new(Vec::new());
Python::attach(|py| {
NUMBERS.lock_py_attached(py).expect("no poisoning").push(42);
});
# })
# }
```
</summary>

### `PyMemoryError` now maps to `io::ErrorKind::OutOfMemory` when converted to `io::Error`
<details>
<summary><small>Click to expand</small></summary>
Expand Down
1 change: 1 addition & 0 deletions newsfragments/5285.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Deprecate `GILProtected`.
7 changes: 7 additions & 0 deletions src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use crate::PyVisit;
/// Combining `GILProtected` with `RefCell` enables mutable access to static data:
///
/// ```
/// # #![allow(deprecated)]
/// # use pyo3::prelude::*;
/// use pyo3::sync::GILProtected;
/// use std::cell::RefCell;
Expand All @@ -43,11 +44,16 @@ use crate::PyVisit;
/// NUMBERS.get(py).borrow_mut().push(42);
/// });
/// ```
#[deprecated(
since = "0.26.0",
note = "Prefer an interior mutability primitive compatible with free-threaded Python, such as `Mutex` in combination with the `MutexExt` trait"
)]
#[cfg(not(Py_GIL_DISABLED))]
pub struct GILProtected<T> {
value: T,
}

#[allow(deprecated)]
#[cfg(not(Py_GIL_DISABLED))]
impl<T> GILProtected<T> {
/// Place the given value under the protection of the GIL.
Expand All @@ -66,6 +72,7 @@ impl<T> GILProtected<T> {
}
}

#[allow(deprecated)]
#[cfg(not(Py_GIL_DISABLED))]
unsafe impl<T> Sync for GILProtected<T> where T: Send {}

Expand Down
Loading