SOLVED: Pyo3 class method to accept generic

I maintain the python 3D graphics module pi3d and I'm looking at making a rust version accessible from python. 18 months ago I started experimenting with a rust version GitHub - paddywwoof/rust_pi3d: translation of pi3d from python to rust and now I'm attempting to wrap it using pyo3. Mainly this all seems to work quite well, but my issue is how to have a class method add_child() on Cuboid, Sphere, Cone etc. etc (which are all just wrappers with different constructors for Shape) that can accept Cuboid, Sphere, Cone types.

When I try a pyo3 version of the code below I get the error A Python method can't have a generic add_child parameter: type. I suspect the solution might something to do with pyo3 PyObjects but I haven't been able to find anything in docs.

#[derive(Clone, Debug)]
struct Shape {
    a: i32,
    children: Vec<Shape>,
}

trait GetShape {
    fn get_shape(&mut self) -> Shape;
}

#[derive(Debug)]
struct Cuboid {
    shape: Shape,
}
impl GetShape for Cuboid {
    fn get_shape(&mut self) -> Shape {
        self.shape.clone()
    }
}
impl Cuboid {
    fn add_child<T: GetShape>(&mut self, other: &mut T) {
        self.shape.children.push(other.get_shape());
    }
}

#[derive(Debug)]
struct Sphere {
    shape: Shape,
}
impl GetShape for Sphere {
    fn get_shape(&mut self) -> Shape {
        self.shape.clone()
    }
}
impl Sphere {
    fn add_child<T: GetShape>(&mut self, other: &mut T) {
        self.shape.children.push(other.get_shape());
    }
}

fn main() {
    let mut cube = Cuboid {
            shape: Shape {a:33, children: vec![]},
        };
    let mut sphere = Sphere {
            shape: Shape {a:366, children: vec![]},
        };
    cube.add_child(&mut sphere);
    println!("{:?}", cube);
}
1 Like

It's possible to do something like this using (extends=..) as explained here: Question: How can I pass generic cutom classes to a method · Issue #696 · PyO3/pyo3 · GitHub

grateful thanks to @kngwyu on the pyo3 github repo

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.