Skip to content

Commit 10152a7

Browse files
authored
feature gate PyCell (#4177)
* feature gate `PyCell` * feature gate `HasPyGilRef` completely * bump version
1 parent 57500d9 commit 10152a7

30 files changed

+220
-98
lines changed

Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "pyo3"
3-
version = "0.21.2"
3+
version = "0.22.0-dev"
44
description = "Bindings to Python interpreter"
55
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
66
readme = "README.md"
@@ -20,10 +20,10 @@ libc = "0.2.62"
2020
memoffset = "0.9"
2121

2222
# ffi bindings to the python interpreter, split into a separate crate so they can be used independently
23-
pyo3-ffi = { path = "pyo3-ffi", version = "=0.21.2" }
23+
pyo3-ffi = { path = "pyo3-ffi", version = "=0.22.0-dev" }
2424

2525
# support crates for macros feature
26-
pyo3-macros = { path = "pyo3-macros", version = "=0.21.2", optional = true }
26+
pyo3-macros = { path = "pyo3-macros", version = "=0.22.0-dev", optional = true }
2727
indoc = { version = "2.0.1", optional = true }
2828
unindent = { version = "0.2.1", optional = true }
2929

@@ -62,7 +62,7 @@ rayon = "1.6.1"
6262
futures = "0.3.28"
6363

6464
[build-dependencies]
65-
pyo3-build-config = { path = "pyo3-build-config", version = "=0.21.2", features = ["resolve-config"] }
65+
pyo3-build-config = { path = "pyo3-build-config", version = "=0.22.0-dev", features = ["resolve-config"] }
6666

6767
[features]
6868
default = ["macros"]
@@ -106,7 +106,7 @@ generate-import-lib = ["pyo3-ffi/generate-import-lib"]
106106
auto-initialize = []
107107

108108
# Allows use of the deprecated "GIL Refs" APIs.
109-
gil-refs = []
109+
gil-refs = ["pyo3-macros/gil-refs"]
110110

111111
# Enables `Clone`ing references to Python objects `Py<T>` which panics if the GIL is not held.
112112
py-clone = []

guide/src/class.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,6 +1307,7 @@ struct MyClass {
13071307
impl pyo3::types::DerefToPyAny for MyClass {}
13081308

13091309
# #[allow(deprecated)]
1310+
# #[cfg(feature = "gil-refs")]
13101311
unsafe impl pyo3::type_object::HasPyGilRef for MyClass {
13111312
type AsRefTarget = pyo3::PyCell<Self>;
13121313
}

guide/src/migration.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,7 +1609,7 @@ For more, see [the constructor section](class.md#constructor) of this guide.
16091609
<details>
16101610
<summary><small>Click to expand</small></summary>
16111611

1612-
PyO3 0.9 introduces [`PyCell`], which is a [`RefCell`]-like object wrapper
1612+
PyO3 0.9 introduces `PyCell`, which is a [`RefCell`]-like object wrapper
16131613
for ensuring Rust's rules regarding aliasing of references are upheld.
16141614
For more detail, see the
16151615
[Rust Book's section on Rust's rules of references](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#the-rules-of-references)
@@ -1788,7 +1788,6 @@ impl PySequenceProtocol for ByteSequence {
17881788

17891789
[`FromPyObject`]: {{#PYO3_DOCS_URL}}/pyo3/conversion/trait.FromPyObject.html
17901790
[`PyAny`]: {{#PYO3_DOCS_URL}}/pyo3/types/struct.PyAny.html
1791-
[`PyCell`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyCell.html
17921791
[`PyBorrowMutError`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyBorrowMutError.html
17931792
[`PyRef`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyRef.html
17941793
[`PyRefMut`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyRef.html

pyo3-build-config/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "pyo3-build-config"
3-
version = "0.21.2"
3+
version = "0.22.0-dev"
44
description = "Build configuration for the PyO3 ecosystem"
55
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
66
keywords = ["pyo3", "python", "cpython", "ffi"]

pyo3-ffi/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "pyo3-ffi"
3-
version = "0.21.2"
3+
version = "0.22.0-dev"
44
description = "Python-API bindings for the PyO3 ecosystem"
55
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
66
keywords = ["pyo3", "python", "cpython", "ffi"]
@@ -38,7 +38,7 @@ abi3-py312 = ["abi3", "pyo3-build-config/abi3-py312"]
3838
generate-import-lib = ["pyo3-build-config/python3-dll-a"]
3939

4040
[build-dependencies]
41-
pyo3-build-config = { path = "../pyo3-build-config", version = "=0.21.2", features = ["resolve-config"] }
41+
pyo3-build-config = { path = "../pyo3-build-config", version = "=0.22.0-dev", features = ["resolve-config"] }
4242

4343
[lints]
4444
workspace = true

pyo3-macros-backend/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "pyo3-macros-backend"
3-
version = "0.21.2"
3+
version = "0.22.0-dev"
44
description = "Code generation for PyO3 package"
55
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
66
keywords = ["pyo3", "python", "cpython", "ffi"]
@@ -16,7 +16,7 @@ edition = "2021"
1616
[dependencies]
1717
heck = "0.5"
1818
proc-macro2 = { version = "1", default-features = false }
19-
pyo3-build-config = { path = "../pyo3-build-config", version = "=0.21.2", features = ["resolve-config"] }
19+
pyo3-build-config = { path = "../pyo3-build-config", version = "=0.22.0-dev", features = ["resolve-config"] }
2020
quote = { version = "1", default-features = false }
2121

2222
[dependencies.syn]
@@ -29,3 +29,4 @@ workspace = true
2929

3030
[features]
3131
experimental-async = []
32+
gil-refs = []

pyo3-macros-backend/src/module.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,11 @@ fn process_functions_in_module(options: &PyModuleOptions, func: &mut syn::ItemFn
384384
let Ctx { pyo3_path } = ctx;
385385
let mut stmts: Vec<syn::Stmt> = Vec::new();
386386

387+
#[cfg(feature = "gil-refs")]
388+
let imports = quote!(use #pyo3_path::{PyNativeType, types::PyModuleMethods};);
389+
#[cfg(not(feature = "gil-refs"))]
390+
let imports = quote!(use #pyo3_path::types::PyModuleMethods;);
391+
387392
for mut stmt in func.block.stmts.drain(..) {
388393
if let syn::Stmt::Item(Item::Fn(func)) = &mut stmt {
389394
if let Some(pyfn_args) = get_pyfn_attr(&mut func.attrs)? {
@@ -394,7 +399,7 @@ fn process_functions_in_module(options: &PyModuleOptions, func: &mut syn::ItemFn
394399
#wrapped_function
395400
{
396401
#[allow(unknown_lints, unused_imports, redundant_imports)]
397-
use #pyo3_path::{PyNativeType, types::PyModuleMethods};
402+
#imports
398403
#module_name.as_borrowed().add_function(#pyo3_path::wrap_pyfunction!(#name, #module_name.as_borrowed())?)?;
399404
}
400405
};

pyo3-macros-backend/src/pyclass.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1307,11 +1307,19 @@ fn impl_pytypeinfo(
13071307
quote! { ::core::option::Option::None }
13081308
};
13091309

1310-
quote! {
1310+
#[cfg(feature = "gil-refs")]
1311+
let has_py_gil_ref = quote! {
13111312
#[allow(deprecated)]
13121313
unsafe impl #pyo3_path::type_object::HasPyGilRef for #cls {
13131314
type AsRefTarget = #pyo3_path::PyCell<Self>;
13141315
}
1316+
};
1317+
1318+
#[cfg(not(feature = "gil-refs"))]
1319+
let has_py_gil_ref = TokenStream::new();
1320+
1321+
quote! {
1322+
#has_py_gil_ref
13151323

13161324
unsafe impl #pyo3_path::type_object::PyTypeInfo for #cls {
13171325
const NAME: &'static str = #cls_name;

pyo3-macros/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "pyo3-macros"
3-
version = "0.21.2"
3+
version = "0.22.0-dev"
44
description = "Proc macros for PyO3 package"
55
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
66
keywords = ["pyo3", "python", "cpython", "ffi"]
@@ -17,12 +17,13 @@ proc-macro = true
1717
multiple-pymethods = []
1818
experimental-async = ["pyo3-macros-backend/experimental-async"]
1919
experimental-declarative-modules = []
20+
gil-refs = ["pyo3-macros-backend/gil-refs"]
2021

2122
[dependencies]
2223
proc-macro2 = { version = "1", default-features = false }
2324
quote = "1"
2425
syn = { version = "2", features = ["full", "extra-traits"] }
25-
pyo3-macros-backend = { path = "../pyo3-macros-backend", version = "=0.21.2" }
26+
pyo3-macros-backend = { path = "../pyo3-macros-backend", version = "=0.22.0-dev" }
2627

2728
[lints]
2829
workspace = true

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
[tool.towncrier]
55
filename = "CHANGELOG.md"
6-
version = "0.21.2"
6+
version = "0.22.0-dev"
77
start_string = "<!-- towncrier release notes start -->\n"
88
template = ".towncrier.template.md"
99
title_format = "## [{version}] - {project_date}"

src/conversion.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,12 @@ use crate::inspect::types::TypeInfo;
55
use crate::pyclass::boolean_struct::False;
66
use crate::types::any::PyAnyMethods;
77
use crate::types::PyTuple;
8-
use crate::{
9-
ffi, Borrowed, Bound, Py, PyAny, PyClass, PyNativeType, PyObject, PyRef, PyRefMut, Python,
10-
};
8+
use crate::{ffi, Borrowed, Bound, Py, PyAny, PyClass, PyObject, PyRef, PyRefMut, Python};
119
#[cfg(feature = "gil-refs")]
1210
use {
1311
crate::{
1412
err::{self, PyDowncastError},
15-
gil,
13+
gil, PyNativeType,
1614
},
1715
std::ptr::NonNull,
1816
};
@@ -221,6 +219,7 @@ pub trait FromPyObject<'py>: Sized {
221219
///
222220
/// Implementors are encouraged to implement `extract_bound` and leave this method as the
223221
/// default implementation, which will forward calls to `extract_bound`.
222+
#[cfg(feature = "gil-refs")]
224223
fn extract(ob: &'py PyAny) -> PyResult<Self> {
225224
Self::extract_bound(&ob.as_borrowed())
226225
}

src/err/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ use crate::panic::PanicException;
33
use crate::type_object::PyTypeInfo;
44
use crate::types::any::PyAnyMethods;
55
use crate::types::{string::PyStringMethods, typeobject::PyTypeMethods, PyTraceback, PyType};
6+
#[cfg(feature = "gil-refs")]
7+
use crate::PyNativeType;
68
use crate::{
79
exceptions::{self, PyBaseException},
810
ffi,
911
};
10-
use crate::{Borrowed, IntoPy, Py, PyAny, PyNativeType, PyObject, Python, ToPyObject};
12+
use crate::{Borrowed, IntoPy, Py, PyAny, PyObject, Python, ToPyObject};
1113
use std::borrow::Cow;
1214
use std::cell::UnsafeCell;
1315
use std::ffi::CString;
@@ -47,11 +49,13 @@ pub type PyResult<T> = Result<T, PyErr>;
4749

4850
/// Error that indicates a failure to convert a PyAny to a more specific Python type.
4951
#[derive(Debug)]
52+
#[cfg(feature = "gil-refs")]
5053
pub struct PyDowncastError<'a> {
5154
from: &'a PyAny,
5255
to: Cow<'static, str>,
5356
}
5457

58+
#[cfg(feature = "gil-refs")]
5559
impl<'a> PyDowncastError<'a> {
5660
/// Create a new `PyDowncastError` representing a failure to convert the object
5761
/// `from` into the type named in `to`.
@@ -64,7 +68,6 @@ impl<'a> PyDowncastError<'a> {
6468

6569
/// Compatibility API to convert the Bound variant `DowncastError` into the
6670
/// gil-ref variant
67-
#[cfg(feature = "gil-refs")]
6871
pub(crate) fn from_downcast_err(DowncastError { from, to }: DowncastError<'a, 'a>) -> Self {
6972
#[allow(deprecated)]
7073
let from = unsafe { from.py().from_borrowed_ptr(from.as_ptr()) };
@@ -1012,8 +1015,10 @@ impl<'a> std::convert::From<PyDowncastError<'a>> for PyErr {
10121015
}
10131016
}
10141017

1018+
#[cfg(feature = "gil-refs")]
10151019
impl<'a> std::error::Error for PyDowncastError<'a> {}
10161020

1021+
#[cfg(feature = "gil-refs")]
10171022
impl<'a> std::fmt::Display for PyDowncastError<'a> {
10181023
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
10191024
display_downcast_error(f, &self.from.as_borrowed(), &self.to)

src/exceptions.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ macro_rules! import_exception_bound {
146146

147147
// FIXME remove this: was necessary while `PyTypeInfo` requires `HasPyGilRef`,
148148
// should change in 0.22.
149+
#[cfg(feature = "gil-refs")]
149150
unsafe impl $crate::type_object::HasPyGilRef for $name {
150151
type AsRefTarget = $crate::PyAny;
151152
}

src/impl_/deprecations.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub struct NotAGilRef<T>(std::marker::PhantomData<T>);
1919

2020
pub trait IsGilRef {}
2121

22+
#[cfg(feature = "gil-refs")]
2223
impl<T: crate::PyNativeType> IsGilRef for &'_ T {}
2324

2425
impl<T> GilRefs<T> {

src/impl_/pyclass.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#[cfg(feature = "gil-refs")]
2+
use crate::PyNativeType;
13
use crate::{
24
exceptions::{PyAttributeError, PyNotImplementedError, PyRuntimeError, PyValueError},
35
ffi,
@@ -7,8 +9,7 @@ use crate::{
79
pyclass_init::PyObjectInit,
810
types::any::PyAnyMethods,
911
types::PyBool,
10-
Borrowed, Py, PyAny, PyClass, PyErr, PyMethodDefType, PyNativeType, PyResult, PyTypeInfo,
11-
Python,
12+
Borrowed, Py, PyAny, PyClass, PyErr, PyMethodDefType, PyResult, PyTypeInfo, Python,
1213
};
1314
use std::{
1415
borrow::Cow,
@@ -168,7 +169,12 @@ pub trait PyClassImpl: Sized + 'static {
168169

169170
/// The closest native ancestor. This is `PyAny` by default, and when you declare
170171
/// `#[pyclass(extends=PyDict)]`, it's `PyDict`.
172+
#[cfg(feature = "gil-refs")]
171173
type BaseNativeType: PyTypeInfo + PyNativeType;
174+
/// The closest native ancestor. This is `PyAny` by default, and when you declare
175+
/// `#[pyclass(extends=PyDict)]`, it's `PyDict`.
176+
#[cfg(not(feature = "gil-refs"))]
177+
type BaseNativeType: PyTypeInfo;
172178

173179
/// This handles following two situations:
174180
/// 1. In case `T` is `Send`, stub `ThreadChecker` is used and does nothing.

0 commit comments

Comments
 (0)