mojox-core
Pure model layer for the mojox build system. No I/O, no subprocess, no filesystem access at module level. All data types are frozen dataclasses; every transformer is a pure function (data in, data out).
Install
uv add mojox-core
Requires Python 3.10+. Only runtime dependency is packaging>=23.0
(plus tomli on Python < 3.11). mojox and mojox-build 0.6 require
mojox-core 0.6.x.
Pipeline
The core exposes a five-stage pipeline where each step takes immutable data and returns immutable data:
parse -> discover -> resolve -> plan -> serialize
I/O readers live in the separate mojox_core.io subpackage. Consumers can
skip them entirely and feed fixtures directly into the pipeline.
Quick start
from pathlib import Path
from mojox_core import (
parse_manifest,
discover,
resolve,
plan,
serialize,
LocalSettings,
)
from mojox_core.io.manifest import read as read_manifest
from mojox_core.io.toolchain import resolve as resolve_toolchain
from mojox_core.io.environment import (
read_distributions,
read_lockfile,
read_host_facts,
)
from mojox_core import build_env
# 1. Read raw TOML (I/O)
raw = read_manifest(Path("."))
# 2. Parse manifest (pure)
manifest = parse_manifest(raw)
# 3. Discover targets by convention (pure)
targets = discover(manifest, Path("."))
# 4. Resolve build policy from all precedence layers (pure)
policy = resolve(manifest, "dev", {}, LocalSettings.EMPTY)
# 5. Detect toolchain and build environment (I/O)
toolchain = resolve_toolchain()
dists = read_distributions()
lock = read_lockfile(Path("."))
env = build_env(dists, lock, toolchain.mojo_path, toolchain.version)
host = read_host_facts(Path("."))
# 6. Plan mojo invocations (pure)
commands = plan(targets, env, policy, toolchain, host)
for cmd in commands:
print(cmd.kind, cmd.argv)
# 7. Serialize to the `mojox metadata` JSON schema (pure)
metadata = serialize(targets, env, policy, commands, toolchain, diagnostics=())
Public API
Types
All exported from mojox_core. Every type is a frozen dataclass or enum.
| Type | Description |
|---|---|
Manifest |
Parsed [tool.mojox] config and PEP 621 project metadata |
Command |
A planned mojo invocation (data, not execution) |
CommandKind |
Enum of command kinds |
Policy |
Resolved build policy (profile + defines + flags) |
Profile |
Build profile (dev or release) with optimization/debug settings |
Target |
A single build/test/example/binary target |
TargetKind |
Enum of target kinds |
TargetGraph |
The full set of discovered targets |
ResolvedEnv |
Resolved environment (import paths, library paths, mojo binary) |
Toolchain |
Detected Mojo toolchain info |
HostFacts |
Host platform facts |
LocalSettings |
Parsed .mojox/config.toml settings |
Diagnostic |
Lint diagnostic |
LintConfig |
Lint configuration |
DistEntry |
Distribution metadata entry |
DistKind |
Enum of distribution kinds |
BinaryEntry |
Binary entry in a distribution |
Transformers
Pure functions. No side effects, no I/O.
parse_manifest(data: dict) -> Manifest
discover(manifest: Manifest, root: Path) -> TargetGraph
resolve(manifest: Manifest, profile_name: str, cli_overrides: dict, settings: LocalSettings) -> Policy
plan(graph: TargetGraph, env: ResolvedEnv, policy: Policy, toolchain: Toolchain, host: HostFacts) -> tuple[Command, ...]
build_env(dists: list[dict], lock_data: dict | None, mojo_path: str, mojo_version: str) -> ResolvedEnv
serialize(graph: TargetGraph, env: ResolvedEnv, policy: Policy, commands: tuple[Command, ...], toolchain: Toolchain, diagnostics: tuple[Diagnostic, ...]) -> dict
parse_settings(user: dict | None, project: dict | None, env: dict[str, str]) -> LocalSettings
I/O readers
In the mojox_core.io subpackage. These are the only functions that touch
the filesystem or run subprocesses.
mojox_core.io.manifest.read(path: Path) -> dict # read & parse pyproject.toml
mojox_core.io.toolchain.resolve() -> Toolchain # detect installed Mojo compiler
mojox_core.io.environment.read_distributions(platlib=None) -> list[dict] # scan installed dists
mojox_core.io.environment.read_lockfile(project_root: Path) -> dict | None
mojox_core.io.environment.read_host_facts(manifest_dir: Path, environ: Mapping[str, str] | None = None) -> HostFacts # locale: LANG/LC_* of environ (default os.environ)
read_host_facts keeps only the LANG and LC_* variables of environ, and
the planner forwards them to every command, falling back to LC_ALL=C.UTF-8
when there are none. As a result, each command's env in mojox metadata
includes the host locale.
Errors
class ConfigError(Exception):
key_path: str # dotted path to the offending key
message: str # human-readable explanation
Raised on invalid manifest or settings. No KeyError or TypeError reaches
the caller -- every rejection is a ConfigError with a structured key path.
Testing without I/O
Because the pipeline is pure, you can test any stage by constructing fixtures directly:
from mojox_core import Manifest, discover, TargetGraph
manifest = Manifest(...) # build the frozen dataclass by hand
graph = discover(manifest, some_temp_dir)
assert isinstance(graph, TargetGraph)
No mojo compiler, no installed packages, no pyproject.toml required.
See also
- mojox -- CLI that drives the full build
- mojox-build -- PEP 517 build backend
License
MIT
Metadata
Release files for mojox-core 0.6.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mojox_core-0.6.1.tar.gz | 37.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mojox_core-0.6.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 65.0 kB
Release files / mojox_core-0.6.1.tar.gz
| Download URL | mojox_core-0.6.1.tar.gz |
|---|---|
| Size | 37.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
80cf86a2b903402b615f6cf85a6600d7603b32bc4fd36b442407f3e89905be74
|
|
BLAKE2b-256 checksum How to use checksums |
ea7caff8ed19bf1e2f80231bb586a39a5072f29bc697898673eac760ea3fa4f3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.21 {"installer":{"name":"uv","version":"0.12.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / mojox_core-0.6.1-py3-none-any.whl
| Download URL | mojox_core-0.6.1-py3-none-any.whl |
|---|---|
| Size | 28.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d51f2877a713c534b15355af8243b07f148ffe586eb01b039ff8152f48234e08
|
|
BLAKE2b-256 checksum How to use checksums |
389ad2dcddaa68f066558a3a46c7d38631126cc4466e578249cfa257f7a9db27
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.21 {"installer":{"name":"uv","version":"0.12.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|