Skip to content

Commit 7450e98

Browse files
deprecate GILProtected (#5285)
* deprecate `GILProtected` * newsfragment * Update guide/src/migration.md Co-authored-by: Bas Schoenmaeckers <7943856+bschoenmaeckers@users.noreply.github.com> * fixup warnings * fixup one more case * also deprecate in guide * skip doctest on free threaded --------- Co-authored-by: Bas Schoenmaeckers <7943856+bschoenmaeckers@users.noreply.github.com>
1 parent a52aee2 commit 7450e98

File tree

4 files changed

+53
-1
lines changed

4 files changed

+53
-1
lines changed

guide/src/free-threading.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ Python::attach(|py| {
337337

338338
### `GILProtected` is not exposed
339339

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

350350
```rust
351+
# #![allow(deprecated)]
351352
# fn main() {
352353
# #[cfg(not(Py_GIL_DISABLED))] {
353354
# use pyo3::prelude::*;

guide/src/migration.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ For a detailed list of all changes, see the [CHANGELOG](changelog.md).
77
### Rename of `Python::with_gil`, `Python::allow_threads`, and `pyo3::prepare_freethreaded_python`
88
<details open>
99
<summary><small>Click to expand</small></summary>
10+
1011
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.
1112
For this reason we chose to rename these to more modern terminology introduced in free-threading:
1213

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

19+
### Deprecation of `GILProtected`
20+
<details open>
21+
<summary><small>Click to expand</small></summary>
22+
23+
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).
24+
25+
Before:
26+
27+
```rust
28+
# #![allow(deprecated)]
29+
# use pyo3::prelude::*;
30+
# fn main() {
31+
# #[cfg(not(Py_GIL_DISABLED))] {
32+
use pyo3::sync::GILProtected;
33+
use std::cell::RefCell;
34+
# Python::attach(|py| {
35+
static NUMBERS: GILProtected<RefCell<Vec<i32>>> = GILProtected::new(RefCell::new(Vec::new()));
36+
Python::attach(|py| {
37+
NUMBERS.get(py).borrow_mut().push(42);
38+
});
39+
# })
40+
# }
41+
# }
42+
```
43+
44+
After:
45+
46+
```rust
47+
# use pyo3::prelude::*;
48+
use pyo3::sync::MutexExt;
49+
use std::sync::Mutex;
50+
# fn main() {
51+
# Python::attach(|py| {
52+
static NUMBERS: Mutex<Vec<i32>> = Mutex::new(Vec::new());
53+
Python::attach(|py| {
54+
NUMBERS.lock_py_attached(py).expect("no poisoning").push(42);
55+
});
56+
# })
57+
# }
58+
```
59+
</summary>
60+
1861
### `PyMemoryError` now maps to `io::ErrorKind::OutOfMemory` when converted to `io::Error`
1962
<details>
2063
<summary><small>Click to expand</small></summary>

newsfragments/5285.changed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Deprecate `GILProtected`.

src/sync.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use crate::PyVisit;
3333
/// Combining `GILProtected` with `RefCell` enables mutable access to static data:
3434
///
3535
/// ```
36+
/// # #![allow(deprecated)]
3637
/// # use pyo3::prelude::*;
3738
/// use pyo3::sync::GILProtected;
3839
/// use std::cell::RefCell;
@@ -43,11 +44,16 @@ use crate::PyVisit;
4344
/// NUMBERS.get(py).borrow_mut().push(42);
4445
/// });
4546
/// ```
47+
#[deprecated(
48+
since = "0.26.0",
49+
note = "Prefer an interior mutability primitive compatible with free-threaded Python, such as `Mutex` in combination with the `MutexExt` trait"
50+
)]
4651
#[cfg(not(Py_GIL_DISABLED))]
4752
pub struct GILProtected<T> {
4853
value: T,
4954
}
5055

56+
#[allow(deprecated)]
5157
#[cfg(not(Py_GIL_DISABLED))]
5258
impl<T> GILProtected<T> {
5359
/// Place the given value under the protection of the GIL.
@@ -66,6 +72,7 @@ impl<T> GILProtected<T> {
6672
}
6773
}
6874

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

0 commit comments

Comments
 (0)