feature gate `PyCell` (#4177)
* feature gate `PyCell` * feature gate `HasPyGilRef` completely * bump version
This commit is contained in:
parent
57500d9b09
commit
10152a7078
10
Cargo.toml
10
Cargo.toml
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "pyo3"
|
name = "pyo3"
|
||||||
version = "0.21.2"
|
version = "0.22.0-dev"
|
||||||
description = "Bindings to Python interpreter"
|
description = "Bindings to Python interpreter"
|
||||||
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
|
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
@ -20,10 +20,10 @@ libc = "0.2.62"
|
||||||
memoffset = "0.9"
|
memoffset = "0.9"
|
||||||
|
|
||||||
# ffi bindings to the python interpreter, split into a separate crate so they can be used independently
|
# ffi bindings to the python interpreter, split into a separate crate so they can be used independently
|
||||||
pyo3-ffi = { path = "pyo3-ffi", version = "=0.21.2" }
|
pyo3-ffi = { path = "pyo3-ffi", version = "=0.22.0-dev" }
|
||||||
|
|
||||||
# support crates for macros feature
|
# support crates for macros feature
|
||||||
pyo3-macros = { path = "pyo3-macros", version = "=0.21.2", optional = true }
|
pyo3-macros = { path = "pyo3-macros", version = "=0.22.0-dev", optional = true }
|
||||||
indoc = { version = "2.0.1", optional = true }
|
indoc = { version = "2.0.1", optional = true }
|
||||||
unindent = { version = "0.2.1", optional = true }
|
unindent = { version = "0.2.1", optional = true }
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ rayon = "1.6.1"
|
||||||
futures = "0.3.28"
|
futures = "0.3.28"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
pyo3-build-config = { path = "pyo3-build-config", version = "=0.21.2", features = ["resolve-config"] }
|
pyo3-build-config = { path = "pyo3-build-config", version = "=0.22.0-dev", features = ["resolve-config"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["macros"]
|
default = ["macros"]
|
||||||
|
@ -106,7 +106,7 @@ generate-import-lib = ["pyo3-ffi/generate-import-lib"]
|
||||||
auto-initialize = []
|
auto-initialize = []
|
||||||
|
|
||||||
# Allows use of the deprecated "GIL Refs" APIs.
|
# Allows use of the deprecated "GIL Refs" APIs.
|
||||||
gil-refs = []
|
gil-refs = ["pyo3-macros/gil-refs"]
|
||||||
|
|
||||||
# Enables `Clone`ing references to Python objects `Py<T>` which panics if the GIL is not held.
|
# Enables `Clone`ing references to Python objects `Py<T>` which panics if the GIL is not held.
|
||||||
py-clone = []
|
py-clone = []
|
||||||
|
|
|
@ -1307,6 +1307,7 @@ struct MyClass {
|
||||||
impl pyo3::types::DerefToPyAny for MyClass {}
|
impl pyo3::types::DerefToPyAny for MyClass {}
|
||||||
|
|
||||||
# #[allow(deprecated)]
|
# #[allow(deprecated)]
|
||||||
|
# #[cfg(feature = "gil-refs")]
|
||||||
unsafe impl pyo3::type_object::HasPyGilRef for MyClass {
|
unsafe impl pyo3::type_object::HasPyGilRef for MyClass {
|
||||||
type AsRefTarget = pyo3::PyCell<Self>;
|
type AsRefTarget = pyo3::PyCell<Self>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1609,7 +1609,7 @@ For more, see [the constructor section](class.md#constructor) of this guide.
|
||||||
<details>
|
<details>
|
||||||
<summary><small>Click to expand</small></summary>
|
<summary><small>Click to expand</small></summary>
|
||||||
|
|
||||||
PyO3 0.9 introduces [`PyCell`], which is a [`RefCell`]-like object wrapper
|
PyO3 0.9 introduces `PyCell`, which is a [`RefCell`]-like object wrapper
|
||||||
for ensuring Rust's rules regarding aliasing of references are upheld.
|
for ensuring Rust's rules regarding aliasing of references are upheld.
|
||||||
For more detail, see the
|
For more detail, see the
|
||||||
[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)
|
[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 {
|
||||||
|
|
||||||
[`FromPyObject`]: {{#PYO3_DOCS_URL}}/pyo3/conversion/trait.FromPyObject.html
|
[`FromPyObject`]: {{#PYO3_DOCS_URL}}/pyo3/conversion/trait.FromPyObject.html
|
||||||
[`PyAny`]: {{#PYO3_DOCS_URL}}/pyo3/types/struct.PyAny.html
|
[`PyAny`]: {{#PYO3_DOCS_URL}}/pyo3/types/struct.PyAny.html
|
||||||
[`PyCell`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyCell.html
|
|
||||||
[`PyBorrowMutError`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyBorrowMutError.html
|
[`PyBorrowMutError`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyBorrowMutError.html
|
||||||
[`PyRef`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyRef.html
|
[`PyRef`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyRef.html
|
||||||
[`PyRefMut`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyRef.html
|
[`PyRefMut`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyRef.html
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "pyo3-build-config"
|
name = "pyo3-build-config"
|
||||||
version = "0.21.2"
|
version = "0.22.0-dev"
|
||||||
description = "Build configuration for the PyO3 ecosystem"
|
description = "Build configuration for the PyO3 ecosystem"
|
||||||
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
|
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
|
||||||
keywords = ["pyo3", "python", "cpython", "ffi"]
|
keywords = ["pyo3", "python", "cpython", "ffi"]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "pyo3-ffi"
|
name = "pyo3-ffi"
|
||||||
version = "0.21.2"
|
version = "0.22.0-dev"
|
||||||
description = "Python-API bindings for the PyO3 ecosystem"
|
description = "Python-API bindings for the PyO3 ecosystem"
|
||||||
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
|
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
|
||||||
keywords = ["pyo3", "python", "cpython", "ffi"]
|
keywords = ["pyo3", "python", "cpython", "ffi"]
|
||||||
|
@ -38,7 +38,7 @@ abi3-py312 = ["abi3", "pyo3-build-config/abi3-py312"]
|
||||||
generate-import-lib = ["pyo3-build-config/python3-dll-a"]
|
generate-import-lib = ["pyo3-build-config/python3-dll-a"]
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
pyo3-build-config = { path = "../pyo3-build-config", version = "=0.21.2", features = ["resolve-config"] }
|
pyo3-build-config = { path = "../pyo3-build-config", version = "=0.22.0-dev", features = ["resolve-config"] }
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "pyo3-macros-backend"
|
name = "pyo3-macros-backend"
|
||||||
version = "0.21.2"
|
version = "0.22.0-dev"
|
||||||
description = "Code generation for PyO3 package"
|
description = "Code generation for PyO3 package"
|
||||||
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
|
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
|
||||||
keywords = ["pyo3", "python", "cpython", "ffi"]
|
keywords = ["pyo3", "python", "cpython", "ffi"]
|
||||||
|
@ -16,7 +16,7 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
heck = "0.5"
|
heck = "0.5"
|
||||||
proc-macro2 = { version = "1", default-features = false }
|
proc-macro2 = { version = "1", default-features = false }
|
||||||
pyo3-build-config = { path = "../pyo3-build-config", version = "=0.21.2", features = ["resolve-config"] }
|
pyo3-build-config = { path = "../pyo3-build-config", version = "=0.22.0-dev", features = ["resolve-config"] }
|
||||||
quote = { version = "1", default-features = false }
|
quote = { version = "1", default-features = false }
|
||||||
|
|
||||||
[dependencies.syn]
|
[dependencies.syn]
|
||||||
|
@ -29,3 +29,4 @@ workspace = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
experimental-async = []
|
experimental-async = []
|
||||||
|
gil-refs = []
|
||||||
|
|
|
@ -384,6 +384,11 @@ fn process_functions_in_module(options: &PyModuleOptions, func: &mut syn::ItemFn
|
||||||
let Ctx { pyo3_path } = ctx;
|
let Ctx { pyo3_path } = ctx;
|
||||||
let mut stmts: Vec<syn::Stmt> = Vec::new();
|
let mut stmts: Vec<syn::Stmt> = Vec::new();
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
|
let imports = quote!(use #pyo3_path::{PyNativeType, types::PyModuleMethods};);
|
||||||
|
#[cfg(not(feature = "gil-refs"))]
|
||||||
|
let imports = quote!(use #pyo3_path::types::PyModuleMethods;);
|
||||||
|
|
||||||
for mut stmt in func.block.stmts.drain(..) {
|
for mut stmt in func.block.stmts.drain(..) {
|
||||||
if let syn::Stmt::Item(Item::Fn(func)) = &mut stmt {
|
if let syn::Stmt::Item(Item::Fn(func)) = &mut stmt {
|
||||||
if let Some(pyfn_args) = get_pyfn_attr(&mut func.attrs)? {
|
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
|
||||||
#wrapped_function
|
#wrapped_function
|
||||||
{
|
{
|
||||||
#[allow(unknown_lints, unused_imports, redundant_imports)]
|
#[allow(unknown_lints, unused_imports, redundant_imports)]
|
||||||
use #pyo3_path::{PyNativeType, types::PyModuleMethods};
|
#imports
|
||||||
#module_name.as_borrowed().add_function(#pyo3_path::wrap_pyfunction!(#name, #module_name.as_borrowed())?)?;
|
#module_name.as_borrowed().add_function(#pyo3_path::wrap_pyfunction!(#name, #module_name.as_borrowed())?)?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1307,11 +1307,19 @@ fn impl_pytypeinfo(
|
||||||
quote! { ::core::option::Option::None }
|
quote! { ::core::option::Option::None }
|
||||||
};
|
};
|
||||||
|
|
||||||
quote! {
|
#[cfg(feature = "gil-refs")]
|
||||||
|
let has_py_gil_ref = quote! {
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
unsafe impl #pyo3_path::type_object::HasPyGilRef for #cls {
|
unsafe impl #pyo3_path::type_object::HasPyGilRef for #cls {
|
||||||
type AsRefTarget = #pyo3_path::PyCell<Self>;
|
type AsRefTarget = #pyo3_path::PyCell<Self>;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(not(feature = "gil-refs"))]
|
||||||
|
let has_py_gil_ref = TokenStream::new();
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#has_py_gil_ref
|
||||||
|
|
||||||
unsafe impl #pyo3_path::type_object::PyTypeInfo for #cls {
|
unsafe impl #pyo3_path::type_object::PyTypeInfo for #cls {
|
||||||
const NAME: &'static str = #cls_name;
|
const NAME: &'static str = #cls_name;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "pyo3-macros"
|
name = "pyo3-macros"
|
||||||
version = "0.21.2"
|
version = "0.22.0-dev"
|
||||||
description = "Proc macros for PyO3 package"
|
description = "Proc macros for PyO3 package"
|
||||||
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
|
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
|
||||||
keywords = ["pyo3", "python", "cpython", "ffi"]
|
keywords = ["pyo3", "python", "cpython", "ffi"]
|
||||||
|
@ -17,12 +17,13 @@ proc-macro = true
|
||||||
multiple-pymethods = []
|
multiple-pymethods = []
|
||||||
experimental-async = ["pyo3-macros-backend/experimental-async"]
|
experimental-async = ["pyo3-macros-backend/experimental-async"]
|
||||||
experimental-declarative-modules = []
|
experimental-declarative-modules = []
|
||||||
|
gil-refs = ["pyo3-macros-backend/gil-refs"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
proc-macro2 = { version = "1", default-features = false }
|
proc-macro2 = { version = "1", default-features = false }
|
||||||
quote = "1"
|
quote = "1"
|
||||||
syn = { version = "2", features = ["full", "extra-traits"] }
|
syn = { version = "2", features = ["full", "extra-traits"] }
|
||||||
pyo3-macros-backend = { path = "../pyo3-macros-backend", version = "=0.21.2" }
|
pyo3-macros-backend = { path = "../pyo3-macros-backend", version = "=0.22.0-dev" }
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
[tool.towncrier]
|
[tool.towncrier]
|
||||||
filename = "CHANGELOG.md"
|
filename = "CHANGELOG.md"
|
||||||
version = "0.21.2"
|
version = "0.22.0-dev"
|
||||||
start_string = "<!-- towncrier release notes start -->\n"
|
start_string = "<!-- towncrier release notes start -->\n"
|
||||||
template = ".towncrier.template.md"
|
template = ".towncrier.template.md"
|
||||||
title_format = "## [{version}] - {project_date}"
|
title_format = "## [{version}] - {project_date}"
|
||||||
|
|
|
@ -5,14 +5,12 @@ use crate::inspect::types::TypeInfo;
|
||||||
use crate::pyclass::boolean_struct::False;
|
use crate::pyclass::boolean_struct::False;
|
||||||
use crate::types::any::PyAnyMethods;
|
use crate::types::any::PyAnyMethods;
|
||||||
use crate::types::PyTuple;
|
use crate::types::PyTuple;
|
||||||
use crate::{
|
use crate::{ffi, Borrowed, Bound, Py, PyAny, PyClass, PyObject, PyRef, PyRefMut, Python};
|
||||||
ffi, Borrowed, Bound, Py, PyAny, PyClass, PyNativeType, PyObject, PyRef, PyRefMut, Python,
|
|
||||||
};
|
|
||||||
#[cfg(feature = "gil-refs")]
|
#[cfg(feature = "gil-refs")]
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
err::{self, PyDowncastError},
|
err::{self, PyDowncastError},
|
||||||
gil,
|
gil, PyNativeType,
|
||||||
},
|
},
|
||||||
std::ptr::NonNull,
|
std::ptr::NonNull,
|
||||||
};
|
};
|
||||||
|
@ -221,6 +219,7 @@ pub trait FromPyObject<'py>: Sized {
|
||||||
///
|
///
|
||||||
/// Implementors are encouraged to implement `extract_bound` and leave this method as the
|
/// Implementors are encouraged to implement `extract_bound` and leave this method as the
|
||||||
/// default implementation, which will forward calls to `extract_bound`.
|
/// default implementation, which will forward calls to `extract_bound`.
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
fn extract(ob: &'py PyAny) -> PyResult<Self> {
|
fn extract(ob: &'py PyAny) -> PyResult<Self> {
|
||||||
Self::extract_bound(&ob.as_borrowed())
|
Self::extract_bound(&ob.as_borrowed())
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,13 @@ use crate::panic::PanicException;
|
||||||
use crate::type_object::PyTypeInfo;
|
use crate::type_object::PyTypeInfo;
|
||||||
use crate::types::any::PyAnyMethods;
|
use crate::types::any::PyAnyMethods;
|
||||||
use crate::types::{string::PyStringMethods, typeobject::PyTypeMethods, PyTraceback, PyType};
|
use crate::types::{string::PyStringMethods, typeobject::PyTypeMethods, PyTraceback, PyType};
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
|
use crate::PyNativeType;
|
||||||
use crate::{
|
use crate::{
|
||||||
exceptions::{self, PyBaseException},
|
exceptions::{self, PyBaseException},
|
||||||
ffi,
|
ffi,
|
||||||
};
|
};
|
||||||
use crate::{Borrowed, IntoPy, Py, PyAny, PyNativeType, PyObject, Python, ToPyObject};
|
use crate::{Borrowed, IntoPy, Py, PyAny, PyObject, Python, ToPyObject};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cell::UnsafeCell;
|
use std::cell::UnsafeCell;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
@ -47,11 +49,13 @@ pub type PyResult<T> = Result<T, PyErr>;
|
||||||
|
|
||||||
/// Error that indicates a failure to convert a PyAny to a more specific Python type.
|
/// Error that indicates a failure to convert a PyAny to a more specific Python type.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub struct PyDowncastError<'a> {
|
pub struct PyDowncastError<'a> {
|
||||||
from: &'a PyAny,
|
from: &'a PyAny,
|
||||||
to: Cow<'static, str>,
|
to: Cow<'static, str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'a> PyDowncastError<'a> {
|
impl<'a> PyDowncastError<'a> {
|
||||||
/// Create a new `PyDowncastError` representing a failure to convert the object
|
/// Create a new `PyDowncastError` representing a failure to convert the object
|
||||||
/// `from` into the type named in `to`.
|
/// `from` into the type named in `to`.
|
||||||
|
@ -64,7 +68,6 @@ impl<'a> PyDowncastError<'a> {
|
||||||
|
|
||||||
/// Compatibility API to convert the Bound variant `DowncastError` into the
|
/// Compatibility API to convert the Bound variant `DowncastError` into the
|
||||||
/// gil-ref variant
|
/// gil-ref variant
|
||||||
#[cfg(feature = "gil-refs")]
|
|
||||||
pub(crate) fn from_downcast_err(DowncastError { from, to }: DowncastError<'a, 'a>) -> Self {
|
pub(crate) fn from_downcast_err(DowncastError { from, to }: DowncastError<'a, 'a>) -> Self {
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
let from = unsafe { from.py().from_borrowed_ptr(from.as_ptr()) };
|
let from = unsafe { from.py().from_borrowed_ptr(from.as_ptr()) };
|
||||||
|
@ -1012,8 +1015,10 @@ impl<'a> std::convert::From<PyDowncastError<'a>> for PyErr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'a> std::error::Error for PyDowncastError<'a> {}
|
impl<'a> std::error::Error for PyDowncastError<'a> {}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'a> std::fmt::Display for PyDowncastError<'a> {
|
impl<'a> std::fmt::Display for PyDowncastError<'a> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||||
display_downcast_error(f, &self.from.as_borrowed(), &self.to)
|
display_downcast_error(f, &self.from.as_borrowed(), &self.to)
|
||||||
|
|
|
@ -146,6 +146,7 @@ macro_rules! import_exception_bound {
|
||||||
|
|
||||||
// FIXME remove this: was necessary while `PyTypeInfo` requires `HasPyGilRef`,
|
// FIXME remove this: was necessary while `PyTypeInfo` requires `HasPyGilRef`,
|
||||||
// should change in 0.22.
|
// should change in 0.22.
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
unsafe impl $crate::type_object::HasPyGilRef for $name {
|
unsafe impl $crate::type_object::HasPyGilRef for $name {
|
||||||
type AsRefTarget = $crate::PyAny;
|
type AsRefTarget = $crate::PyAny;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ pub struct NotAGilRef<T>(std::marker::PhantomData<T>);
|
||||||
|
|
||||||
pub trait IsGilRef {}
|
pub trait IsGilRef {}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<T: crate::PyNativeType> IsGilRef for &'_ T {}
|
impl<T: crate::PyNativeType> IsGilRef for &'_ T {}
|
||||||
|
|
||||||
impl<T> GilRefs<T> {
|
impl<T> GilRefs<T> {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
|
use crate::PyNativeType;
|
||||||
use crate::{
|
use crate::{
|
||||||
exceptions::{PyAttributeError, PyNotImplementedError, PyRuntimeError, PyValueError},
|
exceptions::{PyAttributeError, PyNotImplementedError, PyRuntimeError, PyValueError},
|
||||||
ffi,
|
ffi,
|
||||||
|
@ -7,8 +9,7 @@ use crate::{
|
||||||
pyclass_init::PyObjectInit,
|
pyclass_init::PyObjectInit,
|
||||||
types::any::PyAnyMethods,
|
types::any::PyAnyMethods,
|
||||||
types::PyBool,
|
types::PyBool,
|
||||||
Borrowed, Py, PyAny, PyClass, PyErr, PyMethodDefType, PyNativeType, PyResult, PyTypeInfo,
|
Borrowed, Py, PyAny, PyClass, PyErr, PyMethodDefType, PyResult, PyTypeInfo, Python,
|
||||||
Python,
|
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
|
@ -168,7 +169,12 @@ pub trait PyClassImpl: Sized + 'static {
|
||||||
|
|
||||||
/// The closest native ancestor. This is `PyAny` by default, and when you declare
|
/// The closest native ancestor. This is `PyAny` by default, and when you declare
|
||||||
/// `#[pyclass(extends=PyDict)]`, it's `PyDict`.
|
/// `#[pyclass(extends=PyDict)]`, it's `PyDict`.
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
type BaseNativeType: PyTypeInfo + PyNativeType;
|
type BaseNativeType: PyTypeInfo + PyNativeType;
|
||||||
|
/// The closest native ancestor. This is `PyAny` by default, and when you declare
|
||||||
|
/// `#[pyclass(extends=PyDict)]`, it's `PyDict`.
|
||||||
|
#[cfg(not(feature = "gil-refs"))]
|
||||||
|
type BaseNativeType: PyTypeInfo;
|
||||||
|
|
||||||
/// This handles following two situations:
|
/// This handles following two situations:
|
||||||
/// 1. In case `T` is `Send`, stub `ThreadChecker` is used and does nothing.
|
/// 1. In case `T` is `Send`, stub `ThreadChecker` is used and does nothing.
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::err::{self, PyErr, PyResult};
|
||||||
use crate::impl_::pycell::PyClassObject;
|
use crate::impl_::pycell::PyClassObject;
|
||||||
use crate::pycell::{PyBorrowError, PyBorrowMutError};
|
use crate::pycell::{PyBorrowError, PyBorrowMutError};
|
||||||
use crate::pyclass::boolean_struct::{False, True};
|
use crate::pyclass::boolean_struct::{False, True};
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
use crate::type_object::HasPyGilRef;
|
use crate::type_object::HasPyGilRef;
|
||||||
use crate::types::{any::PyAnyMethods, string::PyStringMethods, typeobject::PyTypeMethods};
|
use crate::types::{any::PyAnyMethods, string::PyStringMethods, typeobject::PyTypeMethods};
|
||||||
use crate::types::{DerefToPyAny, PyDict, PyString, PyTuple};
|
use crate::types::{DerefToPyAny, PyDict, PyString, PyTuple};
|
||||||
|
@ -24,6 +25,7 @@ use std::ptr::NonNull;
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// This trait must only be implemented for types which cannot be accessed without the GIL.
|
/// This trait must only be implemented for types which cannot be accessed without the GIL.
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub unsafe trait PyNativeType: Sized {
|
pub unsafe trait PyNativeType: Sized {
|
||||||
/// The form of this which is stored inside a `Py<T>` smart pointer.
|
/// The form of this which is stored inside a `Py<T>` smart pointer.
|
||||||
type AsRefSource: HasPyGilRef<AsRefTarget = Self>;
|
type AsRefSource: HasPyGilRef<AsRefTarget = Self>;
|
||||||
|
@ -666,11 +668,11 @@ impl<'a, 'py, T> From<&'a Bound<'py, T>> for Borrowed<'a, 'py, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'py, T> Borrowed<'py, 'py, T>
|
impl<'py, T> Borrowed<'py, 'py, T>
|
||||||
where
|
where
|
||||||
T: HasPyGilRef,
|
T: HasPyGilRef,
|
||||||
{
|
{
|
||||||
#[cfg(feature = "gil-refs")]
|
|
||||||
pub(crate) fn into_gil_ref(self) -> &'py T::AsRefTarget {
|
pub(crate) fn into_gil_ref(self) -> &'py T::AsRefTarget {
|
||||||
// Safety: self is a borrow over `'py`.
|
// Safety: self is a borrow over `'py`.
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
|
@ -953,6 +955,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<T> Py<T>
|
impl<T> Py<T>
|
||||||
where
|
where
|
||||||
T: HasPyGilRef,
|
T: HasPyGilRef,
|
||||||
|
@ -1000,7 +1003,6 @@ where
|
||||||
/// assert!(my_class_cell.try_borrow().is_ok());
|
/// assert!(my_class_cell.try_borrow().is_ok());
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(feature = "gil-refs")]
|
|
||||||
#[deprecated(
|
#[deprecated(
|
||||||
since = "0.21.0",
|
since = "0.21.0",
|
||||||
note = "use `obj.bind(py)` instead of `obj.as_ref(py)`"
|
note = "use `obj.bind(py)` instead of `obj.as_ref(py)`"
|
||||||
|
@ -1053,7 +1055,6 @@ where
|
||||||
/// obj.into_ref(py)
|
/// obj.into_ref(py)
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(feature = "gil-refs")]
|
|
||||||
#[deprecated(
|
#[deprecated(
|
||||||
since = "0.21.0",
|
since = "0.21.0",
|
||||||
note = "use `obj.into_bound(py)` instead of `obj.into_ref(py)`"
|
note = "use `obj.into_bound(py)` instead of `obj.into_ref(py)`"
|
||||||
|
@ -1118,8 +1119,7 @@ where
|
||||||
///
|
///
|
||||||
/// For frozen classes, the simpler [`get`][Self::get] is available.
|
/// For frozen classes, the simpler [`get`][Self::get] is available.
|
||||||
///
|
///
|
||||||
/// Equivalent to `self.as_ref(py).borrow()` -
|
/// Equivalent to `self.bind(py).borrow()` - see [`Bound::borrow`].
|
||||||
/// see [`PyCell::borrow`](crate::pycell::PyCell::borrow).
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -1157,8 +1157,7 @@ where
|
||||||
///
|
///
|
||||||
/// This borrow lasts while the returned [`PyRefMut`] exists.
|
/// This borrow lasts while the returned [`PyRefMut`] exists.
|
||||||
///
|
///
|
||||||
/// Equivalent to `self.as_ref(py).borrow_mut()` -
|
/// Equivalent to `self.bind(py).borrow_mut()` - see [`Bound::borrow_mut`].
|
||||||
/// see [`PyCell::borrow_mut`](crate::pycell::PyCell::borrow_mut).
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -1202,8 +1201,7 @@ where
|
||||||
///
|
///
|
||||||
/// For frozen classes, the simpler [`get`][Self::get] is available.
|
/// For frozen classes, the simpler [`get`][Self::get] is available.
|
||||||
///
|
///
|
||||||
/// Equivalent to `self.as_ref(py).borrow_mut()` -
|
/// Equivalent to `self.bind(py).try_borrow()` - see [`Bound::try_borrow`].
|
||||||
/// see [`PyCell::try_borrow`](crate::pycell::PyCell::try_borrow).
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn try_borrow<'py>(&'py self, py: Python<'py>) -> Result<PyRef<'py, T>, PyBorrowError> {
|
pub fn try_borrow<'py>(&'py self, py: Python<'py>) -> Result<PyRef<'py, T>, PyBorrowError> {
|
||||||
self.bind(py).try_borrow()
|
self.bind(py).try_borrow()
|
||||||
|
@ -1215,8 +1213,7 @@ where
|
||||||
///
|
///
|
||||||
/// This is the non-panicking variant of [`borrow_mut`](#method.borrow_mut).
|
/// This is the non-panicking variant of [`borrow_mut`](#method.borrow_mut).
|
||||||
///
|
///
|
||||||
/// Equivalent to `self.as_ref(py).try_borrow_mut()` -
|
/// Equivalent to `self.bind(py).try_borrow_mut()` - see [`Bound::try_borrow_mut`].
|
||||||
/// see [`PyCell::try_borrow_mut`](crate::pycell::PyCell::try_borrow_mut).
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn try_borrow_mut<'py>(
|
pub fn try_borrow_mut<'py>(
|
||||||
&'py self,
|
&'py self,
|
||||||
|
@ -1742,6 +1739,7 @@ unsafe impl<T> crate::AsPyPointer for Py<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<T> std::convert::From<&'_ T> for PyObject
|
impl<T> std::convert::From<&'_ T> for PyObject
|
||||||
where
|
where
|
||||||
T: PyNativeType,
|
T: PyNativeType,
|
||||||
|
@ -1866,6 +1864,7 @@ where
|
||||||
///
|
///
|
||||||
/// However for GIL lifetime reasons, cause() cannot be implemented for `Py<T>`.
|
/// However for GIL lifetime reasons, cause() cannot be implemented for `Py<T>`.
|
||||||
/// Use .as_ref() to get the GIL-scoped error if you need to inspect the cause.
|
/// Use .as_ref() to get the GIL-scoped error if you need to inspect the cause.
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<T> std::error::Error for Py<T>
|
impl<T> std::error::Error for Py<T>
|
||||||
where
|
where
|
||||||
T: std::error::Error + PyTypeInfo,
|
T: std::error::Error + PyTypeInfo,
|
||||||
|
@ -1876,7 +1875,6 @@ where
|
||||||
impl<T> std::fmt::Display for Py<T>
|
impl<T> std::fmt::Display for Py<T>
|
||||||
where
|
where
|
||||||
T: PyTypeInfo,
|
T: PyTypeInfo,
|
||||||
T::AsRefTarget: std::fmt::Display,
|
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
Python::with_gil(|py| std::fmt::Display::fmt(self.bind(py), f))
|
Python::with_gil(|py| std::fmt::Display::fmt(self.bind(py), f))
|
||||||
|
|
12
src/lib.rs
12
src/lib.rs
|
@ -320,15 +320,18 @@ pub use crate::conversion::{AsPyPointer, FromPyObject, IntoPy, ToPyObject};
|
||||||
#[cfg(feature = "gil-refs")]
|
#[cfg(feature = "gil-refs")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
pub use crate::conversion::{FromPyPointer, PyTryFrom, PyTryInto};
|
pub use crate::conversion::{FromPyPointer, PyTryFrom, PyTryInto};
|
||||||
pub use crate::err::{
|
#[cfg(feature = "gil-refs")]
|
||||||
DowncastError, DowncastIntoError, PyDowncastError, PyErr, PyErrArguments, PyResult, ToPyErr,
|
pub use crate::err::PyDowncastError;
|
||||||
};
|
pub use crate::err::{DowncastError, DowncastIntoError, PyErr, PyErrArguments, PyResult, ToPyErr};
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
pub use crate::gil::GILPool;
|
pub use crate::gil::GILPool;
|
||||||
#[cfg(not(any(PyPy, GraalPy)))]
|
#[cfg(not(any(PyPy, GraalPy)))]
|
||||||
pub use crate::gil::{prepare_freethreaded_python, with_embedded_python_interpreter};
|
pub use crate::gil::{prepare_freethreaded_python, with_embedded_python_interpreter};
|
||||||
pub use crate::instance::{Borrowed, Bound, Py, PyNativeType, PyObject};
|
#[cfg(feature = "gil-refs")]
|
||||||
|
pub use crate::instance::PyNativeType;
|
||||||
|
pub use crate::instance::{Borrowed, Bound, Py, PyObject};
|
||||||
pub use crate::marker::Python;
|
pub use crate::marker::Python;
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
pub use crate::pycell::PyCell;
|
pub use crate::pycell::PyCell;
|
||||||
pub use crate::pycell::{PyRef, PyRefMut};
|
pub use crate::pycell::{PyRef, PyRefMut};
|
||||||
|
@ -443,6 +446,7 @@ mod conversions;
|
||||||
pub mod coroutine;
|
pub mod coroutine;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub mod derive_utils;
|
pub mod derive_utils;
|
||||||
mod err;
|
mod err;
|
||||||
pub mod exceptions;
|
pub mod exceptions;
|
||||||
|
|
|
@ -105,6 +105,7 @@ macro_rules! py_run_impl {
|
||||||
($py:expr, *$dict:expr, $code:expr) => {{
|
($py:expr, *$dict:expr, $code:expr) => {{
|
||||||
use ::std::option::Option::*;
|
use ::std::option::Option::*;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
use $crate::PyNativeType;
|
use $crate::PyNativeType;
|
||||||
if let ::std::result::Result::Err(e) = $py.run_bound($code, None, Some(&$dict.as_borrowed())) {
|
if let ::std::result::Result::Err(e) = $py.run_bound($code, None, Some(&$dict.as_borrowed())) {
|
||||||
e.print($py);
|
e.print($py);
|
||||||
|
|
|
@ -15,11 +15,13 @@ pub use crate::conversion::{PyTryFrom, PyTryInto};
|
||||||
pub use crate::err::{PyErr, PyResult};
|
pub use crate::err::{PyErr, PyResult};
|
||||||
pub use crate::instance::{Borrowed, Bound, Py, PyObject};
|
pub use crate::instance::{Borrowed, Bound, Py, PyObject};
|
||||||
pub use crate::marker::Python;
|
pub use crate::marker::Python;
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
pub use crate::pycell::PyCell;
|
pub use crate::pycell::PyCell;
|
||||||
pub use crate::pycell::{PyRef, PyRefMut};
|
pub use crate::pycell::{PyRef, PyRefMut};
|
||||||
pub use crate::pyclass_init::PyClassInitializer;
|
pub use crate::pyclass_init::PyClassInitializer;
|
||||||
pub use crate::types::{PyAny, PyModule};
|
pub use crate::types::{PyAny, PyModule};
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub use crate::PyNativeType;
|
pub use crate::PyNativeType;
|
||||||
|
|
||||||
#[cfg(feature = "macros")]
|
#[cfg(feature = "macros")]
|
||||||
|
|
|
@ -14,13 +14,13 @@
|
||||||
//! - However, methods and functions in Rust usually *do* need `&mut` references. While PyO3 can
|
//! - However, methods and functions in Rust usually *do* need `&mut` references. While PyO3 can
|
||||||
//! use the [`Python<'py>`](crate::Python) token to guarantee thread-safe access to them, it cannot
|
//! use the [`Python<'py>`](crate::Python) token to guarantee thread-safe access to them, it cannot
|
||||||
//! statically guarantee uniqueness of `&mut` references. As such those references have to be tracked
|
//! statically guarantee uniqueness of `&mut` references. As such those references have to be tracked
|
||||||
//! dynamically at runtime, using [`PyCell`] and the other types defined in this module. This works
|
//! dynamically at runtime, using `PyCell` and the other types defined in this module. This works
|
||||||
//! similar to std's [`RefCell`](std::cell::RefCell) type.
|
//! similar to std's [`RefCell`](std::cell::RefCell) type.
|
||||||
//!
|
//!
|
||||||
//! # When *not* to use PyCell
|
//! # When *not* to use PyCell
|
||||||
//!
|
//!
|
||||||
//! Usually you can use `&mut` references as method and function receivers and arguments, and you
|
//! Usually you can use `&mut` references as method and function receivers and arguments, and you
|
||||||
//! won't need to use [`PyCell`] directly:
|
//! won't need to use `PyCell` directly:
|
||||||
//!
|
//!
|
||||||
//! ```rust
|
//! ```rust
|
||||||
//! use pyo3::prelude::*;
|
//! use pyo3::prelude::*;
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! The [`#[pymethods]`](crate::pymethods) proc macro will generate this wrapper function (and more),
|
//! The [`#[pymethods]`](crate::pymethods) proc macro will generate this wrapper function (and more),
|
||||||
//! using [`PyCell`] under the hood:
|
//! using `PyCell` under the hood:
|
||||||
//!
|
//!
|
||||||
//! ```rust,ignore
|
//! ```rust,ignore
|
||||||
//! # use pyo3::prelude::*;
|
//! # use pyo3::prelude::*;
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
//! # When to use PyCell
|
//! # When to use PyCell
|
||||||
//! ## Using pyclasses from Rust
|
//! ## Using pyclasses from Rust
|
||||||
//!
|
//!
|
||||||
//! However, we *do* need [`PyCell`] if we want to call its methods from Rust:
|
//! However, we *do* need `PyCell` if we want to call its methods from Rust:
|
||||||
//! ```rust
|
//! ```rust
|
||||||
//! # use pyo3::prelude::*;
|
//! # use pyo3::prelude::*;
|
||||||
//! #
|
//! #
|
||||||
|
@ -115,7 +115,7 @@
|
||||||
//! ```
|
//! ```
|
||||||
//! ## Dealing with possibly overlapping mutable references
|
//! ## Dealing with possibly overlapping mutable references
|
||||||
//!
|
//!
|
||||||
//! It is also necessary to use [`PyCell`] if you can receive mutable arguments that may overlap.
|
//! It is also necessary to use `PyCell` if you can receive mutable arguments that may overlap.
|
||||||
//! Suppose the following function that swaps the values of two `Number`s:
|
//! Suppose the following function that swaps the values of two `Number`s:
|
||||||
//! ```
|
//! ```
|
||||||
//! # use pyo3::prelude::*;
|
//! # use pyo3::prelude::*;
|
||||||
|
@ -193,28 +193,30 @@
|
||||||
//! [guide]: https://pyo3.rs/latest/class.html#pycell-and-interior-mutability "PyCell and interior mutability"
|
//! [guide]: https://pyo3.rs/latest/class.html#pycell-and-interior-mutability "PyCell and interior mutability"
|
||||||
//! [Interior Mutability]: https://doc.rust-lang.org/book/ch15-05-interior-mutability.html "RefCell<T> and the Interior Mutability Pattern - The Rust Programming Language"
|
//! [Interior Mutability]: https://doc.rust-lang.org/book/ch15-05-interior-mutability.html "RefCell<T> and the Interior Mutability Pattern - The Rust Programming Language"
|
||||||
|
|
||||||
use crate::conversion::{AsPyPointer, ToPyObject};
|
use crate::conversion::AsPyPointer;
|
||||||
use crate::exceptions::PyRuntimeError;
|
use crate::exceptions::PyRuntimeError;
|
||||||
use crate::ffi_ptr_ext::FfiPtrExt;
|
use crate::ffi_ptr_ext::FfiPtrExt;
|
||||||
use crate::impl_::pyclass::PyClassImpl;
|
use crate::pyclass::{boolean_struct::False, PyClass};
|
||||||
use crate::pyclass::{
|
|
||||||
boolean_struct::{False, True},
|
|
||||||
PyClass,
|
|
||||||
};
|
|
||||||
use crate::type_object::{PyLayout, PySizedLayout};
|
|
||||||
use crate::types::any::PyAnyMethods;
|
use crate::types::any::PyAnyMethods;
|
||||||
use crate::types::PyAny;
|
|
||||||
use crate::{ffi, Bound, IntoPy, PyErr, PyNativeType, PyObject, PyTypeCheck, Python};
|
|
||||||
#[cfg(feature = "gil-refs")]
|
#[cfg(feature = "gil-refs")]
|
||||||
use crate::{pyclass_init::PyClassInitializer, PyResult};
|
use crate::{
|
||||||
|
conversion::ToPyObject,
|
||||||
|
impl_::pyclass::PyClassImpl,
|
||||||
|
pyclass::boolean_struct::True,
|
||||||
|
pyclass_init::PyClassInitializer,
|
||||||
|
type_object::{PyLayout, PySizedLayout},
|
||||||
|
types::PyAny,
|
||||||
|
PyNativeType, PyResult, PyTypeCheck,
|
||||||
|
};
|
||||||
|
use crate::{ffi, Bound, IntoPy, PyErr, PyObject, Python};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::mem::ManuallyDrop;
|
use std::mem::ManuallyDrop;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
pub(crate) mod impl_;
|
pub(crate) mod impl_;
|
||||||
use impl_::PyClassBorrowChecker;
|
#[cfg(feature = "gil-refs")]
|
||||||
|
use self::impl_::PyClassObject;
|
||||||
use self::impl_::{PyClassObject, PyClassObjectLayout};
|
use impl_::{PyClassBorrowChecker, PyClassObjectLayout};
|
||||||
|
|
||||||
/// A container type for (mutably) accessing [`PyClass`] values
|
/// A container type for (mutably) accessing [`PyClass`] values
|
||||||
///
|
///
|
||||||
|
@ -223,7 +225,7 @@ use self::impl_::{PyClassObject, PyClassObjectLayout};
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// This example demonstrates getting a mutable reference of the contained `PyClass`.
|
/// This example demonstrates getting a mutable reference of the contained `PyClass`.
|
||||||
/// ```rust,ignore
|
/// ```rust
|
||||||
/// use pyo3::prelude::*;
|
/// use pyo3::prelude::*;
|
||||||
///
|
///
|
||||||
/// #[pyclass]
|
/// #[pyclass]
|
||||||
|
@ -252,28 +254,27 @@ use self::impl_::{PyClassObject, PyClassObjectLayout};
|
||||||
/// ```
|
/// ```
|
||||||
/// For more information on how, when and why (not) to use `PyCell` please see the
|
/// For more information on how, when and why (not) to use `PyCell` please see the
|
||||||
/// [module-level documentation](self).
|
/// [module-level documentation](self).
|
||||||
#[cfg_attr(
|
#[cfg(feature = "gil-refs")]
|
||||||
not(feature = "gil-refs"),
|
#[deprecated(
|
||||||
deprecated(
|
since = "0.21.0",
|
||||||
since = "0.21.0",
|
note = "`PyCell` was merged into `Bound`, use that instead; see the migration guide for more info"
|
||||||
note = "`PyCell` was merged into `Bound`, use that instead; see the migration guide for more info"
|
|
||||||
)
|
|
||||||
)]
|
)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PyCell<T: PyClassImpl>(PyClassObject<T>);
|
pub struct PyCell<T: PyClassImpl>(PyClassObject<T>);
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
unsafe impl<T: PyClass> PyNativeType for PyCell<T> {
|
unsafe impl<T: PyClass> PyNativeType for PyCell<T> {
|
||||||
type AsRefSource = T;
|
type AsRefSource = T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
impl<T: PyClass> PyCell<T> {
|
impl<T: PyClass> PyCell<T> {
|
||||||
/// Makes a new `PyCell` on the Python heap and return the reference to it.
|
/// Makes a new `PyCell` on the Python heap and return the reference to it.
|
||||||
///
|
///
|
||||||
/// In cases where the value in the cell does not need to be accessed immediately after
|
/// In cases where the value in the cell does not need to be accessed immediately after
|
||||||
/// creation, consider [`Py::new`](crate::Py::new) as a more efficient alternative.
|
/// creation, consider [`Py::new`](crate::Py::new) as a more efficient alternative.
|
||||||
#[cfg(feature = "gil-refs")]
|
|
||||||
#[deprecated(
|
#[deprecated(
|
||||||
since = "0.21.0",
|
since = "0.21.0",
|
||||||
note = "use `Bound::new(py, value)` or `Py::new(py, value)` instead of `PyCell::new(py, value)`"
|
note = "use `Bound::new(py, value)` or `Py::new(py, value)` instead of `PyCell::new(py, value)`"
|
||||||
|
@ -316,7 +317,7 @@ impl<T: PyClass> PyCell<T> {
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```ignore
|
/// ```
|
||||||
/// # use pyo3::prelude::*;
|
/// # use pyo3::prelude::*;
|
||||||
/// #[pyclass]
|
/// #[pyclass]
|
||||||
/// struct Class {}
|
/// struct Class {}
|
||||||
|
@ -346,7 +347,7 @@ impl<T: PyClass> PyCell<T> {
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```ignore
|
/// ```
|
||||||
/// # use pyo3::prelude::*;
|
/// # use pyo3::prelude::*;
|
||||||
/// #[pyclass]
|
/// #[pyclass]
|
||||||
/// struct Class {}
|
/// struct Class {}
|
||||||
|
@ -379,7 +380,7 @@ impl<T: PyClass> PyCell<T> {
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```ignore
|
/// ```
|
||||||
/// # use pyo3::prelude::*;
|
/// # use pyo3::prelude::*;
|
||||||
/// #[pyclass]
|
/// #[pyclass]
|
||||||
/// struct Class {}
|
/// struct Class {}
|
||||||
|
@ -416,7 +417,7 @@ impl<T: PyClass> PyCell<T> {
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```ignore
|
/// ```
|
||||||
/// use std::sync::atomic::{AtomicUsize, Ordering};
|
/// use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
/// # use pyo3::prelude::*;
|
/// # use pyo3::prelude::*;
|
||||||
///
|
///
|
||||||
|
@ -487,11 +488,14 @@ impl<T: PyClass> PyCell<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
unsafe impl<T: PyClassImpl> PyLayout<T> for PyCell<T> {}
|
unsafe impl<T: PyClassImpl> PyLayout<T> for PyCell<T> {}
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
impl<T: PyClass> PySizedLayout<T> for PyCell<T> {}
|
impl<T: PyClass> PySizedLayout<T> for PyCell<T> {}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
impl<T> PyTypeCheck for PyCell<T>
|
impl<T> PyTypeCheck for PyCell<T>
|
||||||
where
|
where
|
||||||
|
@ -503,7 +507,7 @@ where
|
||||||
<T as PyTypeCheck>::type_check(object)
|
<T as PyTypeCheck>::type_check(object)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
unsafe impl<T: PyClass> AsPyPointer for PyCell<T> {
|
unsafe impl<T: PyClass> AsPyPointer for PyCell<T> {
|
||||||
fn as_ptr(&self) -> *mut ffi::PyObject {
|
fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||||
|
@ -511,6 +515,7 @@ unsafe impl<T: PyClass> AsPyPointer for PyCell<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
impl<T: PyClass> ToPyObject for &PyCell<T> {
|
impl<T: PyClass> ToPyObject for &PyCell<T> {
|
||||||
fn to_object(&self, py: Python<'_>) -> PyObject {
|
fn to_object(&self, py: Python<'_>) -> PyObject {
|
||||||
|
@ -542,6 +547,7 @@ impl<T: PyClass> Deref for PyCell<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
impl<T: PyClass + fmt::Debug> fmt::Debug for PyCell<T> {
|
impl<T: PyClass + fmt::Debug> fmt::Debug for PyCell<T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
@ -768,6 +774,7 @@ impl<T: PyClass> IntoPy<PyObject> for &'_ PyRef<'_, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
impl<'a, T: PyClass> std::convert::TryFrom<&'a PyCell<T>> for crate::PyRef<'a, T> {
|
impl<'a, T: PyClass> std::convert::TryFrom<&'a PyCell<T>> for crate::PyRef<'a, T> {
|
||||||
type Error = PyBorrowError;
|
type Error = PyBorrowError;
|
||||||
|
@ -788,7 +795,7 @@ impl<T: PyClass + fmt::Debug> fmt::Debug for PyRef<'_, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A wrapper type for a mutably borrowed value from a[`PyCell`]`<T>`.
|
/// A wrapper type for a mutably borrowed value from a [`Bound<'py, T>`].
|
||||||
///
|
///
|
||||||
/// See the [module-level documentation](self) for more information.
|
/// See the [module-level documentation](self) for more information.
|
||||||
pub struct PyRefMut<'p, T: PyClass<Frozen = False>> {
|
pub struct PyRefMut<'p, T: PyClass<Frozen = False>> {
|
||||||
|
@ -928,6 +935,7 @@ unsafe impl<'a, T: PyClass<Frozen = False>> AsPyPointer for PyRefMut<'a, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
impl<'a, T: PyClass<Frozen = False>> std::convert::TryFrom<&'a PyCell<T>>
|
impl<'a, T: PyClass<Frozen = False>> std::convert::TryFrom<&'a PyCell<T>>
|
||||||
for crate::PyRefMut<'a, T>
|
for crate::PyRefMut<'a, T>
|
||||||
|
@ -944,7 +952,7 @@ impl<T: PyClass<Frozen = False> + fmt::Debug> fmt::Debug for PyRefMut<'_, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An error type returned by [`PyCell::try_borrow`].
|
/// An error type returned by [`Bound::try_borrow`].
|
||||||
///
|
///
|
||||||
/// If this error is allowed to bubble up into Python code it will raise a `RuntimeError`.
|
/// If this error is allowed to bubble up into Python code it will raise a `RuntimeError`.
|
||||||
pub struct PyBorrowError {
|
pub struct PyBorrowError {
|
||||||
|
@ -969,7 +977,7 @@ impl From<PyBorrowError> for PyErr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An error type returned by [`PyCell::try_borrow_mut`].
|
/// An error type returned by [`Bound::try_borrow_mut`].
|
||||||
///
|
///
|
||||||
/// If this error is allowed to bubble up into Python code it will raise a `RuntimeError`.
|
/// If this error is allowed to bubble up into Python code it will raise a `RuntimeError`.
|
||||||
pub struct PyBorrowMutError {
|
pub struct PyBorrowMutError {
|
||||||
|
|
|
@ -74,6 +74,7 @@ pub trait PyClassBorrowChecker {
|
||||||
/// Increments immutable borrow count, if possible
|
/// Increments immutable borrow count, if possible
|
||||||
fn try_borrow(&self) -> Result<(), PyBorrowError>;
|
fn try_borrow(&self) -> Result<(), PyBorrowError>;
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
fn try_borrow_unguarded(&self) -> Result<(), PyBorrowError>;
|
fn try_borrow_unguarded(&self) -> Result<(), PyBorrowError>;
|
||||||
|
|
||||||
/// Decrements immutable borrow count
|
/// Decrements immutable borrow count
|
||||||
|
@ -96,6 +97,7 @@ impl PyClassBorrowChecker for EmptySlot {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
fn try_borrow_unguarded(&self) -> Result<(), PyBorrowError> {
|
fn try_borrow_unguarded(&self) -> Result<(), PyBorrowError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -130,6 +132,7 @@ impl PyClassBorrowChecker for BorrowChecker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
fn try_borrow_unguarded(&self) -> Result<(), PyBorrowError> {
|
fn try_borrow_unguarded(&self) -> Result<(), PyBorrowError> {
|
||||||
let flag = self.0.get();
|
let flag = self.0.get();
|
||||||
if flag != BorrowFlag::HAS_MUTABLE_BORROW {
|
if flag != BorrowFlag::HAS_MUTABLE_BORROW {
|
||||||
|
|
|
@ -16,6 +16,7 @@ pub use self::gc::{PyTraverseError, PyVisit};
|
||||||
/// The `#[pyclass]` attribute implements this trait for your Rust struct -
|
/// The `#[pyclass]` attribute implements this trait for your Rust struct -
|
||||||
/// you shouldn't implement this trait directly.
|
/// you shouldn't implement this trait directly.
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub trait PyClass: PyTypeInfo<AsRefTarget = crate::PyCell<Self>> + PyClassImpl {
|
pub trait PyClass: PyTypeInfo<AsRefTarget = crate::PyCell<Self>> + PyClassImpl {
|
||||||
/// Whether the pyclass is frozen.
|
/// Whether the pyclass is frozen.
|
||||||
///
|
///
|
||||||
|
@ -23,6 +24,18 @@ pub trait PyClass: PyTypeInfo<AsRefTarget = crate::PyCell<Self>> + PyClassImpl {
|
||||||
type Frozen: Frozen;
|
type Frozen: Frozen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Types that can be used as Python classes.
|
||||||
|
///
|
||||||
|
/// The `#[pyclass]` attribute implements this trait for your Rust struct -
|
||||||
|
/// you shouldn't implement this trait directly.
|
||||||
|
#[cfg(not(feature = "gil-refs"))]
|
||||||
|
pub trait PyClass: PyTypeInfo + PyClassImpl {
|
||||||
|
/// Whether the pyclass is frozen.
|
||||||
|
///
|
||||||
|
/// This can be enabled via `#[pyclass(frozen)]`.
|
||||||
|
type Frozen: Frozen;
|
||||||
|
}
|
||||||
|
|
||||||
/// Operators for the `__richcmp__` method
|
/// Operators for the `__richcmp__` method
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum CompareOp {
|
pub enum CompareOp {
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
use crate::ffi_ptr_ext::FfiPtrExt;
|
use crate::ffi_ptr_ext::FfiPtrExt;
|
||||||
use crate::types::any::PyAnyMethods;
|
use crate::types::any::PyAnyMethods;
|
||||||
use crate::types::{PyAny, PyType};
|
use crate::types::{PyAny, PyType};
|
||||||
use crate::{ffi, Bound, PyNativeType, Python};
|
#[cfg(feature = "gil-refs")]
|
||||||
|
use crate::PyNativeType;
|
||||||
|
use crate::{ffi, Bound, Python};
|
||||||
|
|
||||||
/// `T: PyLayout<U>` represents that `T` is a concrete representation of `U` in the Python heap.
|
/// `T: PyLayout<U>` represents that `T` is a concrete representation of `U` in the Python heap.
|
||||||
/// E.g., `PyClassObject` is a concrete representation of all `pyclass`es, and `ffi::PyObject`
|
/// E.g., `PyClassObject` is a concrete representation of all `pyclass`es, and `ffi::PyObject`
|
||||||
|
@ -29,11 +31,13 @@ pub trait PySizedLayout<T>: PyLayout<T> + Sized {}
|
||||||
///
|
///
|
||||||
/// - `Py<Self>::as_ref` will hand out references to `Self::AsRefTarget`.
|
/// - `Py<Self>::as_ref` will hand out references to `Self::AsRefTarget`.
|
||||||
/// - `Self::AsRefTarget` must have the same layout as `UnsafeCell<ffi::PyAny>`.
|
/// - `Self::AsRefTarget` must have the same layout as `UnsafeCell<ffi::PyAny>`.
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub unsafe trait HasPyGilRef {
|
pub unsafe trait HasPyGilRef {
|
||||||
/// Utility type to make Py::as_ref work.
|
/// Utility type to make Py::as_ref work.
|
||||||
type AsRefTarget: PyNativeType;
|
type AsRefTarget: PyNativeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
unsafe impl<T> HasPyGilRef for T
|
unsafe impl<T> HasPyGilRef for T
|
||||||
where
|
where
|
||||||
T: PyNativeType,
|
T: PyNativeType,
|
||||||
|
@ -54,6 +58,7 @@ where
|
||||||
///
|
///
|
||||||
/// Implementations must provide an implementation for `type_object_raw` which infallibly produces a
|
/// Implementations must provide an implementation for `type_object_raw` which infallibly produces a
|
||||||
/// non-null pointer to the corresponding Python type object.
|
/// non-null pointer to the corresponding Python type object.
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub unsafe trait PyTypeInfo: Sized + HasPyGilRef {
|
pub unsafe trait PyTypeInfo: Sized + HasPyGilRef {
|
||||||
/// Class name.
|
/// Class name.
|
||||||
const NAME: &'static str;
|
const NAME: &'static str;
|
||||||
|
@ -132,7 +137,62 @@ pub unsafe trait PyTypeInfo: Sized + HasPyGilRef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Python type information.
|
||||||
|
/// All Python native types (e.g., `PyDict`) and `#[pyclass]` structs implement this trait.
|
||||||
|
///
|
||||||
|
/// This trait is marked unsafe because:
|
||||||
|
/// - specifying the incorrect layout can lead to memory errors
|
||||||
|
/// - the return value of type_object must always point to the same PyTypeObject instance
|
||||||
|
///
|
||||||
|
/// It is safely implemented by the `pyclass` macro.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// Implementations must provide an implementation for `type_object_raw` which infallibly produces a
|
||||||
|
/// non-null pointer to the corresponding Python type object.
|
||||||
|
#[cfg(not(feature = "gil-refs"))]
|
||||||
|
pub unsafe trait PyTypeInfo: Sized {
|
||||||
|
/// Class name.
|
||||||
|
const NAME: &'static str;
|
||||||
|
|
||||||
|
/// Module name, if any.
|
||||||
|
const MODULE: Option<&'static str>;
|
||||||
|
|
||||||
|
/// Returns the PyTypeObject instance for this type.
|
||||||
|
fn type_object_raw(py: Python<'_>) -> *mut ffi::PyTypeObject;
|
||||||
|
|
||||||
|
/// Returns the safe abstraction over the type object.
|
||||||
|
#[inline]
|
||||||
|
fn type_object_bound(py: Python<'_>) -> Bound<'_, PyType> {
|
||||||
|
// Making the borrowed object `Bound` is necessary for soundness reasons. It's an extreme
|
||||||
|
// edge case, but arbitrary Python code _could_ change the __class__ of an object and cause
|
||||||
|
// the type object to be freed.
|
||||||
|
//
|
||||||
|
// By making `Bound` we assume ownership which is then safe against races.
|
||||||
|
unsafe {
|
||||||
|
Self::type_object_raw(py)
|
||||||
|
.cast::<ffi::PyObject>()
|
||||||
|
.assume_borrowed_unchecked(py)
|
||||||
|
.to_owned()
|
||||||
|
.downcast_into_unchecked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks if `object` is an instance of this type or a subclass of this type.
|
||||||
|
#[inline]
|
||||||
|
fn is_type_of_bound(object: &Bound<'_, PyAny>) -> bool {
|
||||||
|
unsafe { ffi::PyObject_TypeCheck(object.as_ptr(), Self::type_object_raw(object.py())) != 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks if `object` is an instance of this type.
|
||||||
|
#[inline]
|
||||||
|
fn is_exact_type_of_bound(object: &Bound<'_, PyAny>) -> bool {
|
||||||
|
unsafe { ffi::Py_TYPE(object.as_ptr()) == Self::type_object_raw(object.py()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Implemented by types which can be used as a concrete Python type inside `Py<T>` smart pointers.
|
/// Implemented by types which can be used as a concrete Python type inside `Py<T>` smart pointers.
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub trait PyTypeCheck: HasPyGilRef {
|
pub trait PyTypeCheck: HasPyGilRef {
|
||||||
/// Name of self. This is used in error messages, for example.
|
/// Name of self. This is used in error messages, for example.
|
||||||
const NAME: &'static str;
|
const NAME: &'static str;
|
||||||
|
@ -143,6 +203,18 @@ pub trait PyTypeCheck: HasPyGilRef {
|
||||||
fn type_check(object: &Bound<'_, PyAny>) -> bool;
|
fn type_check(object: &Bound<'_, PyAny>) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Implemented by types which can be used as a concrete Python type inside `Py<T>` smart pointers.
|
||||||
|
#[cfg(not(feature = "gil-refs"))]
|
||||||
|
pub trait PyTypeCheck {
|
||||||
|
/// Name of self. This is used in error messages, for example.
|
||||||
|
const NAME: &'static str;
|
||||||
|
|
||||||
|
/// Checks if `object` is an instance of `Self`, which may include a subtype.
|
||||||
|
///
|
||||||
|
/// This should be equivalent to the Python expression `isinstance(object, Self)`.
|
||||||
|
fn type_check(object: &Bound<'_, PyAny>) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> PyTypeCheck for T
|
impl<T> PyTypeCheck for T
|
||||||
where
|
where
|
||||||
T: PyTypeInfo,
|
T: PyTypeInfo,
|
||||||
|
|
|
@ -1646,7 +1646,7 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed {
|
||||||
/// Extracts some type from the Python object.
|
/// Extracts some type from the Python object.
|
||||||
///
|
///
|
||||||
/// This is a wrapper function around
|
/// This is a wrapper function around
|
||||||
/// [`FromPyObject::extract()`](crate::FromPyObject::extract).
|
/// [`FromPyObject::extract_bound()`](crate::FromPyObject::extract_bound).
|
||||||
fn extract<'a, T>(&'a self) -> PyResult<T>
|
fn extract<'a, T>(&'a self) -> PyResult<T>
|
||||||
where
|
where
|
||||||
T: FromPyObjectBound<'a, 'py>;
|
T: FromPyObjectBound<'a, 'py>;
|
||||||
|
|
|
@ -122,10 +122,12 @@ pub trait DerefToPyAny {
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! pyobject_native_type_base(
|
macro_rules! pyobject_native_type_base(
|
||||||
($name:ty $(;$generics:ident)* ) => {
|
($name:ty $(;$generics:ident)* ) => {
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
unsafe impl<$($generics,)*> $crate::PyNativeType for $name {
|
unsafe impl<$($generics,)*> $crate::PyNativeType for $name {
|
||||||
type AsRefSource = Self;
|
type AsRefSource = Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<$($generics,)*> ::std::fmt::Debug for $name {
|
impl<$($generics,)*> ::std::fmt::Debug for $name {
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>)
|
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>)
|
||||||
-> ::std::result::Result<(), ::std::fmt::Error>
|
-> ::std::result::Result<(), ::std::fmt::Error>
|
||||||
|
@ -136,6 +138,7 @@ macro_rules! pyobject_native_type_base(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<$($generics,)*> ::std::fmt::Display for $name {
|
impl<$($generics,)*> ::std::fmt::Display for $name {
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>)
|
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>)
|
||||||
-> ::std::result::Result<(), ::std::fmt::Error>
|
-> ::std::result::Result<(), ::std::fmt::Error>
|
||||||
|
|
|
@ -14,7 +14,7 @@ fn test_compile_errors() {
|
||||||
#[cfg(any(not(Py_LIMITED_API), Py_3_11))]
|
#[cfg(any(not(Py_LIMITED_API), Py_3_11))]
|
||||||
t.compile_fail("tests/ui/invalid_pymethods_buffer.rs");
|
t.compile_fail("tests/ui/invalid_pymethods_buffer.rs");
|
||||||
// The output is not stable across abi3 / not abi3 and features
|
// The output is not stable across abi3 / not abi3 and features
|
||||||
#[cfg(all(not(Py_LIMITED_API), feature = "full"))]
|
#[cfg(all(not(Py_LIMITED_API), feature = "full", not(feature = "gil-refs")))]
|
||||||
t.compile_fail("tests/ui/invalid_pymethods_duplicates.rs");
|
t.compile_fail("tests/ui/invalid_pymethods_duplicates.rs");
|
||||||
t.compile_fail("tests/ui/invalid_pymethod_enum.rs");
|
t.compile_fail("tests/ui/invalid_pymethod_enum.rs");
|
||||||
t.compile_fail("tests/ui/invalid_pymethod_names.rs");
|
t.compile_fail("tests/ui/invalid_pymethod_names.rs");
|
||||||
|
@ -27,12 +27,14 @@ fn test_compile_errors() {
|
||||||
t.compile_fail("tests/ui/invalid_argument_attributes.rs");
|
t.compile_fail("tests/ui/invalid_argument_attributes.rs");
|
||||||
t.compile_fail("tests/ui/invalid_frompy_derive.rs");
|
t.compile_fail("tests/ui/invalid_frompy_derive.rs");
|
||||||
t.compile_fail("tests/ui/static_ref.rs");
|
t.compile_fail("tests/ui/static_ref.rs");
|
||||||
|
#[cfg(not(feature = "gil-refs"))]
|
||||||
t.compile_fail("tests/ui/wrong_aspyref_lifetimes.rs");
|
t.compile_fail("tests/ui/wrong_aspyref_lifetimes.rs");
|
||||||
t.compile_fail("tests/ui/invalid_pyfunctions.rs");
|
t.compile_fail("tests/ui/invalid_pyfunctions.rs");
|
||||||
t.compile_fail("tests/ui/invalid_pymethods.rs");
|
t.compile_fail("tests/ui/invalid_pymethods.rs");
|
||||||
// output changes with async feature
|
// output changes with async feature
|
||||||
#[cfg(all(Py_LIMITED_API, feature = "experimental-async"))]
|
#[cfg(all(Py_LIMITED_API, feature = "experimental-async"))]
|
||||||
t.compile_fail("tests/ui/abi3_nativetype_inheritance.rs");
|
t.compile_fail("tests/ui/abi3_nativetype_inheritance.rs");
|
||||||
|
#[cfg(not(feature = "gil-refs"))]
|
||||||
t.compile_fail("tests/ui/invalid_intern_arg.rs");
|
t.compile_fail("tests/ui/invalid_intern_arg.rs");
|
||||||
t.compile_fail("tests/ui/invalid_frozen_pyclass_borrow.rs");
|
t.compile_fail("tests/ui/invalid_frozen_pyclass_borrow.rs");
|
||||||
t.compile_fail("tests/ui/invalid_pymethod_receiver.rs");
|
t.compile_fail("tests/ui/invalid_pymethod_receiver.rs");
|
||||||
|
|
|
@ -34,6 +34,12 @@ error: use of deprecated constant `__pyfunction_pyfunction_option_4::SIGNATURE`:
|
||||||
138 | fn pyfunction_option_4(
|
138 | fn pyfunction_option_4(
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: use of deprecated struct `pyo3::PyCell`: `PyCell` was merged into `Bound`, use that instead; see the migration guide for more info
|
||||||
|
--> tests/ui/deprecations.rs:23:30
|
||||||
|
|
|
||||||
|
23 | fn method_gil_ref(_slf: &PyCell<Self>) {}
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
error: use of deprecated method `pyo3::deprecations::GilRefs::<T>::from_py_with_arg`: use `&Bound<'_, PyAny>` as the argument for this `from_py_with` extractor
|
error: use of deprecated method `pyo3::deprecations::GilRefs::<T>::from_py_with_arg`: use `&Bound<'_, PyAny>` as the argument for this `from_py_with` extractor
|
||||||
--> tests/ui/deprecations.rs:45:44
|
--> tests/ui/deprecations.rs:45:44
|
||||||
|
|
|
|
||||||
|
|
|
@ -13,5 +13,5 @@ error: lifetime may not live long enough
|
||||||
5 | Python::with_gil(|py| py.import_bound(pyo3::intern!(py, _foo)).unwrap());
|
5 | Python::with_gil(|py| py.import_bound(pyo3::intern!(py, _foo)).unwrap());
|
||||||
| --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
|
| --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
|
||||||
| | |
|
| | |
|
||||||
| | return type of closure is pyo3::Bound<'2, pyo3::prelude::PyModule>
|
| | return type of closure is pyo3::Bound<'2, PyModule>
|
||||||
| has type `pyo3::Python<'1>`
|
| has type `Python<'1>`
|
||||||
|
|
|
@ -26,23 +26,6 @@ error[E0277]: the trait bound `TwoNew: PyTypeInfo` is not satisfied
|
||||||
PyDate
|
PyDate
|
||||||
and $N others
|
and $N others
|
||||||
|
|
||||||
error[E0277]: the trait bound `TwoNew: HasPyGilRef` is not satisfied
|
|
||||||
--> tests/ui/invalid_pymethods_duplicates.rs:9:6
|
|
||||||
|
|
|
||||||
9 | impl TwoNew {
|
|
||||||
| ^^^^^^ the trait `PyNativeType` is not implemented for `TwoNew`, which is required by `TwoNew: HasPyGilRef`
|
|
||||||
|
|
|
||||||
= help: the trait `HasPyGilRef` is implemented for `pyo3::coroutine::Coroutine`
|
|
||||||
= note: required for `TwoNew` to implement `HasPyGilRef`
|
|
||||||
note: required by a bound in `pyo3::PyTypeInfo::NAME`
|
|
||||||
--> src/type_object.rs
|
|
||||||
|
|
|
||||||
| pub unsafe trait PyTypeInfo: Sized + HasPyGilRef {
|
|
||||||
| ^^^^^^^^^^^ required by this bound in `PyTypeInfo::NAME`
|
|
||||||
| /// Class name.
|
|
||||||
| const NAME: &'static str;
|
|
||||||
| ---- required by a bound in this associated constant
|
|
||||||
|
|
||||||
error[E0592]: duplicate definitions with name `__pymethod___new____`
|
error[E0592]: duplicate definitions with name `__pymethod___new____`
|
||||||
--> tests/ui/invalid_pymethods_duplicates.rs:8:1
|
--> tests/ui/invalid_pymethods_duplicates.rs:8:1
|
||||||
|
|
|
|
||||||
|
|
|
@ -5,4 +5,4 @@ error: lifetime may not live long enough
|
||||||
| --- ^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
|
| --- ^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
|
||||||
| | |
|
| | |
|
||||||
| | return type of closure is &'2 pyo3::Bound<'_, PyDict>
|
| | return type of closure is &'2 pyo3::Bound<'_, PyDict>
|
||||||
| has type `pyo3::Python<'1>`
|
| has type `Python<'1>`
|
||||||
|
|
Loading…
Reference in New Issue