-
Notifications
You must be signed in to change notification settings - Fork 778
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
Try harder by looking for a __bool__ magic method when extracing bool values from Python objects. #3638
Conversation
f02d0d1
to
9e348a9
Compare
CodSpeed Performance ReportMerging #3638 will not alter performanceComparing Summary
|
I don't think it is good to single out objects that define Contrary to something like I.e. my recommendation is, either keep being strict here, or just use |
While I can see the argument for being consistent in one way or the other, i.e. either strict insofar a function argument is sort of type specification for the Python API or loose where we try as hard as possible to convert any incoming value into a the target type, I think that we cannot solve this issue as long as the single There is also precedent for this middle ground approach in other implementations, e.g. So while I would prefer a principled approach, the practicalities of ergonomic usage of PyO3 based on a single trait prevent this for now as far I can see. |
I can see that, but my argument is that the approach in this PR is worse than either. It happens to work for numpy bools, fixing the original issue, but also allows conversion for a whole host of other types, none of which have to be "bool-like", and arbitrarily excludes others which are no less "bool-like". |
But does this have any concrete usability consequences or is it merely an uncomfortably inconsistent design? |
Maybe as a data point that this can work, pybind11 seems have run into the same problem, i.e. pybind/pybind11#925 1 and solved it in similar manner albeit optimized to avoid the cost of Admittedly, they are in the advantageous position of having the Footnotes
|
But they certainly also had a long discussion before settling on the final approach. 😅 |
This reminds me a lot of python/cpython#15609 - in Python 3.12 they changed all Slight aside, what do you think of renaming |
This I like.
This, not so much. |
👍 I will open an Regarding the Python 3.12 change, I agree it's not my favourite behaviour either (and PyO3 being principled about the difference between |
(Sorry I was a little slow on review here, ended up getting excited by the Py2 work...) Hmmm, it's hard to make a judgement on the right solution for this. I am definitely in favour of us trying to fix the numpy case. Overall, we've definitely been trending slowly towards being more lax on these Python -> Rust conversions, e.g. #3374, #3197, as this seems to be what users want.
Yes, I definitely think there is room for something like this; I called it "strict" mode in #3226 (comment), we could have Overall, I think that pybind11 prior art is a reasonable one to follow here, and I like consistency in the ecosystem (if we think the CPython choice is too lax). I also think it's less breaking for future users if we chose to go more lax again to match CPython than it would be to get stricter. I definitely think that where we're at is that So perhaps the road ahead is to proceed with the implementation of this as is currently written in this PR, and then if users want to opt-out, we should add a All this said, would I think I need to sleep on this and see how I feel in the morning... |
With fresh eyes I've come around to this solution, I think the smaller behaviour change is preferable. If users want to have the stricter method again I suggest we explore the |
556271e
to
ff13fd8
Compare
@birkenfeld I would be quite unhappy to merge this over you direct objection. I wonder if you can be placated by the suggestion of adding a |
I'm all in favor of the Just think about the user's perspective. If I can pass in |
Yes, if we had
I think there is a difference between "bool-convertible" and "truthy". The truth value testing which includes |
This is my feeling too when I was reflecting on |
My point is that Just check out https://github.com/search?type=code&auto_enroll=true&q=%22def+__bool__%22 - many of the objects defining |
I see what you mean, that "bool conversion" isn't separable from truth testing on the Python side. Given the strength of @birkenfeld's conviction, maybe we should slow down for now and just take the route |
Yes, if only to resolve the issue at hand. I do see some types in the above list would be good candidates as well, like pytorch's |
0937f7c
to
e0a2c6f
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.
Looks good to me, save for the CHANGELOG entry. I think if we want to go further here the next steps will be to figure out how the #[pyo3(noconvert)]
annotation might work.
e0a2c6f
to
a2b84d2
Compare
Uff, it seems |
I wonder if this changes based on version, e.g. maybe 3.9 or 3.10 change? It could be worth adding PyPy 3.10 on Ubuntu to the pr ci to get a hint what might work before the full merge queue runs? |
I tested this locally using |
But reading https://peps.python.org/pep-3155/ and testing this in the CPython REPL, |
From reading https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_name, I think we should use |
So, I think ideally, this would be rebased on #3660 and made use of |
… values from Python objects. I decided to not implement the full protocol for truth value testing [1] as it seems confusing in the context of function arguments if basically any instance of custom class or non-empty collection turns into `true`. [1] https://docs.python.org/3/library/stdtypes.html#truth
a2b84d2
to
4177dfc
Compare
Rebased this onto main now that the full name is available on |
I decided to not implement the full protocol for truth value testing as it seems confusing in the context of function arguments if basically any instance of custom classes or non-empty collections turns into
true
.Closes #3637