Skip to content
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

How to wrap a struct with lifetime parameter? #502

Closed
lochbrunner opened this issue Jun 3, 2019 · 8 comments
Closed

How to wrap a struct with lifetime parameter? #502

lochbrunner opened this issue Jun 3, 2019 · 8 comments

Comments

@lochbrunner
Copy link
Contributor

🐛 Bug Reports

This is different to issue 246.

🌍 Environment

  • Your operating system and version: 4.15.0-50-generic Add PyDict::iter #54-Ubuntu SMP
  • Your python version: Python 3.6.8
  • How did you install python (e.g. apt or pyenv)? Did you use a virtualenv?: Anaconda 64bit
  • Your rust version (rustc --version): rustc 1.34.0-nightly (e1c6d0057 2019-02-22)
  • Are you using the latest pyo3 version? Have you tried using latest master (replace version = "0.x.y" with git = "https://github.com/PyO3/pyo3")? version: 0.7.0

💥 Reproducing

When using a struct with lifetime as follow:

use pyo3::prelude::*;

#[pyclass]
struct MyClass<'a> {
    r: &'a u32,
}

results in the compiler error:

error[E0106]: missing lifetime specifier
--> pycore/src/trace.rs:114:8
|
114 | struct MyClass<'a> {
| ^^^^^^^ expected lifetime parameter
error: aborting due to previous error

Using dependency:

[dependencies]
pyo3 = {version = "0.7.0", features = ["extension-module"]}
@kngwyu
Copy link
Member

kngwyu commented Jun 4, 2019

It's not allowed now since it's really difficult to handle the lifetime from Python side.

@birkenfeld
Copy link
Member

birkenfeld commented Jun 4, 2019

For illustration, the issue is that as a pyclass, the object has to be able to be passed into Python code. For that, it has to be put onto the Python heap, at which point the lifetime is out of control of Rust and the borrow checker. It can be kept alive potentially indefinitely by Python references.

@birkenfeld
Copy link
Member

That said, the error could be a lot clearer :)

@kngwyu
Copy link
Member

kngwyu commented Jun 4, 2019

That said, the error could be a lot clearer :)

Agreed 👍

@lochbrunner
Copy link
Contributor Author

@birkenfeld I thought so already...

@konstin
Copy link
Member

konstin commented Jul 15, 2019

PR with better error message has been merged

@chrisrossi
Copy link

Is there a workaround for the fundamental issue here? If I need to wrap a struct from a pure-Rust library that uses lifetimes, how do I do that, short of rewriting the pure-Rust library to work within PyO3 limitations? Is there some clever hack/indirection to get around this limitation?

@adamreichold
Copy link
Member

You could only unsafely transmute MyStruct<'a> into MyStruct<'static> and store that inside a #[pyclass]. Of course, it will then be your responsibility to ensure that the correct lifetimes will be applied during usage. (Generally speaking, this seems unlikely to work as the lifetime 'a in MyStruct<'a> suggests that it references data stored elsewhere. This relationship can just not be managed automatically using the Python heap.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants