The Vendored Ruff Fork
tyc/vendor/ contains a fork of five Ruff crates. They are workspace members; consumer crates depend on them as ordinary path dependencies.
What’s vendored
tyc/vendor/├── ruff_text_size/ TextSize / TextRange newtypes├── ruff_source_file/ Line index over a source string├── ruff_python_trivia/ Whitespace / comment helpers├── ruff_python_ast/ Python AST + Typhon's Mutability extension└── ruff_python_parser/ Lexer + parser + let/mut soft keywordsWhy a fork
Ruff’s parser is the fastest, most spec-compliant Python parser in Rust. It is not published to crates.io — only the Ruff binary is shipped to PyPI. So to use the parser we either had to:
- Depend on Ruff via a git dep (fragile across upstream changes).
- Vendor the source we need.
Vendoring won. The deltas against upstream are tiny:
Mutabilityenum and an extra field on assignment AST nodes (ruff_python_ast).letandmutsoft-keyword support in the lexer / parser (ruff_python_parser).
The rest is upstream Ruff verbatim.
Tracking upstream
tyc/vendor/UPSTREAM records the upstream SHA we vendored. Sync work:
- Check the upstream Ruff repo for relevant changes.
- Cherry-pick into vendor branches.
- Update
tyc/vendor/UPSTREAM. - Run
cargo test --workspaceto verify.
In practice this is monthly; the parser is stable.
Why not vendor ruff_python_codegen?
The Phase-0 plan called for it. We ended up writing a hand-rolled printer in tyc-emit because:
- Upstream codegen doesn’t expose the per-statement line-offset hook needed for
.py.mapv2. - The Typhon-specific lowerings (
Result?,gather:,go,lazy) needed custom emission anyway.
Vendoring ruff_python_codegen remains an open follow-up — see tyc/vendor/README.md in the repo.
Why not rustpython-parser (on crates.io)?
It lags Ruff on Python-version coverage and is slower. It’s the fallback if Ruff’s parser ever stops being usable.
When upstream renames things
Every Ruff API call in tyc sits behind a one-function-wide module of our own (in tyc-syntax). When upstream renames a node, the change is localised.
Where next
- Architecture — the bigger picture.
- Workspace Layout — every crate.
- Ruff upstream repo — for upstream API reference.