-
Notifications
You must be signed in to change notification settings - Fork 806
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
create_exception: the trait bound MyError: pyo3::PyNativeType
is not satisfied
#4562
Comments
Thanks for the report. Can you please provide a more complete minimal reproduction? I cannot reproduce this locally. |
Before i got there i found the issue: The macro expands to:#[repr(transparent)]
#[allow(non_camel_case_types)]
#[doc = "Some description."]
pub struct MyError(::pyo3::PyAny);
#[allow(unknown_lints, non_local_definitions)]
#[cfg(feature = "gil-refs")]
impl ::std::convert::From<&MyError> for ::pyo3::PyErr {
#[inline]
fn from(err: &MyError) -> ::pyo3::PyErr {
#[allow(deprecated)]
::pyo3::PyErr::from_value(err)
}
}
impl MyError {
/// Creates a new [ `PyErr` ] of this type.
///
/// [`PyErr`] : https://docs.rs/pyo3/latest/pyo3/struct.PyErr.html "PyErr in pyo3"
#[inline]
#[allow(dead_code)]
pub fn new_err<A>(args: A) -> ::pyo3::PyErr
where
A: ::pyo3::PyErrArguments + ::std::marker::Send + ::std::marker::Sync + 'static,
{
::pyo3::PyErr::new::<MyError, A>(args)
}
}
#[cfg(feature = "gil-refs")]
impl ::std::error::Error for MyError {
fn source(&self) -> ::std::option::Option<&( dyn ::std::error::Error + 'static )> {
#[allow(unsafe_code)]
unsafe {
#[allow(deprecated)]
let cause: &::pyo3::exceptions::PyBaseException = self
.py()
.from_owned_ptr_or_opt(::pyo3::ffi::PyException_GetCause(self.as_ptr()))?;
::std::option::Option::Some(cause)
}
}
}
impl ::pyo3::ToPyErr for MyError {}
#[cfg(feature = "gil-refs")]
#[allow(unsafe_code)]
unsafe impl<> ::pyo3::PyNativeType for MyError {
type AsRefSource = Self;
}
#[cfg(feature = "gil-refs")]
impl<> ::std::fmt::Debug for MyError {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>)
-> ::std::result::Result<(), ::std::fmt::Error>
{
use ::pyo3::{PyNativeType, types::{PyAnyMethods, PyStringMethods}};
let s = self.as_borrowed().repr().or(::std::result::Result::Err(::std::fmt::Error))?;
f.write_str(&s.to_string_lossy())
}
}
#[cfg(feature = "gil-refs")]
impl<> ::std::fmt::Display for MyError {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>)
-> ::std::result::Result<(), ::std::fmt::Error>
{
use ::pyo3::{PyNativeType, types::{PyAnyMethods, PyStringMethods, PyTypeMethods}};
match self.as_borrowed().str() {
::std::result::Result::Ok(s) => return f.write_str(&s.to_string_lossy()),
::std::result::Result::Err(err) => err.write_unraisable_bound(self.py(), ::std::option::Option::Some(&self.as_borrowed())),
}
match self.as_borrowed().get_type().name() {
::std::result::Result::Ok(name) => ::std::write!(f, "<unprintable {} object>", name),
::std::result::Result::Err(_err) => f.write_str("<unprintable object>"),
}
}
}
#[cfg(feature = "gil-refs")]
impl<> ::pyo3::ToPyObject for MyError
{
#[inline]
fn to_object(&self, py: ::pyo3::Python<'_>) -> ::pyo3::PyObject {
#[allow(unsafe_code)]
unsafe { ::pyo3::PyObject::from_borrowed_ptr(py, self.as_ptr()) }
}
}
impl<> ::std::convert::AsRef<::pyo3::PyAny> for MyError {
#[inline]
fn as_ref(&self) -> &::pyo3::PyAny {
&self.0
}
}
impl<> ::std::ops::Deref for MyError {
type Target = ::pyo3::PyAny;
#[inline]
fn deref(&self) -> &::pyo3::PyAny {
&self.0
}
}
#[allow(unsafe_code)]
unsafe impl<> ::pyo3::AsPyPointer for MyError {
/// Gets the underlying FFI pointer, returns a borrowed pointer.
#[inline]
fn as_ptr(&self) -> *mut ::pyo3::ffi::PyObject {
self.0.as_ptr()
}
}
#[allow(unknown_lints, non_local_definitions)]
#[cfg(feature = "gil-refs")]
impl<> ::pyo3::IntoPy<::pyo3::Py<MyError>> for &'_ MyError {
#[inline]
fn into_py(self, py: ::pyo3::Python<'_>) -> ::pyo3::Py<MyError> {
#[allow(unsafe_code)]
unsafe { ::pyo3::Py::from_borrowed_ptr(py, self.as_ptr()) }
}
}
#[allow(unknown_lints, non_local_definitions)]
#[cfg(feature = "gil-refs")]
impl<> ::std::convert::From<&'_ MyError> for ::pyo3::Py<MyError> {
#[inline]
fn from(other: &MyError) -> Self {
use ::pyo3::PyNativeType;
#[allow(unsafe_code)]
unsafe { ::pyo3::Py::from_borrowed_ptr(other.py(), other.as_ptr()) }
}
}
#[allow(unknown_lints, non_local_definitions)]
#[cfg(feature = "gil-refs")]
impl<'a, > ::std::convert::From<&'a MyError> for &'a ::pyo3::PyAny {
fn from(ob: &'a MyError) -> Self {
#[allow(unsafe_code)]
unsafe { &*(ob as *const MyError as *const ::pyo3::PyAny) }
}
}
impl ::pyo3::types::DerefToPyAny for MyError {}
#[allow(unsafe_code)]
unsafe impl<> ::pyo3::type_object::PyTypeInfo for MyError {
const NAME: &'static str = "MyError";
const MODULE: ::std::option::Option<&'static str> = (::std::option::Option::Some("my_module")
);
#[inline]
#[allow(clippy::redundant_closure_call)]
fn type_object_raw(py: ::pyo3::Python<'_>) -> *mut ::pyo3::ffi::PyTypeObject {
MyError::type_object_raw(py)
}
}
impl MyError {
#[doc(hidden)]
pub const _PYO3_DEF: ::pyo3::impl_::pymodule::AddTypeToModule<Self> = ::pyo3::impl_::pymodule::AddTypeToModule::new();
}
#[allow(unknown_lints, non_local_definitions)]
#[cfg(feature = "gil-refs")]
impl<'py, > ::pyo3::FromPyObject<'py> for &'py MyError {
#[inline]
fn extract_bound(obj: &::pyo3::Bound<'py, ::pyo3::PyAny>) -> ::pyo3::PyResult<Self> {
::std::clone::Clone::clone(obj).into_gil_ref().downcast().map_err(::std::convert::Into::into)
}
}
impl MyError {
fn type_object_raw(py: ::pyo3::Python<'_>) -> *mut ::pyo3::ffi::PyTypeObject {
use ::pyo3::sync::GILOnceCell;
static TYPE_OBJECT: GILOnceCell<::pyo3::Py<::pyo3::types::PyType>> =
GILOnceCell::new();
TYPE_OBJECT
.get_or_init(py, ||
::pyo3::PyErr::new_type_bound(
py,
"my_module.MyError",
(::std::option::Option::Some("Some description.")
),
::std::option::Option::Some(&py.get_type_bound::<PyException>()),
::std::option::Option::None,
).expect("Failed to initialize new exception type."),
).as_ptr() as *mut ::pyo3::ffi::PyTypeObject
}
}
|
Thanks for debugging, that makes a lot of sense. I think the fix is that we have to rework to have two copies of the macros, which have the Note also that you should probably aim to stop using the |
Fixed in #4589 / to be released in 0.22.4 |
Bug Description
while migrating to pyo3 0.22.3 the declared exceptions were no longer compiling due to a missing trait bound
Steps to Reproduce
create_exception!(my_module, MyError, PyException, "Some description.");
Backtrace
Your operating system and version
Windows 10
Your Python version (
python --version
)3.12
Your Rust version (
rustc --version
)1.75
Your PyO3 version
0.22
How did you install python? Did you use a virtualenv?
python is not required to reproduce the issue
Additional Info
No response
The text was updated successfully, but these errors were encountered: