Merge pull request #1997 from davidhewitt/get-panic
macros: fix panic in __get__ implementation
This commit is contained in:
commit
e790d55304
|
@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Fix use of `catch_unwind` in `allow_threads` which can cause fatal crashes. [#1989](https://github.com/PyO3/pyo3/pull/1989)
|
||||
- Fix build failure on PyPy when abi3 features are activated. [#1991](https://github.com/PyO3/pyo3/pull/1991)
|
||||
- Fix mingw platform detection. [#1993](https://github.com/PyO3/pyo3/pull/1993)
|
||||
- Fix panic in `__get__` implementation when accessing descriptor on type object. [#1997](https://github.com/PyO3/pyo3/pull/1997)
|
||||
|
||||
## [0.15.0] - 2021-11-03
|
||||
|
||||
|
|
|
@ -483,8 +483,8 @@ const __HASH__: SlotDef = SlotDef::new("Py_tp_hash", "hashfunc")
|
|||
const __RICHCMP__: SlotDef = SlotDef::new("Py_tp_richcompare", "richcmpfunc")
|
||||
.extract_error_mode(ExtractErrorMode::NotImplemented)
|
||||
.arguments(&[Ty::Object, Ty::CompareOp]);
|
||||
const __GET__: SlotDef =
|
||||
SlotDef::new("Py_tp_descr_get", "descrgetfunc").arguments(&[Ty::Object, Ty::Object]);
|
||||
const __GET__: SlotDef = SlotDef::new("Py_tp_descr_get", "descrgetfunc")
|
||||
.arguments(&[Ty::MaybeNullObject, Ty::MaybeNullObject]);
|
||||
const __ITER__: SlotDef = SlotDef::new("Py_tp_iter", "getiterfunc");
|
||||
const __NEXT__: SlotDef = SlotDef::new("Py_tp_iternext", "iternextfunc").return_conversion(
|
||||
TokenGenerator(|| quote! { ::pyo3::class::iter::IterNextOutput::<_, _> }),
|
||||
|
@ -606,6 +606,7 @@ fn pyproto(method_name: &str) -> Option<&'static SlotDef> {
|
|||
#[derive(Clone, Copy)]
|
||||
enum Ty {
|
||||
Object,
|
||||
MaybeNullObject,
|
||||
NonNullObject,
|
||||
CompareOp,
|
||||
Int,
|
||||
|
@ -617,7 +618,7 @@ enum Ty {
|
|||
impl Ty {
|
||||
fn ffi_type(self) -> TokenStream {
|
||||
match self {
|
||||
Ty::Object => quote! { *mut ::pyo3::ffi::PyObject },
|
||||
Ty::Object | Ty::MaybeNullObject => quote! { *mut ::pyo3::ffi::PyObject },
|
||||
Ty::NonNullObject => quote! { ::std::ptr::NonNull<::pyo3::ffi::PyObject> },
|
||||
Ty::Int | Ty::CompareOp => quote! { ::std::os::raw::c_int },
|
||||
Ty::PyHashT => quote! { ::pyo3::ffi::Py_hash_t },
|
||||
|
@ -645,6 +646,22 @@ impl Ty {
|
|||
);
|
||||
extract_object(cls, arg.ty, ident, extract)
|
||||
}
|
||||
Ty::MaybeNullObject => {
|
||||
let extract = handle_error(
|
||||
extract_error_mode,
|
||||
py,
|
||||
quote! {
|
||||
#py.from_borrowed_ptr::<::pyo3::PyAny>(
|
||||
if #ident.is_null() {
|
||||
::pyo3::ffi::Py_None()
|
||||
} else {
|
||||
#ident
|
||||
}
|
||||
).extract()
|
||||
},
|
||||
);
|
||||
extract_object(cls, arg.ty, ident, extract)
|
||||
}
|
||||
Ty::NonNullObject => {
|
||||
let extract = handle_error(
|
||||
extract_error_mode,
|
||||
|
|
|
@ -548,11 +548,23 @@ fn descr_getset() {
|
|||
r#"
|
||||
class Class:
|
||||
counter = Counter()
|
||||
|
||||
# access via type
|
||||
counter = Class.counter
|
||||
assert counter.count == 1
|
||||
|
||||
# access with instance directly
|
||||
assert Counter.__get__(counter, Class()).count == 2
|
||||
|
||||
# access via instance
|
||||
c = Class()
|
||||
c.counter # count += 1
|
||||
assert c.counter.count == 2
|
||||
c.counter = Counter()
|
||||
assert c.counter.count == 3
|
||||
|
||||
# __set__
|
||||
c.counter = Counter()
|
||||
assert c.counter.count == 4
|
||||
|
||||
# __delete__
|
||||
del c.counter
|
||||
assert c.counter.count == 1
|
||||
"#
|
||||
|
|
Loading…
Reference in New Issue