tyc build
tyc build [PATH] [--out DIR] [--no-format] [--check] [--no-sync] [--with-ty] [--optimise]Runs the full compilation pipeline and writes the emitted Python to the output directory (default build/, configurable via [project] out).
Examples
tyc build # full project → build/tyc build --out dist/ # → dist/ insteadtyc build --no-format # skip the ruff format post-processtyc build --check # dry-run: list every file that would be writtentyc build -O # apply [optimise] level = 1 for this invocationtyc build --no-sync # skip `uv sync` (also TYC_NO_SYNC=1); pyproject.toml is still mergedtyc build --with-ty # then run Astral's `ty` over the emitted PythonWhat it produces
For a project with src/main.ty and src/users.ty:
build/├── main.py├── users.py├── .sourcemaps/│ ├── main.py.map # source map v2 (under .sourcemaps/ since v0.6.1)│ └── users.py.map└── typhon_runtime/ # only if Result / go / lazy let / freeze let / as! / auto-parallel are used ├── __init__.py ├── result.py ├── tasks.py ├── lazy.py ├── parallel.py ├── freeze.py ├── cast.py ├── traceback.py └── stdlib.pyAnd, if you have .dty stubs:
build/├── ... (above)└── *.pyi # PEP 561 stubs alongside emitted .pyThe pipeline stages
- Lex + parse (
tyc-syntax). - Resolve (
tyc-resolve) — symbol tables, scopes,let/mutclassification. - Type-check (
tyc-types) — narrowing, signature compatibility, exhaustiveness. - Analyse (
tyc-analyse) — purity, async, comptime, auto-gather. - Desugar (
tyc-desugar) — mergeimplblocks, expand?, lowergather:/go/lazy, evaluatecomptime. - Emit (
tyc-emit) — hand-written printer produces.py+.py.map. - Format (
tyc-format) — post-process throughruff formatwhen[emit] format = true.
Each stage is a Salsa query; on incremental rebuilds, only invalidated outputs are recomputed.
Flags
| Flag | Effect |
|---|---|
--out DIR (-o) | Override the [project] out directory. Relative paths resolve against the project root. |
--no-format | Skip the ruff format post-process. |
--check | Dry-run mode. The full pipeline still runs (so type errors continue to surface), but no files are written — instead, every file that would be created or overwritten is listed. Useful for previewing the effect of a class-default or skip-decoration-bases change before committing to disk. |
--no-sync | Skip the uv sync step; pyproject.toml is still merged so the next regular build picks the manifest up. Also honoured via TYC_NO_SYNC=1. |
--with-ty | After a successful build, run Astral’s ty over the emitted Python as a typeshed-backed second-stage check — the same behaviour as [checker] external = "ty", for one invocation. ty errors fail the build. Requires ty on PATH. |
--optimise / -O (alias --optimize) | Apply [optimise] level = 1 for this invocation — flips the default of auto-memoise, auto-gather, auto-parallel, and pgo-memoise to on. Overrides a config level = 0, but an explicit [strictness] entry for any of those knobs still wins. |
.py files alongside .ty
Plain .py files in src/ are copied verbatim into the build output (skipping __pycache__/, tests/, .venv/, and dotfiles). This is the recommended escape hatch when a class can’t be expressed cleanly in Typhon — write it in Python, drop it next to your .ty files, and the relative import keeps working at runtime. A relative .py import that resolves to a file outside src/ fires tyc::orphan_py_import so the missing-at-runtime case is caught at build time.
When the build fails
If any error-severity diagnostic fires during check or analyse, the build does not produce output. The diagnostics are emitted to stderr and the process exits 1.
You can run tyc check first to fail-fast in CI without producing partial artefacts.
What’s not in build/
- Python bytecode (
*.pyc,__pycache__/) — created by Python at runtime, not bytyc build. - Cargo artefacts (
target/) — those are from buildingtycitself, kept in thetyc/subdirectory. - Editor or test caches —
tycdoesn’t manage those.
Safe to delete build/ at any time; it regenerates.
Incremental rebuilds
Salsa caches every stage’s output. If you change one function in one file, the rebuild typically touches only that file’s emit, not the whole project. The cost is roughly proportional to the change size.
Where next
tyc run— execute a Typhon program (in-process VM by default,--compilefor build-then-exec).tyc check— type-check without emit.- Lowering Overview — what each construct compiles to.