A NumPy implementation in Rust for Python code running in sandboxed environments (RustPython/WASM).
41,775 tests passing (2026-03-23)
Python code (import numpy as np)
│
numpy/ package (Python wrappers + submodules)
│
_numpy_native (Rust ← RustPython bindings)
│
numpy-rust-core (ndarray, nalgebra, rustfft, rand)
All numerical operations run in native Rust. The Python layer handles API surface and dtype routing.
| Suite | Result |
|---|---|
cargo test |
454 passed |
| Python vendored tests | 1,188 passed |
NumPy compat (test_numeric.py) |
1,204 passed, 10 expected failures |
NumPy ufunc compat (test_ufunc.py) |
106 passed, 344 expected failures |
NumPy I/O compat (test_io.py) |
23 passed, 2 skipped |
| Upstream NumPy tests (74 files, 86K lines) | 38,800 passed, 0 failures, 361 skipped |
74 vendored upstream NumPy test files cover: core array ops, math, indexing, dtypes, scalars, shape manipulation, einsum, array padding, set ops, nan functions, histograms, index tricks, stride tricks, type checking, masked arrays, polynomials, FFT, linalg, random, and more.
# Run all upstream tests (scan mode) — uses CPython + real numpy
python3 tests/numpy_compat/run_upstream.py --scan
# Run a single upstream test file
python3 tests/numpy_compat/run_upstream.py upstream/core_test_numeric.py| Submodule | Notes |
|---|---|
np.linalg |
matmul, inv, solve, det, eig, svd, qr, norm, cholesky, lstsq, pinv — via nalgebra |
np.fft |
fft/ifft (Rust/rustfft), rfft/irfft, fft2/fftn, fftfreq, fftshift |
np.random |
Full distribution set, both legacy and Generator API, SeedSequence |
np.ma |
Complete MaskedArray (224 symbols): creation, masking, ufunc wrappers, reductions, manipulation, set ops, statistics |
np.testing |
assert_allclose, assert_array_equal, assert_equal, assert_raises, suppress_warnings, temppath |
np.polynomial |
Polynomial, Chebyshev, Legendre, Hermite, HermiteE, Laguerre classes with val/fit/add/sub/mul/der/int |
np.char / np.strings |
35+ element-wise string operations |
np.lib.scimath |
Complex-safe math (sqrt, log, log2, log10, arcsin, arccos) |
np.lib.stride_tricks |
as_strided, broadcast_shapes, sliding_window_view |
np.dtypes |
DType class stubs for all numeric types |
np._core |
Full internal compatibility package (15 submodules) |
np.exceptions |
AxisError, ComplexWarning, DTypePromotionError, RankWarning, TooHardError |
np._utils |
asbytes, asunicode, Version |
- C-extension ufunc machinery. The low-level strided-loop API,
PyUFunc_OO_Ogeneric loops, and gufunc signature introspection all require CPython internals. The 344 ufunc xfails are entirely in this category. - C-extension custom dtypes (e.g.
rational). Requires CPython's type system. np.memmap. Memory-mapped files aren't available in WASM.nditer. The N-dimensional iterator requires CPython C-level iteration protocol.errstatewithraisemode. FP exception signaling requires OS-level signal handling.
- Slice views are copies.
arr[1:4]returns a copy — thendarraycrate can't represent sub-arrayArcArrayviews.view()andreshape()on the whole array work in O(1).shares_memory()/may_share_memory()work correctly via Arc pointer equality. out=with slices. Writes toclip(out=arr[1:4])don't propagate back because slices are copies.- Complex scalars. Scalars extracted from complex arrays come back as
(re, im)tuples — a RustPython limitation. - Fortran-order layout. All arrays are C-contiguous.
order='F'is accepted but data is always row-major. - Long double.
np.longdoublemaps tofloat64(Rust has no 80-bit float). Same fornp.clongdouble→complex128.
einsumuses brute-force index iteration — correct but slow for large contractions.rfft/irfftare pure Python.fft/ifftare native Rust viarustfft.- No SIMD or multi-threading. All operations are single-threaded.
casting=, subok= on most ufuncs. out= is silently ignored except for in-place operators.
This repo is included as a git submodule in codepod at packages/numpy-rust. The codepod Python binary links it via a Cargo feature flag:
cargo build -p codepod-python --features numpy --target wasm32-wasip1# Install git hooks (formatting + clippy on commit, full tests on push)
./hooks/install.sh# Build (native)
cargo build --release
# Build (WASM, as used by codepod)
cargo build -p numpy-rust-wasm --target wasm32-wasip1
# Rust unit tests
cargo test --release
# Python integration tests
bash tests/python/run_tests.sh
# NumPy compat tests (tracks known gaps via xfail list)
./target/release/numpy-python tests/numpy_compat/run_compat.py --ci
./target/release/numpy-python tests/numpy_compat/run_ufunc_compat.py --ci
./target/release/numpy-python tests/numpy_compat/run_io_compat.py --ci
# Upstream NumPy tests (74 vendored test files)
./target/release/numpy-python tests/numpy_compat/run_upstream.py --scanGitHub Actions runs on every push and PR to main:
- Test —
cargo test(core + workspace) - Lint —
cargo fmt --check+cargo clippy -D warnings - Python Tests — builds the binary and runs all vendored Python test files
- WASM Build Check — verifies the project compiles for
wasm32-wasip1