Commit 49dd7b0
OMC reaches into Python: pyo3 embed + np/pd integration written in OMC
The hard half of integration: OMC programs can now drive numpy,
pandas, requests, sqlite, anything pip-installable. The integration
LIBRARIES are written in OMC itself — not Rust. py_* primitives are
the only Rust-side surface; everything else is OMC.
What landed:
* `python-embed` feature on omnimcode-core (off by default — building
doesn't require libpython unless you want Python integration).
Bumped to pyo3 0.23 + PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 for
Python 3.14 support.
* src/python_embed.rs: 8 builtins covering the whole py surface:
py_import / py_call / py_get / py_call_fn / py_eval / py_exec /
py_repr / py_clear_registry. Bidirectional Value ↔ PyObject
conversion: scalars / lists / tuples / dicts / numpy ndarrays
convert automatically; everything else becomes an opaque handle.
Handle IDs start at 10^15 to never collide with regular OMC ints
(caught by a passing-int-array bug in the smoke test).
* maybe_register_python() in main.rs: gated on OMC_PYTHON=1 env var
AND the python-embed feature flag. Two-gate so the same binary
serves users who don't want the Python runtime cost.
Bug fixed along the way:
* Aliased imports (`import "lib" as alias`) were renaming each fn
to `alias.fn` but NOT rewriting intra-module calls. So a helper
pattern like `fn _np() {...}` called from `fn array(items) {
return py_call(_np(), ...)` broke under aliasing — `_np` looked
up unprefixed but only `pd._np` existed in the function table.
Added rewrite_module_calls() AST walk on import: every Call
expression whose name is in the module's defined-set gets the
alias prefix. Required for the np.omc / pd.omc helpers to work.
OMC integration libraries (written in OMC):
* examples/lib/np.omc — numpy bridge. 30 lines. Exposes array /
zeros / ones / arange / linspace / mean / median / std / dot /
sort / argsort / percentile / quantile / corrcoef and pi/e/inf
constants. Each fn is one or two lines on top of py_call.
* examples/lib/pd.omc — pandas bridge. 60 lines. Exposes read_csv /
read_json / read_parquet / read_excel / read_table loaders, plus
shape / columns / col / head / tail / select_cols / group_by /
agg_mean / agg_count / describe / to_dict.
Demo:
* examples/datascience/movielens_harmonic.omc — the real thing.
Pipeline: pd.read_csv (10k rows in 276ms) → numpy stats on
ratings → harmonic_partition (OMC-distinctive — 6 attractor
buckets in 1ms) → numpy mean/std per bucket → pandas group_by +
numpy argsort for top-10 movies. End-to-end real data, real
libraries, real OMC.
Strategic positioning: integration scripts get written in OMC.
Users fork np.omc / pd.omc to add wrapping for new methods, no
Rust knowledge needed. Same playbook as Lua embedding — small C
API, ecosystem in Lua.
omnimcode-python (the legacy "Python embeds OMC" wrapper) excluded
from the workspace because its `extension-module` pyo3 feature
conflicts with python-embed at link time. Build it separately
via `cargo build -p omnimcode-python` if needed; functionally
eclipsed by the inverse direction landing here.
43/43 functional examples produce identical output under tree-walk
and VM. 92/92 unit tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>1 parent cb769e9 commit 49dd7b0
11 files changed
Lines changed: 981 additions & 86 deletions
File tree
- examples
- datascience
- lib
- omnimcode-core
- src
- omnimcode-python
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
6 | 5 | | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
7 | 13 | | |
8 | 14 | | |
9 | 15 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
0 commit comments