Pyo3: `#[new]` should support arrays

Created on 25 Feb 2020  路  5Comments  路  Source: PyO3/pyo3

Maybe a missing implementation?

use pyo3::prelude::*;

#[pyclass]
struct Foo {
  array: [i32; 2]
}

#[pymethods]
impl Foo {
  #[new]
  //pub fn new(array: [i32; 2]) -> Self {
  pub fn new(array: &[i32; 2]) -> Self {
    //Self { array }
    Self { array: *array }
  }
}

Most helpful comment

I will gladly provide a PR for arrays (up to 32) using declarative macros with some mentoring

All 5 comments

Like with everything about arrays in Rust, we could write a solution to support arrays up to an arbitrary length (normally 32).

To do this for all sizes would require const generics being available.

A PR for this to support arrays up to length 32 is very welcome.

I will gladly provide a PR for arrays (up to 32) using declarative macros with some mentoring

That would be awesome, thanks! I'll find some time to write some quick mentoring notes either tomorrow or the day after.

Mentoring notes, as promised:

Take a look at the implementation of FromPyObject for Vec<T>: https://github.com/PyO3/pyo3/blob/90b14fb36904ccbd91ce8adf121c38d23c8b4a4c/src/types/sequence.rs#L244

This is probably a good starting point. It uses specialization to do an optimization for Buffer objects, but we don't need that here - arrays of only 32 elements will be short enough that an optimization is kinda irrelevant. So you only need to care about the extract_sequence function.

As for the macro, you could structure it something like this:

macro_rules impl_array! {
    ($n:literal) => {
        impl<'a, T> FromPyObject<'a> for [T; $n]
            where T: FromPyObject<'a>
        {
            ...
        }
    };
}

impl_array!(0);
...  // call for each N
impl_array!(32);

You might be able to also make a trick so that impl_array! calls itself recursively, but that's a bit of fun you can play with yourself if you want.

If you're willing, it would be awesome to also have IntoPy<PyObject> implemented for arrays in the same way. See https://github.com/PyO3/pyo3/blob/90b14fb36904ccbd91ce8adf121c38d23c8b4a4c/src/types/list.rs#L190

@c410-f3r ping me if you have any further questions on this. The help is much appreciated.

Thank you, @davidhewitt

Was this page helpful?
0 / 5 - 0 ratings