Inhibit subclassing native types with ABI3 set
This commit is contained in:
parent
c07e1aa40a
commit
7644d67ad8
|
@ -103,6 +103,8 @@ macro_rules! pyobject_native_type_core {
|
|||
#[macro_export]
|
||||
macro_rules! pyobject_native_type_sized {
|
||||
($name: ty, $layout: path $(,$type_param: ident)*) => {
|
||||
// To prevent inheriting native types with ABI3
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
impl $crate::type_object::PySizedLayout<$name> for $layout {}
|
||||
impl<'a, $($type_param,)*> $crate::derive_utils::PyBaseTypeUtils for $name {
|
||||
type Dict = $crate::pyclass_slots::PyClassDummySlot;
|
||||
|
|
|
@ -11,6 +11,9 @@ fn test_compile_errors() {
|
|||
t.compile_fail("tests/ui/reject_generics.rs");
|
||||
t.compile_fail("tests/ui/wrong_aspyref_lifetimes.rs");
|
||||
|
||||
#[cfg(Py_LIMITED_API)]
|
||||
t.compile_fail("tests/ui/abi3_nativetype_inheritance.rs");
|
||||
|
||||
tests_rust_1_43(&t);
|
||||
tests_rust_1_46(&t);
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ use pyo3::py_run;
|
|||
|
||||
use pyo3::types::IntoPyDict;
|
||||
|
||||
use pyo3::types::{PyDict, PySet};
|
||||
mod common;
|
||||
|
||||
#[pyclass(subclass)]
|
||||
|
@ -153,60 +152,63 @@ except Exception as e:
|
|||
);
|
||||
}
|
||||
|
||||
#[pyclass(extends=PySet)]
|
||||
#[derive(Debug)]
|
||||
struct SetWithName {
|
||||
#[pyo3(get(name))]
|
||||
_name: &'static str,
|
||||
}
|
||||
// Subclassing builtin types is not allowed in the LIMITED API.
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
mod inheriting_native_type {
|
||||
use super::*;
|
||||
use pyo3::types::{PyDict, PySet};
|
||||
|
||||
#[pymethods]
|
||||
impl SetWithName {
|
||||
#[new]
|
||||
fn new() -> Self {
|
||||
SetWithName { _name: "Hello :)" }
|
||||
#[pyclass(extends=PySet)]
|
||||
#[derive(Debug)]
|
||||
struct SetWithName {
|
||||
#[pyo3(get(name))]
|
||||
_name: &'static str,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl SetWithName {
|
||||
#[new]
|
||||
fn new() -> Self {
|
||||
SetWithName { _name: "Hello :)" }
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inherit_set() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let set_sub = pyo3::PyCell::new(py, SetWithName::new()).unwrap();
|
||||
py_run!(
|
||||
py,
|
||||
set_sub,
|
||||
r#"set_sub.add(10); assert list(set_sub) == [10]; assert set_sub._name == "Hello :)""#
|
||||
);
|
||||
}
|
||||
|
||||
#[pyclass(extends=PyDict)]
|
||||
#[derive(Debug)]
|
||||
struct DictWithName {
|
||||
#[pyo3(get(name))]
|
||||
_name: &'static str,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl DictWithName {
|
||||
#[new]
|
||||
fn new() -> Self {
|
||||
DictWithName { _name: "Hello :)" }
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inherit_dict() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let dict_sub = pyo3::PyCell::new(py, DictWithName::new()).unwrap();
|
||||
py_run!(
|
||||
py,
|
||||
dict_sub,
|
||||
r#"dict_sub[0] = 1; assert dict_sub[0] == 1; assert dict_sub._name == "Hello :)""#
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Subclassing builtin types is not allowed in the LIMITED API.
|
||||
#[test]
|
||||
#[cfg_attr(Py_LIMITED_API, should_panic)]
|
||||
fn inherit_set() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let set_sub = pyo3::PyCell::new(py, SetWithName::new()).unwrap();
|
||||
py_run!(
|
||||
py,
|
||||
set_sub,
|
||||
r#"set_sub.add(10); assert list(set_sub) == [10]; assert set_sub._name == "Hello :)""#
|
||||
);
|
||||
}
|
||||
|
||||
#[pyclass(extends=PyDict)]
|
||||
#[derive(Debug)]
|
||||
struct DictWithName {
|
||||
#[pyo3(get(name))]
|
||||
_name: &'static str,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl DictWithName {
|
||||
#[new]
|
||||
fn new() -> Self {
|
||||
DictWithName { _name: "Hello :)" }
|
||||
}
|
||||
}
|
||||
|
||||
// Subclassing builtin types is not allowed in the LIMITED API.
|
||||
#[test]
|
||||
#[cfg_attr(Py_LIMITED_API, should_panic)]
|
||||
fn inherit_dict() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let dict_sub = pyo3::PyCell::new(py, DictWithName::new()).unwrap();
|
||||
py_run!(
|
||||
py,
|
||||
dict_sub,
|
||||
r#"dict_sub[0] = 1; assert dict_sub[0] == 1; assert dict_sub._name == "Hello :)""#
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
use pyo3::prelude::*;
|
||||
use pyo3::types::PyDict;
|
||||
|
||||
#[pyclass(extends=PyDict)]
|
||||
struct TestClass {}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,13 @@
|
|||
error[E0277]: the trait bound `pyo3::ffi::dictobject::PyDictObject: pyo3::type_object::PySizedLayout<pyo3::types::dict::PyDict>` is not satisfied
|
||||
--> $DIR/abi3_nativetype_inheritance.rs:4:1
|
||||
|
|
||||
4 | #[pyclass(extends=PyDict)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `pyo3::type_object::PySizedLayout<pyo3::types::dict::PyDict>` is not implemented for `pyo3::ffi::dictobject::PyDictObject`
|
||||
|
|
||||
::: $WORKSPACE/src/type_object.rs:96:22
|
||||
|
|
||||
96 | type BaseLayout: PySizedLayout<Self::BaseType>;
|
||||
| ----------------------------- required by this bound in `pyo3::type_object::PyTypeInfo`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `pyo3::type_object::PySizedLayout<pyo3::types::dict::PyDict>` for `pyo3::pycell::PyCellBase<pyo3::types::dict::PyDict>`
|
||||
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
Loading…
Reference in New Issue