-
Notifications
You must be signed in to change notification settings - Fork 770
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
Add from_py_with attribute #1411
Conversation
Just bikeshedding: would you consider 'from_py'? It's even more succinct and I think "with" is pretty clear once you add the equals sign.
… On 1 Feb 2021, at 10:47 PM, Daniil Konovalenko ***@***.***> wrote:
This PR addresses #1239.
It adds a #[pyo3(from_py_with = "function")] attribute that allows to customize conversion between Python-native and Rust-native types.
At the moment only argument attributes are supported. I plan on adding support for derive in the near future.
I've made a couple of design decisions along the way, that can be changed if needed:
I chose from_py_with instead of from_python_with from the original proposal because it was shorter to type. Also it goes well with the trait name FromPyObject.
The path to the conversion function is quoted instead of being a raw identifier, mainly because serde does this. If there are any reasons it shouldn't be quoted, please let me know.
TODO:
support from_python_with in derive(FromPyObject)
refactor parse_arg_attributes into smaller functions
add tests with usage in #[pymethods]
add tests for errors
add a CHANGELOG entry
add docs
You can view, comment on, or merge this pull request online at:
#1411
Commit Summary
implement draft of from_py_with for function arguments
add a test
File Changes
M pyo3-macros-backend/src/method.rs (43)
M pyo3-macros-backend/src/module.rs (11)
M pyo3-macros-backend/src/pyfunction.rs (46)
M pyo3-macros-backend/src/pymethod.rs (10)
M pyo3-macros-backend/src/pyproto.rs (6)
M tests/test_pyfunction.rs (34)
Patch Links:
https://github.com/PyO3/pyo3/pull/1411.patch
https://github.com/PyO3/pyo3/pull/1411.diff
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
Thanks very much for this PR. I'm very excited to see it! I'm very busy at the moment though hope to get a moment to read it by the weekend and share my full thoughts and feedback then. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
I think the API is fine, but there's some room for improvements in the implementation (can we reduce mut
)?
I think it's worth considering, but I personally prefer In any case, I feel that the final naming decision should be made by the maintainers, as they have much better understanding of pyo3's API as a whole than I do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks again for this, and sorry for the delay from me getting round to reading it!
The implementation looks good and has some decent test coverage; I added a few comments on places in the code where I have some questions and ideas to improve it a bit.
Regarding name - I think you're correct that from_py_with
is better than from_python_with
.
I also think that from_py_with
is better than from_py
, as we're keeping in line with the precedent made by serde.
Would be nice to hear if @kngwyu has any strong preference on name also.
e2ed1fc
to
b06d211
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the continued work on this, this is looking increasingly solid.
I took another read just now and had a few more ideas...
CI just got updated to Rust 1.50 and it broke formatting, plus there's a couple of new Clippy rules... |
👍 I'll fix in a bit and you can rebase this PR on it after |
Awesome, thank you! |
See #1422 - just waiting for a second pair of eyes on it... |
#1422 is merged, so if you rebase things should work now! |
d79f1f3
to
d43c19b
Compare
Rebased, I hope it wouldn't mess up the comments too much |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, the implementation looks great to me!
I'm happy with the design here, I think this is good to merge. @kngwyu are you also happy with this?
I see that the TODO list still includes CHANGELOG entry and docs.
I think docs should go in the guide. TBH the #[name = ...]
attribute is also undocumented; I was going to move it to #[pyo3(name = ...)]
and add a guide section to document attributes better at the same time. If you like you can just open an issue to document #[pyo3(from_py_with)]
and I'll do it at the same time.
CHANGELOG entry - I suggest something like this:
- Add #[pyo3(from_py_with = "...")]` attribute for function arguments and struct fields to override the default from-Python conversion. [#1411](https://github.com/PyO3/pyo3/pull/1411)
some_object: String, | ||
} | ||
|
||
#[test] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Final thought; could we please add tests for tuple structs and enum variants? Just to make sure that all cases are covered and remain covered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, thank you for the reminder!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've finally got to this and I have a question. At the moment we provide from_py_with
for struct fields only.
Do you have in mind that from_py_with
should be supported for tuple structs and enums as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, that's a good point, I didn't really specify those on #1239 when I proposed the idea.
I think for tuple structs with #[derive(FromPyObject)]
it's quite natural to want to be able to annotate fields in the same way. Maybe let's skip on deciding what to do with enum variants for now. That'll be easy to add later anyway.
If tuple structs are going to be a lot of extra work, perhaps let's merge this PR for now and add an issue to remember to support them later?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for clearing this out! I'll try supporting tuple structs, maybe it won't be that hard.
In any case, I think it's worth adding a compiler error (warning?) when from_py_with
is used on types that are not yet supported
@davidhewitt I'm still a little bit bummed about this: pyo3/pyo3-macros-backend/src/method.rs Lines 136 to 138 in d43c19b
I have tried a few things but I can't seem to fix it completely.
If we just use the mutable iterator everywhere, then we would need the additional variables listed above. Also it introduces unnecessary mutability to The other approach I tried is this:
There's also the third approach:
At this point I'm stuck. I would love to hear any ideas that you have on this. |
No, I'm fine with the current name. |
I am now still playing in the code but will leave some suggestions in a day. |
I've pushed the second approach implementation. It's awkward around skipping arguments, but otherwise I like it more than what I had before. |
de028bf
to
13efe6e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, your last commit nicely simplifies the code. 👍🏼
I left some comments to make the intention clearer.
@kngwyu Thanks for the suggestions! It looks a lot better now |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I think now it's ready 👍🏼
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This all looks great to me, thanks for your hard work on this. The implementation of FnSpec::parse
is a lot better now, really nice job.
Few final nits and then let's merge this. It could also be worth squashing this down to one or two commits from 22.
* allow from_py_with inside #[derive(FromPyObject)] * split up FnSpec::parse
e1f2c1e
to
cae3bbb
Compare
Is this the only blocker? |
I forgot to update the TODO: I still need to implement |
I see, thank you! |
This PR addresses #1239.
It adds a
#[pyo3(from_py_with = "function")]
attribute that allows to customize conversion between Python-native and Rust-native types.At the moment only argument attributes are supported. I plan on adding support for derive in the near future.
I've made a couple of design decisions along the way, that can be changed if needed:
from_py_with
instead offrom_python_with
from the original proposal because it was shorter to type. Also it goes well with the trait nameFromPyObject
.There's still a bunch of stuff left to do:
from_py_with
inderive(FromPyObject)
parse_arg_attributes
into smaller functionsfrom_py_with
for enums/tuple structs Support from_py_with on struct tuples and enums #1441