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

Implement FromPyObject and IntoPy<PyObject> traits for arrays (up to 32) #778

Merged
merged 3 commits into from
Mar 3, 2020

Conversation

c410-f3r
Copy link
Contributor

@c410-f3r c410-f3r commented Feb 29, 2020

Fixes #775.

Copy + Default bounds to initialize memory for copy_to_slice_impl and avoid unsafe (MaybeUninit and ptr friends). Copy bound is also necessary due to the lack of a "real" IntoIterator implementation for arrays.

Comment on lines 471 to 454
create_tests!(array);
create_tests!(vec vec!);
Copy link
Contributor Author

@c410-f3r c410-f3r Feb 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this approach is desired. If so, I will also do the same in sequence.rs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a good idea, thanks for adding comprehensive tests!

macro_rules! array_impls {
($($N:expr),+) => {
$(
impl<T> ToPyObject for [T; $N]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As these imples are not faster than one for slices(impl ~ for &[T]), I don't think we need this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree for ToPyObject but not for IntoPy<PyObject> - see below.

@@ -282,6 +325,22 @@ where
Ok(v)
}

fn extract_sequence_into_slice<'s, T>(obj: &'s PyAny, slice: &mut [T]) -> PyResult<()>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about extract_sequence_inplace?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tend to think _inplace as referring to the first argument, so I would vote against that name.

extract_sequence_into_slice is fine imo.

@kngwyu
Copy link
Member

kngwyu commented Feb 29, 2020

Thank you!
FromPyObject impl looks good but I don't think we need IntoPy<PyObject> and ToPyObject impls for arrays.

@davidhewitt
Copy link
Member

Also thanks from me!

FromPyObject impl looks good but I don't think we need IntoPy<PyObject> and ToPyObject impls for arrays.

I slightly disagree with this. ToPyObject taking &[T; N] maybe doesn't offer benefit over &[T] but I believe IntoPy<PyObject> offers value.

For example, the following function will not compile without the IntoPy<PyObject> implementation:

#[pyfunction]
fn make_array()-> [i32; 2] {
    [0, 0]
}

CHANGELOG.md Outdated
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [0.9.0]

* Implement `*Py` traits for arrays (up to 32).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please change the line to read the following and also move it to the Added section of the 0.9.0 changelog.

Suggested change
* Implement `*Py` traits for arrays (up to 32).
* Implement `FromPyObject` and `IntoPy<PyObject>` traits for arrays (up to 32). [#778](https://github.com/PyO3/pyo3/pull/778)

Comment on lines 471 to 454
create_tests!(array);
create_tests!(vec vec!);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a good idea, thanks for adding comprehensive tests!

@c410-f3r c410-f3r changed the title Implement *Py traits to arrays (up to 32) Implement *Py traits for arrays (up to 32) Feb 29, 2020
@c410-f3r c410-f3r changed the title Implement *Py traits for arrays (up to 32) Implement FromPyObject and IntoPy<PyObject> traits for arrays (up to 32) Feb 29, 2020
@c410-f3r
Copy link
Contributor Author

Comments addressed. Thank you guys

@kngwyu
Copy link
Member

kngwyu commented Feb 29, 2020

For example, the following function will not compile without the IntoPy implementation:

That makes sense, thanks 👍

$(
impl<T> IntoPy<PyObject> for [T; $N]
where
T: Copy + IntoPy<PyObject>,
Copy link
Member

@kngwyu kngwyu Feb 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's change this bound to T: ToPyObject.
Then we can use self.as_ref().to_object(py) for implementation.

T: FromPyObject<'s>,
{
let seq = <PySequence as PyTryFrom>::try_from(obj)?;
if (seq.len()? as usize) != slice.len() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (seq.len()? as usize) != slice.len() {
if seq.len()? as usize != slice.len() {

@@ -330,6 +389,9 @@ impl<'v> PyTryFrom<'v> for PySequence {

#[cfg(test)]
mod test {
macro_rules! create_tests {
Copy link
Member

@kngwyu kngwyu Feb 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here not all tests are for FromPyObject.
Do we need to repeat all of them?
I think what we really need is array version of test_extract_bytearray_to_vec.

@@ -205,6 +232,9 @@ where

#[cfg(test)]
mod test {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as below.
Don't need to repeat all tests.

@kngwyu
Copy link
Member

kngwyu commented Mar 2, 2020

Thank you for addressing comments, but as I commented, I think current macro-generated tests seem to make it unclear what is tested here.
For FromPyObject implementation, we just need a test that calls let arr: [u32; N] = obj.extract().unwrap(). Most of tests like test_seq_contains are not related to this PR at all.

We can say the same thing for IntoPy<PyObject> implementation. Most of the tests are not array-specific and use ToPyObject for &[T] implementation(e.g., test_new).
What we need is simply a test that calls [1, 2, 3].into_py(py).

@c410-f3r
Copy link
Contributor Author

c410-f3r commented Mar 2, 2020

I was waiting for David but looks like these tests are actually unwanted

@davidhewitt
Copy link
Member

Thanks - sorry about the extra work there. I thought your macro test implementation was nice, but @kngwyu has been a maintainer of pyo3 for much longer than I so I'm still deferring to his opinion when we differ.

I wasn't going to ask you to undo the work though - was thinking about pushing a change myself. Thanks for doing so.

@kngwyu
Copy link
Member

kngwyu commented Mar 3, 2020

@c410-f3r
Thank you for completing the PR!
@davidhewitt

so I'm still deferring to his opinion when we differ.

You don't have to do so. We sometimes make mistakes, but fortunately, we can help us with each other. When our opinion differs, it just means we need a discussion.

@kngwyu kngwyu merged commit f470154 into PyO3:master Mar 3, 2020
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.

#[new] should support arrays
3 participants