Osiris
Osiris is the project for osr, a small, data-oriented Lisp-to-Python
compiler. The language is designed around readable Python output, explicit
Python decorators, hygienic macros, static types, Unicode names, and
tooling-readable metadata.
The current compiler implements a lossless tokenizer, a recoverable nom
reader, surface AST lowering, hygienic macro expansion, name and alias
resolution, typed HIR, defstruct, static schemas and records, and structured
Python code generation. It also emits deterministic .osri interfaces and
source maps, compiles source modules as one dependency graph, and validates
locked static extension interfaces without importing Python packages.
The compiler-embedded standard library supplies Clojure-inspired control flow
without making the reader or Rust core grow for every form. The implemented
surface includes
threading (->, ->>, cond->, some->, as->, doto), binding and
branching (when, if-let, if-some, case, condp), comprehensions
(for, doseq, dotimes), constant-stack loop/recur, letfn, defn- and
trampoline, lazy sequences and reductions, structured exceptions/resources
(assert, throw, time),
typed ^:dynamic Var bindings, and the initial future/promise/locking
primitives plus eager, ordered parallel forms (pmap, pcalls, pvalues) and
the typed sequence predicates (empty?, seq?, coll?, sequential?). Dynamic
values use Python contextvars,
including context capture when a future is submitted. See the
control-flow coverage matrix
for exact semantics, tests, and intentionally deferred facilities such as
with-bindings, with-local-vars, with-redefs, STM, Agents, and the complete
Clojure sequence/transducer protocols. Osiris borrows these designs but does
not claim Clojure compatibility.
Requirements
- Rust 1.85 or newer
- Python 3.11 or newer for Python packaging and extension builds
uvfor Python development
Project Quick Start
Create a new uv project with an Osiris source root and starter module:
osr init my-project
cd my-project
uv run osr run src/main.osr
To add Osiris to an existing uv project, run this from its root (or pass the directory explicitly):
osr init --existing
osr init --existing path/to/project
init preserves the existing pyproject.toml layout, comments, project
metadata, and dependencies. It creates osiris.jsonc and src/main.osr only
when those files do not exist, and asks uv to add
osiris-lang to the development dependency group. Re-running the command is
safe. A new project path must not already exist; use --existing when joining
an established uv project.
Osiris discovers the nearest osiris.jsonc; the adjacent pyproject.toml
continues to own Python package metadata and dependencies. JSONC comments and
trailing commas are accepted. A typical configuration is deliberately small:
{
"$schema": "https://raw.githubusercontent.com/mjason/osiris/main/schemas/osiris.schema.json",
"source": ["examples"],
"outDir": "dist",
"targetPython": "3.11",
"strict": true,
"displayLocale": "zh-CN"
}
source defines the complete project source scope. exclude contains
project-root-relative glob rules shared by compilation and language tooling;
a value without glob syntax, such as src/generated, also excludes its
descendants.
Patterns such as src/**/generated/** and src/**/*_test.osr can select files
inside a source root when a project needs those rules. outDir is the default
compile destination; artifact selection remains an explicit
osr compile --emit option. One invocation targets one Python version.
Changing targetPython invalidates target-sensitive analysis, interfaces,
extension resolution, and build artifacts.
displayLocale accepts any well-formed BCP 47 language tag and is used by
hover, completion, and signature help when Rich Metadata provides localized
labels or documentation. For example:
"zh-CN"requests Simplified Chinese labels and documentation."en"requests English labels and documentation."ja"requests Japanese labels and documentation.
It changes tooling presentation, not binding identity or generated Python.
RFC 4647 lookup selects the closest authored locale and then falls back to the
authored :default; the configuration is not a closed locale enum. An explicit
locale sent by an LSP client takes precedence over the project value. osr init writes "displayLocale": "zh-CN" by default. LSC intentionally does not
inherit it: pass --locale <bcp47> when a finite CLI query needs a particular
language.
LSC project queries use a disposable libSQL semantic graph stored at
.osiris/cache/language-graph.sqlite3; it never enters dist.
Graph-only searches open a matching cache before workspace analysis. Source,
configuration, lock, or static-interface changes refresh it automatically;
unchanged files reuse hashes from a persistent input manifest, so hot validation
does not reread the workspace. osr lsc cache rebuild remains available as a
full recovery rebuild.
With that configuration and examples/hello.osr:
cargo run --bin osr -- check examples/hello.osr
cargo run --bin osr -- build
cargo run --bin osr -- watch
The multi-file examples/tutorial/app.osr
demonstrates importing another Osiris module with :as and :refer, importing
a macro with import-for-syntax, and keeping Python py/import separate:
(import tutorial.transforms :as transforms :refer [sum-values])
(import-for-syntax tutorial.macros :refer [unless])
(py/import math :as math)
Run cargo run --bin osr -- check examples/tutorial/app.osr to analyze the
whole local dependency graph. See examples/README.md
for the module-to-path mapping and generated outputs.
check parses and validates the project and leaves the working tree
unchanged. build compiles the complete project described by osiris.jsonc,
prints the output directory (dist/ by default), and publishes one artifact
set atomically. watch reruns that same build when a non-excluded .osr
source changes. compile remains the lower-level command for explicit source
and --emit control.
Successful project builds keep one bounded cache entry in .osiris/cache/.
It is separate from dist/, is never published, and can always be deleted.
Unchanged builds leave an identical dist/ untouched; a missing or stale
dist/ can be restored from the validated cache. Generated Python is formatted
by the Ruff formatter embedded in osr before source maps are produced, so no
external ruff command or project Ruff configuration is required. Authored
fallback documentation becomes Python docstrings, and compiler-owned names are
kept recognizable without exposing hygienic internal identities.
dist/hello.pyis the readable generated Python module.dist/hello.osriis the public, versioned Osiris compilation interface used by downstream modules and tools.dist/hello.py.mapmaps generated Python spans back to source and macro-expansion spans.- A distribution-level
*.records.jsonsidecar is emitted only when the compiled modules own public static records (or when--emit recordsis requested).
Python dependencies and Osiris extensions are ordinary Python project
dependencies. Add them from PyPI (or another index/path supported by uv) in
[project].dependencies, then let uv resolve and lock them. The compiler
automatically reads osiris.toml and .osri resources only from distributions
reachable in the runtime lock graph; it never imports extension Python code or
scans unrelated installed packages during discovery.
Publishing a Package
An Osiris package is an ordinary Python distribution whose wheel contains
compiled .osri interfaces and an automatically generated
dist-info/osiris.toml marker. Create one with:
osr init --package acme-osiris
cd acme-osiris
uv lock
uv build --python 3.11
uv publish dist/*
The generated pyproject.toml pins the installed compiler distribution and
selects its bundled PEP 517 backend:
[build-system]
requires = ["osiris-lang==<osr-version>"]
build-backend = "osiris_build"
osr init --package acme-osiris creates
src/acme_osiris/core.osr with module acme_osiris.core. Each public module
is compiled into readable Python plus an .osri interface; the backend adds
one [[extension]] marker entry for each interface, using the module name
(acme_osiris.core) as its ID. Do not write osiris.toml by hand.
To convert an existing uv package, run osr init --existing --package from
its root. The command preserves existing metadata and refuses to replace a
different build backend. If that package needs Hatchling, maturin, or another
backend for additional native build work, backend composition is not yet
supported and should be handled as a separate distribution.
Consumers install the published extension exactly like any other dependency:
uv add acme-osiris
uv lock
uv run osr check src/main.osr
The compiler follows the consumer's locked runtime dependency graph and reads
the extension's static marker and interfaces without importing its Python
package during discovery. Public interface dependencies of an extension must
therefore be declared in [project].dependencies, so they are preserved as
standard Requires-Dist metadata.
Native CLI
cargo run --bin osr -- --version
cargo run --bin osr -- check source.osr
cargo run --bin osr -- build
cargo run --bin osr -- watch
cargo run --bin osr -- compile source.osr
cargo run --bin osr -- expand source.osr
cargo run --bin osr -- fmt --check source.osr
cargo run --bin osr -- lsc semantic source.osr --format json
cargo run --bin osr -- lsc hover osiris.core/map --locale en
cargo run --bin osr -- lsc workspace-search "format message" --format json
cargo run --bin osr -- lsc symbol-context --at examples/hello.osr:10:3 --format json
cargo run --bin osr -- syntax
cargo run --bin osr -- doc '{ documentationCapabilities { snapshotId } }'
cargo run --bin osr -- lsp
cargo test --all-targets --all-features
check runs the frontend and semantic gates. build emits readable Python,
an .osri compilation interface, and a .py.map source map into dist/ by
default. expand shows macro output, fmt applies the canonical formatter,
and lsc exposes the finite semantic and navigation operations used by the
LSP without requiring an editor protocol. syntax prints the embedded English
language manual, while doc queries the embedded read-only documentation
snapshot with GraphQL. Compilation errors return status 1; command-line misuse
returns status 2.
The reader is implemented as composable nom grammar productions over a
lossless token stream. All whitespace, commas, comments, original Unicode
spelling, and raw string spelling remain available to future formatting and
LSP stages. Symbols and keywords also carry an NFC canonical spelling for
collision-safe name resolution.
Python package
The PyPI wheel carries osr as a native Rust executable. Python and its
packaging tools install the wheel, but they do not launch or host the CLI. The
same wheel contains the osiris_build PEP 517 backend used by Osiris source
distributions. It does not provide a shared runtime package: each build links
only reachable standard support into the generated distribution's private
__osiris_runtime__ package, so deployed Python does not depend on
osiris-lang. Python dependencies continue to be declared in
pyproject.toml and locked by uv.
The PyPI distribution is named osiris-lang because the osiris project name
is already occupied. Its importable build-backend package is osiris_build:
uv tool install osiris-lang
osr --version
For repository development:
uv sync
uv run osr --version
The package version is defined once in Cargo.toml; maturin uses it for the
platform wheel and places the native executable in the wheel's scripts area.
Consequently osr, osr watch, and osr lsp run without a Python interpreter
process.
VS Code
The extension lives in editors/vscode and delegates all
semantic behavior to osr lsp. Until Marketplace publishing is enabled, open
the repository's GitHub Releases,
select the latest vscode-vX.Y.Z release, download its .vsix, and run
Extensions: Install from VSIX... in VS Code.
Maintainers publish Python releases with a vX.Y.Z tag and VS Code releases
with a separate vscode-vX.Y.Z tag. Both tags must match the corresponding
package version committed in the repository. Trusted Publisher fields and the
full tag procedure are documented in docs/releasing.md.
The current language design is in
docs/language-design.md. Compiler ownership and
the kernel/macro/extension boundary are documented in
docs/architecture.md.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file osiris_lang-0.3.20.tar.gz.
File metadata
- Download URL: osiris_lang-0.3.20.tar.gz
- Upload date:
- Size: 990.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9d8a564e5220e208e792996d633a030bab8045412d0c607369f53c3a76b43a4b
|
|
| MD5 |
6a6c12a3a2c9bbc3cea1bf94bfacec8b
|
|
| BLAKE2b-256 |
a2f0cfe4d60d36d68702745aa06a257d25e5de6ab8dc3c61e64676d48867f778
|
Provenance
The following attestation bundles were made for osiris_lang-0.3.20.tar.gz:
Publisher:
publish-pypi.yml on mjason/osiris
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
osiris_lang-0.3.20.tar.gz -
Subject digest:
9d8a564e5220e208e792996d633a030bab8045412d0c607369f53c3a76b43a4b - Sigstore transparency entry: 2288136543
- Sigstore integration time:
-
Permalink:
mjason/osiris@c6268054c3f194d618a0f588f47e977ced7776bd -
Branch / Tag:
refs/tags/v0.3.20 - Owner: https://github.com/mjason
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@c6268054c3f194d618a0f588f47e977ced7776bd -
Trigger Event:
push
-
Statement type:
File details
Details for the file osiris_lang-0.3.20-py3-none-win_amd64.whl.
File metadata
- Download URL: osiris_lang-0.3.20-py3-none-win_amd64.whl
- Upload date:
- Size: 8.1 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d1c7e1281e00dd03adbfedb8a138026e4dd76453cab572b599251e93018e9716
|
|
| MD5 |
7294ae8f707ea6c7df64bda732ad1fd7
|
|
| BLAKE2b-256 |
82c442100bedfc15c12d26dc25656b8fb506693a9c933352603d56b14f075783
|
Provenance
The following attestation bundles were made for osiris_lang-0.3.20-py3-none-win_amd64.whl:
Publisher:
publish-pypi.yml on mjason/osiris
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
osiris_lang-0.3.20-py3-none-win_amd64.whl -
Subject digest:
d1c7e1281e00dd03adbfedb8a138026e4dd76453cab572b599251e93018e9716 - Sigstore transparency entry: 2288136766
- Sigstore integration time:
-
Permalink:
mjason/osiris@c6268054c3f194d618a0f588f47e977ced7776bd -
Branch / Tag:
refs/tags/v0.3.20 - Owner: https://github.com/mjason
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@c6268054c3f194d618a0f588f47e977ced7776bd -
Trigger Event:
push
-
Statement type:
File details
Details for the file osiris_lang-0.3.20-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: osiris_lang-0.3.20-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 7.9 MB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7a06bab74fca72286c7cba458ba82f40b36826602371975771c31fb20cd7713e
|
|
| MD5 |
df015334adb896d558eef4fba6af1e43
|
|
| BLAKE2b-256 |
2a58ba62e737b81b62634da3297f4d732513ecec05fa00969a085064f1317dbe
|
Provenance
The following attestation bundles were made for osiris_lang-0.3.20-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
publish-pypi.yml on mjason/osiris
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
osiris_lang-0.3.20-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
7a06bab74fca72286c7cba458ba82f40b36826602371975771c31fb20cd7713e - Sigstore transparency entry: 2288136610
- Sigstore integration time:
-
Permalink:
mjason/osiris@c6268054c3f194d618a0f588f47e977ced7776bd -
Branch / Tag:
refs/tags/v0.3.20 - Owner: https://github.com/mjason
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@c6268054c3f194d618a0f588f47e977ced7776bd -
Trigger Event:
push
-
Statement type:
File details
Details for the file osiris_lang-0.3.20-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: osiris_lang-0.3.20-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 7.3 MB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a98b6471b62973b722690d0e36560d6b5b995520edb1cd8056a326a3505d58aa
|
|
| MD5 |
a759b5e2465443f8a22f9d7c8a63508a
|
|
| BLAKE2b-256 |
838fc4b5b9ca89ae3622bf6ea70f26445be434b91bae698691cfdf133386af45
|
Provenance
The following attestation bundles were made for osiris_lang-0.3.20-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
publish-pypi.yml on mjason/osiris
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
osiris_lang-0.3.20-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
a98b6471b62973b722690d0e36560d6b5b995520edb1cd8056a326a3505d58aa - Sigstore transparency entry: 2288136716
- Sigstore integration time:
-
Permalink:
mjason/osiris@c6268054c3f194d618a0f588f47e977ced7776bd -
Branch / Tag:
refs/tags/v0.3.20 - Owner: https://github.com/mjason
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@c6268054c3f194d618a0f588f47e977ced7776bd -
Trigger Event:
push
-
Statement type:
File details
Details for the file osiris_lang-0.3.20-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: osiris_lang-0.3.20-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 7.3 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8762751e84ca0fb216d4d96248f1518cd1154b6a20ef0d41fedb7de53927773f
|
|
| MD5 |
d8bb620e9de56cf394191e1ce101d3c5
|
|
| BLAKE2b-256 |
bf23910e7275b1063eea2f417e83173fd6ec71ff81251d5eecd516b2ef98d84e
|
Provenance
The following attestation bundles were made for osiris_lang-0.3.20-py3-none-macosx_11_0_arm64.whl:
Publisher:
publish-pypi.yml on mjason/osiris
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
osiris_lang-0.3.20-py3-none-macosx_11_0_arm64.whl -
Subject digest:
8762751e84ca0fb216d4d96248f1518cd1154b6a20ef0d41fedb7de53927773f - Sigstore transparency entry: 2288136669
- Sigstore integration time:
-
Permalink:
mjason/osiris@c6268054c3f194d618a0f588f47e977ced7776bd -
Branch / Tag:
refs/tags/v0.3.20 - Owner: https://github.com/mjason
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@c6268054c3f194d618a0f588f47e977ced7776bd -
Trigger Event:
push
-
Statement type: