PyOrd

Derive Macro PyOrd 

Source
#[derive(PyOrd)]
Expand description

Derive macro generating __lt__(), __le__(), __gt__() and __ge__() fn/Python methods.

The implementation requires PartialOrd impl.

PyO3 supports #[pyclass(ord)] since 0.22.

The generated methods return False when PartialOrd::partial_cmp returns None.

Note that implementing __lt__(), __le__(), __gt__() and __ge__() methods will cause Python not to generate a default __hash__() implementation, so consider also implementing __hash__().

§Expansion

This implements, for example;

#[pymethods]
impl PyClass {
    pub fn __lt__(&self, other: &Self) -> bool {
        matches!(self.partial_cmp(other), Some(Ordering::Less))
    }
    // and __le__, __gt__ and __ge__
}

§Example

use pyo3::{prelude::*, py_run};
use pyderive::*;

#[derive(PyOrd)]
#[pyclass]
#[derive(PartialOrd, PartialEq)]
struct PyClass {
    field: f64,
}

Python::attach(|py| -> PyResult<()> {
    let a = Py::new(py, PyClass { field: 0.0 })?;
    let b = Py::new(py, PyClass { field: 1.0 })?;
    let c = Py::new(py, PyClass { field: f64::NAN })?;

    py_run!(py, a b, "assert a < b");
    py_run!(py, a b, "assert a <= b");
    py_run!(py, a b, "assert not a > b");
    py_run!(py, a b, "assert not a >= b");
    py_run!(py, c, "assert not c < c");

    let test = "
try:
    a < 1
except TypeError:
    pass
else:
    raise AssertionError
";
    py_run!(py, a, test);

    Ok(())
});