Skip to content

Commit 64a3ea5

Browse files
committed
feat: pykore Python bindings (v0.1.0-dev)
- PyO3 object wrappers: Grid, Config, State, Kernel, Diagnostics - NumPy complex128 interop with in-place mutation semantics - GIL release on compute path - maturin build system, pyproject.toml - 12 Python tests passing - cargo clippy --all-features -D warnings clean
1 parent 34cdfae commit 64a3ea5

15 files changed

Lines changed: 622 additions & 27 deletions

File tree

.github/workflows/ci.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,16 @@ jobs:
88
steps:
99
- uses: actions/checkout@v5
1010
- uses: dtolnay/rust-toolchain@stable
11+
- uses: actions/setup-python@v5
12+
with:
13+
python-version: '3.11'
14+
- run: python -m venv .venv
15+
- run: . .venv/bin/activate && python -m pip install maturin pytest numpy
1116
- run: cargo clippy -- -D warnings
1217
- run: cargo test
1318
- run: cargo check
19+
- run: . .venv/bin/activate && maturin develop
20+
- run: . .venv/bin/activate && pytest tests/python -q
1421
- name: Header drift check
1522
run: |
1623
cargo install cbindgen --locked

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,10 @@ target/
33
.DS_Store
44
Cargo.lock
55
docs/
6+
.venv/
7+
python/pykore/_kore*.so
8+
python/pykore/_kore*.pyd
9+
python/pykore/_kore*.dylib
10+
python/pykore/*.dylib.dSYM/
11+
tests/python/__pycache__/
12+
tests/python/.pytest_cache/

Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,15 @@ repository = "https://github.com/edengilbertus/kore"
88

99
[lib]
1010
name = "kore"
11-
crate-type = ["rlib", "staticlib"]
11+
crate-type = ["rlib", "staticlib", "cdylib"]
12+
13+
[features]
14+
python = ["dep:pyo3", "dep:numpy"]
1215

1316
[dependencies]
1417
num-complex = "0.4"
18+
numpy = { version = "0.22", optional = true }
19+
pyo3 = { version = "0.22", optional = true, features = ["extension-module"] }
1520
rayon = "1"
1621
rustfft = "6"
1722

pyproject.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[build-system]
2+
requires = ["maturin>=1,<2"]
3+
build-backend = "maturin"
4+
5+
[project]
6+
name = "pykore"
7+
dynamic = ["version"]
8+
9+
[tool.maturin]
10+
python-source = "python"
11+
module-name = "pykore._kore"
12+
features = ["python"]
13+
14+
[tool.pytest.ini_options]
15+
testpaths = ["tests/python"]

python/pykore/__init__.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from importlib import import_module
2+
3+
__all__ = [
4+
"Grid",
5+
"Config",
6+
"State",
7+
"Kernel",
8+
"Diagnostics",
9+
"DiagnosticsSummary",
10+
]
11+
12+
13+
def __getattr__(name: str):
14+
if name not in __all__:
15+
raise AttributeError(f"module 'pykore' has no attribute {name!r}")
16+
17+
try:
18+
module = import_module("pykore._kore")
19+
except ImportError as exc:
20+
raise ImportError(
21+
"pykore native extension is not built yet; run `maturin develop` first"
22+
) from exc
23+
24+
return getattr(module, name)
897 Bytes
Binary file not shown.

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ pub mod ffi;
1818
mod fft;
1919
mod grid;
2020
mod operators;
21+
#[cfg(feature = "python")]
22+
mod python;
2123
mod sp;
2224
mod state;
2325
mod threading;

0 commit comments

Comments
 (0)