Basic Pair pyo3 conversions dev

Sun, 18 May 2025 23:15:50 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Sun, 18 May 2025 23:15:50 -0500
branch
dev
changeset 144
44d859269132
parent 143
fbbf9ed47913
child 145
0b9aecd7bb76

Basic Pair pyo3 conversions

Cargo.lock file | annotate | diff | comparison | revisions
Cargo.toml file | annotate | diff | comparison | revisions
src/direct_product.rs file | annotate | diff | comparison | revisions
--- a/Cargo.lock	Sun May 18 19:56:28 2025 -0500
+++ b/Cargo.lock	Sun May 18 23:15:50 2025 -0500
@@ -15,6 +15,7 @@
  "num",
  "num-traits",
  "numeric_literals",
+ "pyo3",
  "rayon",
  "rustc_version",
  "serde",
@@ -122,6 +123,18 @@
 checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
 
 [[package]]
+name = "heck"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
+[[package]]
+name = "indoc"
+version = "2.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
+
+[[package]]
 name = "itertools"
 version = "0.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -165,6 +178,15 @@
 checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
 
 [[package]]
+name = "memoffset"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
 name = "nalgebra"
 version = "0.33.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -275,12 +297,24 @@
 ]
 
 [[package]]
+name = "once_cell"
+version = "1.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
+
+[[package]]
 name = "paste"
 version = "1.0.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
 
 [[package]]
+name = "portable-atomic"
+version = "1.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
+
+[[package]]
 name = "proc-macro2"
 version = "1.0.92"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -290,6 +324,68 @@
 ]
 
 [[package]]
+name = "pyo3"
+version = "0.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f239d656363bcee73afef85277f1b281e8ac6212a1d42aa90e55b90ed43c47a4"
+dependencies = [
+ "indoc",
+ "libc",
+ "memoffset",
+ "once_cell",
+ "portable-atomic",
+ "pyo3-build-config",
+ "pyo3-ffi",
+ "pyo3-macros",
+ "unindent",
+]
+
+[[package]]
+name = "pyo3-build-config"
+version = "0.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "755ea671a1c34044fa165247aaf6f419ca39caa6003aee791a0df2713d8f1b6d"
+dependencies = [
+ "once_cell",
+ "target-lexicon",
+]
+
+[[package]]
+name = "pyo3-ffi"
+version = "0.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc95a2e67091e44791d4ea300ff744be5293f394f1bafd9f78c080814d35956e"
+dependencies = [
+ "libc",
+ "pyo3-build-config",
+]
+
+[[package]]
+name = "pyo3-macros"
+version = "0.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a179641d1b93920829a62f15e87c0ed791b6c8db2271ba0fd7c2686090510214"
+dependencies = [
+ "proc-macro2",
+ "pyo3-macros-backend",
+ "quote",
+ "syn 2.0.90",
+]
+
+[[package]]
+name = "pyo3-macros-backend"
+version = "0.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9dff85ebcaab8c441b0e3f7ae40a6963ecea8a9f5e74f647e33fcf5ec9a1e89e"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "pyo3-build-config",
+ "quote",
+ "syn 2.0.90",
+]
+
+[[package]]
 name = "quote"
 version = "1.0.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -422,6 +518,12 @@
 ]
 
 [[package]]
+name = "target-lexicon"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a"
+
+[[package]]
 name = "typenum"
 version = "1.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -434,6 +536,12 @@
 checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
 
 [[package]]
+name = "unindent"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
+
+[[package]]
 name = "wide"
 version = "0.7.30"
 source = "registry+https://github.com/rust-lang/crates.io-index"
--- a/Cargo.toml	Sun May 18 19:56:28 2025 -0500
+++ b/Cargo.toml	Sun May 18 23:15:50 2025 -0500
@@ -31,11 +31,11 @@
 rayon = "1.5.3"
 simba = "0.9.0"
 anyhow = "1.0.95"
+pyo3 = { version = "~0.25.0", optional = true }
 
 [package.metadata.docs.rs]
 rustdoc-args = ["--html-in-header", "katex-header.html"]
 
-
 [profile.release]
 debug = true
 
@@ -45,6 +45,7 @@
 # The nightly feature enables some additional features.
 # Nightly-based optimisations are decided automatically by build.rs.
 nightly = []
+pyo3 = ["dep:pyo3"]
 
 [build-dependencies]
 rustc_version = "0.4"
--- a/src/direct_product.rs	Sun May 18 19:56:28 2025 -0500
+++ b/src/direct_product.rs	Sun May 18 23:15:50 2025 -0500
@@ -566,3 +566,63 @@
         Pair(self.0.dual_origin(), self.1.dual_origin())
     }
 }
+
+#[cfg(feature = "pyo3")]
+mod python {
+    use super::Pair;
+    use pyo3::conversion::FromPyObject;
+    use pyo3::types::{PyAny, PyTuple};
+    use pyo3::{Bound, IntoPyObject, PyErr, PyResult, Python};
+
+    impl<'py, A, B> IntoPyObject<'py> for Pair<A, B>
+    where
+        A: IntoPyObject<'py>,
+        B: IntoPyObject<'py>,
+    {
+        type Target = PyTuple;
+        type Error = PyErr;
+        type Output = Bound<'py, Self::Target>;
+
+        fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
+            (self.0, self.1).into_pyobject(py)
+        }
+    }
+
+    impl<'a, 'py, A, B> IntoPyObject<'py> for &'a mut Pair<A, B>
+    where
+        &'a mut A: IntoPyObject<'py>,
+        &'a mut B: IntoPyObject<'py>,
+    {
+        type Target = PyTuple;
+        type Error = PyErr;
+        type Output = Bound<'py, Self::Target>;
+
+        fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
+            (&mut self.0, &mut self.1).into_pyobject(py)
+        }
+    }
+
+    impl<'a, 'py, A, B> IntoPyObject<'py> for &'a Pair<A, B>
+    where
+        &'a A: IntoPyObject<'py>,
+        &'a B: IntoPyObject<'py>,
+    {
+        type Target = PyTuple;
+        type Error = PyErr;
+        type Output = Bound<'py, Self::Target>;
+
+        fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
+            (&self.0, &self.1).into_pyobject(py)
+        }
+    }
+
+    impl<'py, A, B> FromPyObject<'py> for Pair<A, B>
+    where
+        A: Clone + FromPyObject<'py>,
+        B: Clone + FromPyObject<'py>,
+    {
+        fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult<Self> {
+            FromPyObject::extract_bound(ob).map(|(a, b)| Pair(a, b))
+        }
+    }
+}

mercurial