-
Notifications
You must be signed in to change notification settings - Fork 782
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
Replace (A)IterNextOutput by autoref-based specialization to allow returning arbitrary value #3661
Conversation
Fantastic! I am a little tight for time today, I'll do my best to give this a full read tomorrow 👍 |
6f81bd0
to
a47baf5
Compare
I've had a read and makes sense, I'll hold off from too many comments on the diff while we're figuring out the design. I would like to suggest we don't deprecate the And I guess if we did keep that, probably |
Yeah, I was leaning into direction as well after seeing how little changes are necessary to make this work for existing code. And removing
If I understand this correctly, I would need to remove the generic
I already added |
If you are not fond of specialization introducing subtle behavioural difference based on return type, maybe rather than specialize on |
I think so, yes. Given the tags only work for this slot, I can't see a potential downside right now, and as a performance optimization I guess we can back out again if it's problematic. |
👍 Makes sense to me! |
Yes, I am not fond of that. But the resulting usability and flexibility is a strong argument for supporting |
a47baf5
to
5121b65
Compare
5121b65
to
80b25e3
Compare
80b25e3
to
d4c2c09
Compare
Turns out I did not fully wire the holders change through. Added this as a separate commit here and now the modified test case does indeed compile. |
c9af527
to
50fcc2a
Compare
50fcc2a
to
1c81030
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.
Looking good!
1c81030
to
1954293
Compare
1954293
to
b786bc2
Compare
CodSpeed Performance ReportMerging #3661 will improve performances by 22.03%Comparing Summary
Benchmarks breakdown
|
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 great! I have just one suggestion on wording in the guide, and also a thought on whether we can/should generalise the error type for the result specialisations.
e92db15
to
5528895
Compare
(I guess at some point in the future, we'd want to do something similar for function arguments to avoid matching on the "Option" name?) |
Quite possibly, yes. I played around with something to that regard in the past, but I think the patch is now lost/dead. Also I believe that to completely stop matching on |
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 fantastic, thanks! It's very pleasing to see that this makes user code read nicer :)
@davidhewitt Just noticed this and I have a question in regards to the deprecation: is there a way to yield For instance, how this code could be translated to avoid #[pyclass]
pub(crate) struct PyIterAwaitable {
result: Option<PyResult<PyObject>>,
}
impl PyIterAwaitable {
pub(crate) fn new() -> Self {
Self { result: None }
}
pub(crate) fn set_result(&mut self, result: PyResult<PyObject>) {
self.result = Some(result);
}
}
#[pymethods]
impl PyIterAwaitable {
fn __await__(pyself: PyRef<'_, Self>) -> PyRef<'_, Self> {
pyself
}
fn __iter__(pyself: PyRef<'_, Self>) -> PyRef<'_, Self> {
pyself
}
fn __next__(&self, py: Python) -> PyResult<IterNextOutput<PyObject, PyObject>> {
match &self.result {
Some(res) => match res {
Ok(v) => Ok(IterNextOutput::Return(v.clone_ref(py))),
Err(err) => Err(err.clone_ref(py)),
},
_ => Ok(IterNextOutput::Yield(py.None())),
}
}
} |
@gi0baro great question! To update, you'd want to directly return fn __next__(&self, py: Python) -> PyResult<PyObject> {
match &self.result {
Some(res) => match res {
Ok(v) => Ok(PyStopIteration::new_err(v.clone_ref(py)).into_py(py)),
Err(err) => Err(err.clone_ref(py)),
},
_ => Ok(py.None().into_py(py)),
}
} |
To be done:
Closes #3190