Skip to content

Commit 5cfe4f1

Browse files
finish adding python support
1 parent dfeceb7 commit 5cfe4f1

File tree

3 files changed

+101
-3
lines changed

3 files changed

+101
-3
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# See Notices.txt for copyright information
33
[package]
44
name = "algebraics"
5-
version = "0.1.1"
5+
version = "0.1.2"
66
authors = ["Jacob Lifshay <[email protected]>"]
77
edition = "2018"
88
license = "LGPL-2.1-or-later"

README.md

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
[Algebraic Numbers](https://en.wikipedia.org/wiki/Algebraic_number) Library
1+
## [Algebraic Numbers](https://en.wikipedia.org/wiki/Algebraic_number) Library
22

33
Use when you need exact arithmetic, speed is not critical, and rational numbers aren't good enough.
44

5-
Example:
5+
## Example:
6+
67
```rust
78
use algebraics::prelude::*;
89
use algebraics::RealAlgebraicNumber as Number;
@@ -66,3 +67,32 @@ assert_eq!(
6667
000000000000000000023"
6768
)
6869
```
70+
71+
## Python support
72+
73+
Using algebraics from Python:
74+
75+
```bash
76+
python3 -m pip install algebraics==0.1.2
77+
```
78+
79+
```python
80+
from algebraics import RealAlgebraicNumber
81+
sqrt_2 = 2 ** (RealAlgebraicNumber(1) / 2)
82+
assert sqrt_2 * sqrt_2 == 2
83+
```
84+
85+
Using algebraics in your own Rust project:
86+
87+
```toml
88+
[dependencies.algebraics]
89+
version = "0.1.2"
90+
features = ["python"]
91+
```
92+
93+
Developing algebraics:
94+
95+
```bash
96+
cargo install maturin
97+
maturin develop --cargo-extra-args="--features python-extension"
98+
```

src/python.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,44 @@ use pyo3::PyNumberProtocol;
1919
use pyo3::PyObjectProtocol;
2020
use std::sync::Arc;
2121

22+
impl FromPyObject<'_> for RealAlgebraicNumber {
23+
fn extract(value: &PyAny) -> PyResult<Self> {
24+
Ok((*RealAlgebraicNumberPy::extract(value)?.value).clone())
25+
}
26+
}
27+
28+
impl<'a> FromPyObject<'a> for &'a RealAlgebraicNumber {
29+
fn extract(value: &'a PyAny) -> PyResult<Self> {
30+
let result = RealAlgebraicNumberPy::extract(value)?.value.clone();
31+
let result: &'a _ = value.py().register_any(result);
32+
Ok(&**result)
33+
}
34+
}
35+
36+
impl IntoPy<PyObject> for RealAlgebraicNumber {
37+
fn into_py(self, py: Python) -> PyObject {
38+
RealAlgebraicNumberPy {
39+
value: Arc::new(self),
40+
}
41+
.into_py(py)
42+
}
43+
}
44+
45+
impl IntoPy<PyObject> for &'_ RealAlgebraicNumber {
46+
fn into_py(self, py: Python) -> PyObject {
47+
RealAlgebraicNumberPy {
48+
value: Arc::new(self.clone()),
49+
}
50+
.into_py(py)
51+
}
52+
}
53+
54+
impl ToPyObject for RealAlgebraicNumber {
55+
fn to_object(&self, py: Python) -> PyObject {
56+
self.into_py(py)
57+
}
58+
}
59+
2260
#[pyclass(name=RealAlgebraicNumber, module="algebraics")]
2361
#[derive(Clone)]
2462
struct RealAlgebraicNumberPy {
@@ -220,3 +258,33 @@ fn algebraics(_py: Python, m: &PyModule) -> PyResult<()> {
220258
m.add_class::<RealAlgebraicNumberPy>()?;
221259
Ok(())
222260
}
261+
262+
#[cfg(test)]
263+
mod tests {
264+
use super::*;
265+
266+
#[test]
267+
fn conversion_compile_test() {
268+
#![allow(dead_code)]
269+
270+
#[pyfunction]
271+
fn identity_ref_result(v: &RealAlgebraicNumber) -> PyResult<&RealAlgebraicNumber> {
272+
Ok(v)
273+
}
274+
275+
#[pyfunction]
276+
fn identity_result(v: RealAlgebraicNumber) -> PyResult<RealAlgebraicNumber> {
277+
Ok(v)
278+
}
279+
280+
#[pyfunction]
281+
fn identity_ref(v: &RealAlgebraicNumber) -> &RealAlgebraicNumber {
282+
v
283+
}
284+
285+
#[pyfunction]
286+
fn identity(v: RealAlgebraicNumber) -> RealAlgebraicNumber {
287+
v
288+
}
289+
}
290+
}

0 commit comments

Comments
 (0)