Replies: 2 comments
-
In principle, you don't need a helper struct. You can just expose #[derive(Debug)]
#[pyclass]
pub struct Date {
#[pyo3(get, set)]
pub year: u16,
#[pyo3(get, set)]
pub month: u8,
#[pyo3(get, set)]
pub day: u8
}
#[pymethods]
impl Date {
#[new]
pub fn from_ymd(year: u16, month: u8, day: u8) -> Date {
// ...
}
pub const fn add_days(&self, N: u8) -> Self {
// ...
}
pub const fn is_weekend(&self) -> bool {
// ...
}
}
// methods not exposed to Python
impl Date {
pub fn from_str(s: &str) -> Date {
// ...
}
} All the methods in As for question 3, there is no such thing as multiple constructors in Python either, so pybind11 probably creates a wrapper in the background calling constructors based on types received. You can mimic that by taking |
Beta Was this translation helpful? Give feedback.
-
Thanks @birkenfeld for your comments! Regarding
So if i want to keep my rust library clean, i will have to create helper structs such as Regarding
In case, this could help someone else in the future, I tried the following, which works for me: #[pymethods]
impl DatePy {
#[new]
#[pyo3(signature = (*py_args))]
fn new(py_args: &Bound<'_, PyTuple>) -> PyResult<Self> {
if py_args.len() == 3 && py_args.iter().all(|item| { item.is_instance_of::<PyLong>() }) {
let year: u16 = py_args.get_item(0)?.extract()?;
let month: u8 = py_args.get_item(1)?.extract()?;
let day: u8 = py_args.get_item(2)?.extract()?;
Ok(Date::from_ymd(year, month, day).into())
} else if py_args.len() == 1 && py_args.get_item(0)?.is_instance_of::<PyString>() {
Ok(Date::from_str(py_args.get_item(0)?.extract()?).into())
} else {
Err(PyValueError::new_err(format!("Expected the following signatures: (year: int, month: int, day: int) or (yyyymmdd: str), but have {:?}", py_args)))
}
}
} Any advice on how I could improve this |
Beta Was this translation helpful? Give feedback.
-
Say I have the following C++
Date
class. Usingpybind11
I can easily wrap it to be used in Python:That's 15 lines of code for my bindings using pybind11.
Now, I want to do the same in Rust. So I implemented my
Date
class and then usedPyO3
to wrap it:I've noticed that the
PyO3
bindings contain a lot of boilerplate, and hence they are much longer compared topybind11
:Questions:
DatePy
helper struct? Again, ideally similar to pybind where I don't need to manually create any helper structs.#[new] fn new(year: u16, month: u8, day: u8)
and#[new] fn new(yyyymmdd: &str)
similar to pybind11? RIght now, I am only able to expose 1 constructor with PyO3.Question originates from Correct & concise way to use PyO3 Bindings (similar to pybind11), where a commenter suggested to raise an issue on the PyO3 GitHub.
Beta Was this translation helpful? Give feedback.
All reactions