Open DiTo97 opened 3 weeks ago
Here's the final repository structure along with the contents of each configuration file:
my_dashu_lib/
├── .github/
│ └── workflows/
│ └── ci.yml
├── python_package/
│ ├── my_dashu_lib/
│ │ └── __init__.py
│ └── setup.py
├── src/
│ ├── bindings.rs
│ ├── calculations.rs
│ └── lib.rs
├── Cargo.toml
└── README.md
Cargo.toml
[package]
name = "my_dashu_lib"
version = "0.1.0"
edition = "2021"
[dependencies]
dashu = "0.4" # Adjust the version as needed
pyo3 = { version = "0.16", features = ["extension-module"] }
src/lib.rs
pub mod calculations;
pub mod bindings;
src/calculations.rs
use dashu::integer::IBig;
pub fn add_big_integers(a: &str, b: &str) -> IBig {
let a: IBig = a.parse().unwrap();
let b: IBig = b.parse().unwrap();
a + b
}
src/bindings.rs
use pyo3::prelude::*;
use crate::calculations::add_big_integers;
#[pyfunction]
fn add(a: &str, b: &str) -> String {
add_big_integers(a, b).to_string()
}
#[pymodule]
fn my_dashu_lib(py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(add, m)?)?;
Ok(())
}
python_package/setup.py
from setuptools import setup
from setuptools_rust import RustExtension
setup(
name="my_dashu_lib",
version="0.1.0",
rust_extensions=[RustExtension("my_dashu_lib.my_dashu_lib", "Cargo.toml", binding="pyo3")],
packages=["my_dashu_lib"],
zip_safe=False,
)
python_package/my_dashu_lib/__init__.py
# This file can be left empty or used to initialize the package
.github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
components: rustfmt
- name: Install maturin
run: pip install maturin
- name: Build and test
run: |
maturin develop
pytest
This structure and configuration should give you a working Rust library with Python bindings, a Python package setup, and a CI pipeline using GitHub Actions. Let me know if you need any more details or adjustments!
To run the code in Python after building the package with
maturin
, you can follow these steps:Build the package:
Import and use the module in Python:
Regarding separating source code from bindings, it's indeed possible and often a good practice to keep the core logic separate from the bindings. This way, the core logic can be reused in different contexts. Here's how you can structure your Rust project:
Create a library for the core logic:
In
src/lib.rs
:Create a separate file for the Python bindings:
In
src/python_bindings.rs
:Modify
Cargo.toml
to include the new module:Build the package with
maturin
:Now, you can use the Python module as shown earlier. This approach keeps your core logic in a separate library, making it reusable in other contexts, such as a standalone Rust application or another language's bindings.