#pyo3 #macro-derive #attributes #methods #class #special #python

pyderive

Derive macro of Python special methods and a class attributes for PyO3

4 releases

new 0.8.2 Dec 13, 2024
0.8.1 Dec 13, 2024
0.8.0 Dec 12, 2024
0.7.0 Jun 29, 2024

#776 in Rust patterns

Download history 14/week @ 2024-09-16 7/week @ 2024-09-23 1/week @ 2024-09-30 14/week @ 2024-10-21 29/week @ 2024-10-28 17/week @ 2024-11-04 1/week @ 2024-11-18 2/week @ 2024-11-25 407/week @ 2024-12-09

410 downloads per month

MIT/Apache

130KB
658 lines

pyderive

Crates.io Version Crates.io MSRV GitHub Actions Workflow Status docs.rs Crates.io License

pyderive provides derive macros for Python spacial methods and a class attributes for PyO3.

// Enable `multiple-pymethods` feature of PyO3
use pyo3::prelude::*;
use pyderive::*;

// Place #[derive(PyNew, ...)] before #[pyclass]
#[derive(PyNew, PyMatchArgs, PyRepr, PyEq)]
#[pyclass(get_all)]
#[derive(PartialEq, Hash)]
struct MyClass {
    string: String,
    integer: i64,
    option: Option<String>
}
from rust_module import MyClass

# Derives __new__()
m = MyClass("a", 1, None)

# Derives __match_args__ (supports Pattern Matching by positional arguments)
match m:
    case MyClass(a, b, c):
        assert a == "a"
        assert b == 1
        assert c is None
    case _:
        raise AssertionError

# Derives __repr__(), calls Python repr() recursively
assert str(m) == "MyClass(string='a', integer=1, option=None)"
assert repr(m) == "MyClass(string='a', integer=1, option=None)"

# Derives __eq__() that depends on PartialEq trait
assert m == MyClass("a", 1, None)

This provides deriving following special methods and attributes;

Derive Macro Python Method/Attribute
PyNew __new__()
PyMatchArgs __match_args__
PyRepr __repr__()
PyStr __str__()
PyEq __eq__() and __ne__()
PyOrd __lt__(), __le__(), __gt__() and __ge__()
PyRichCmp ==, !=, >, >=, < and <= by __richcmp__()
PyIter __iter__()
PyReversed __reversed__()
PyLen __len__()
PyDataclassFields __dataclass_fields__
PyNumeric Numeric op methods (__add__() etc.)
PyBitwise Bitwise op methods (__and__() etc.)

The field attributes #[pyderive(..)] is used to customize the implementation, like dataclasses.field() of Python.

Module pyderive::ops and pyderive::convert provides derive macros that implement individual method that enumerating numeric type (__add__() etc.) and called by builtin functions (__int__() etc.).

It requires to enable multiple-pymethods feature of PyO3 because this may produce multiple #[pymethods].

Feature

PyRepr and PyStr

The methods implemented by PyRepr and PyStr are recursively calls repr() or str() like a Python dataclass.

PyEq and PyOrd

The implementation of PyEq and PyOrd does not use __richcmp__().

License

MIT or Apache-2.0

Dependencies

~245–740KB
~17K SLoC