Skip to content

Commit

Permalink
fix compile failure for getter with return lifetime of self
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed Jul 30, 2023
1 parent 79d5e4f commit 00a6ce6
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 20 deletions.
36 changes: 16 additions & 20 deletions pyo3-macros-backend/src/pymethod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ pub fn impl_py_getter_def(
let deprecations = property_type.deprecations();
let doc = property_type.doc();

let getter_impl = match property_type {
let body = match property_type {
PropertyType::Descriptor {
field_index, field, ..
} => {
Expand All @@ -629,31 +629,28 @@ pub fn impl_py_getter_def(
span: Span::call_site(),
}
.receiver(cls, ExtractErrorMode::Raise);
if let Some(ident) = &field.ident {
let field_token = if let Some(ident) = &field.ident {
// named struct field
quote!(::std::clone::Clone::clone(&(#slf.#ident)))
ident.to_token_stream()
} else {
// tuple struct field
let index = syn::Index::from(field_index);
quote!(::std::clone::Clone::clone(&(#slf.#index)))
}
}
PropertyType::Function {
spec, self_type, ..
} => impl_call_getter(cls, spec, self_type)?,
};

let conversion = match property_type {
PropertyType::Descriptor { .. } => {
syn::Index::from(field_index).to_token_stream()
};
quote! {
let item: _pyo3::Py<_pyo3::PyAny> = _pyo3::IntoPy::into_py(item, _py);
::std::result::Result::Ok(_pyo3::conversion::IntoPyPointer::into_ptr(item))
::std::result::Result::Ok(
_pyo3::conversion::IntoPyPointer::into_ptr(
_pyo3::IntoPy::<_pyo3::Py<_pyo3::PyAny>>::into_py(::std::clone::Clone::clone(&(#slf.#field_token)), _py)
)
)
}
}
// Forward to `IntoPyCallbackOutput`, to handle `#[getter]`s returning results.
PropertyType::Function { .. } => {
PropertyType::Function {
spec, self_type, ..
} => {
let call = impl_call_getter(cls, spec, self_type)?;
quote! {
_pyo3::callback::convert(_py, item)
_pyo3::callback::convert(_py, #call)
}
}
};
Expand Down Expand Up @@ -688,8 +685,7 @@ pub fn impl_py_getter_def(
_py: _pyo3::Python<'_>,
_slf: *mut _pyo3::ffi::PyObject
) -> _pyo3::PyResult<*mut _pyo3::ffi::PyObject> {
let item = #getter_impl;
#conversion
#body
}
};

Expand Down
20 changes: 20 additions & 0 deletions tests/test_getter_setter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,3 +216,23 @@ fn cell_getter_setter() {
);
});
}

#[test]
fn borrowed_value_with_lifetime_of_self() {
#[pyclass]
struct BorrowedValue {}

#[pymethods]
impl BorrowedValue {
#[getter]
fn value(&self) -> &str {
"value"
}
}

Python::with_gil(|py| {
let inst = Py::new(py, BorrowedValue {}).unwrap().to_object(py);

py_run!(py, inst, "assert inst.value == 'value'");
});
}

0 comments on commit 00a6ce6

Please sign in to comment.