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

Rayon + PyO3 piece #74

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft

Rayon + PyO3 piece #74

wants to merge 1 commit into from

Conversation

prrao87
Copy link
Member

@prrao87 prrao87 commented Feb 29, 2024

Hi @sanders41, I needed your help with this issue I'm facing. I think I'm not handling errors/exceptions correctly in PyO3 as I pass Rust objects back to Python. I'm facing a trait bound error that I'm not sure how to go about fixing.

If you see the lib.rs in this branch, the compiler complains about the following:

error[E0277]: the trait bound `Result<Vec<RecordProcessed>, PyErr>: OkWrap<_>` is not satisfied
  --> src/pyo3_rayon/src/lib.rs:48:1
   |
48 | #[pyfunction(signature = (records))]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `OkWrap<_>` is not implemented for `Result<Vec<RecordProcessed>, PyErr>`
   |
   = help: the trait `OkWrap<T>` is implemented for `Result<T, E>`

Goal

What I'm trying to accomplish is a bit more than the basic "provide a list of Python file strings as input and get a new set of files as output".

In this piece, I'm trying to make the input to the Rust module a little more generic: I'd like to accept a list of dicts (converted to a type-safe Vec of Records on the Rust end). That way, when calling this function from Python, it doesn't matter whether we obtained the list of dicts in Python from raw files or from a database.

That's why the Rust get_pronoun_counts function signature is set to Vec<Record> instead of a file like in the pure-Rust version.

Here's the Python file I'm trying to run to test whether this logic works:

from pyo3_rayon import get_pronoun_counts


def main() -> None:
    content = (
        "She says she spoke to him about this many times, but he's proving to be quite adamant."
    )
    obj = [{"id": 1, "content": content}]
    result_obj = get_pronoun_counts(obj)
    print(result_obj)


if __name__ == "__main__":
    main()

Expected result

[{"id": 1, "n_m": 2, "n_f": 2}]

Would you be able to take a look and let me know what I'm missing? Thanks!

@sanders41
Copy link
Collaborator

I believe there are a few things going on here and a few different ways to fix it. The structs map to python classes with pyclass, but they are being used as dictionaries here. I fixed the trait error by returning a PyDict instead of RecordProcessed. After doing that the program will compile, but running it with the Python code results in an error AttributeError: 'dict' object has no attribute 'id' because it is expecting a Record class instead of a dict.

So, I believe either passing PyDict into and out of the function, or passing instances of Record and returning instances of RecordProcessed would fix the issue.

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

Successfully merging this pull request may close these issues.

2 participants