ty-scip
A fast SCIP indexer for Python, powered by ty.
ty-scip is a preview SCIP indexer for Python. It turns ty's Python
project model and semantic navigation results into a deterministic index that
is tested with SCIP 0.10 and the SCIP 0.8-based scip-cli 2.7 conversion path.
This is an independent project. It is not affiliated with or endorsed by Astral or Sourcegraph.
The indexer is written in Rust because ty and Ruff expose the required parser,
project, and semantic APIs as Rust crates. ty-scip consumes those crates
directly at one pinned Ruff commit: it is a small adapter, not a Ruff fork and
not an LSP client.
Status
Version 0.1.0 is preview software. It indexes useful first-party structure and
supports the common scip-python command shape, but it is not a drop-in
replacement. The pinned ty/Ruff crates are unpublished internal crates without
an API-stability promise, and the ty-scip symbol scheme may still change.
The project is MIT licensed. Version 0.1.0 provides binary wheels for Linux x86-64 and ARM64 (glibc 2.17 or newer), macOS x86-64 and ARM64, and Windows x86-64. There is no source distribution or crates.io package. Binary packages include the project license and the generated third-party notices.
Install
Run without keeping an installation:
uvx ty-scip index . --output index.scip
Or install the ty-scip executable with one of:
uv tool install ty-scip
pipx install ty-scip
python -m pip install ty-scip
The wheel contains a native executable, not an importable Python API. The installer's Python environment is independent of the Python environment that ty selects for the indexed project.
Build from source
The crate declares Rust 1.96 and is currently exercised with Rust 1.98.1. Building needs Git access to fetch the pinned Ruff revision.
cargo build --release --locked
./target/release/ty-scip --help
To install the current checkout on your PATH:
cargo install --locked --path .
Use
ty-scip [index] [OPTIONS] [PROJECT_PATH] [OUTPUT.scip]
With no arguments, ty-scip indexes the current directory and writes
index.scip there. If only PROJECT_PATH is supplied, the output is still
written as index.scip in the caller's current directory.
# Current project -> ./index.scip
ty-scip
# scip-python-style command -> ./index.scip
ty-scip index . --output index.scip
# Another project discovery path -> explicit output
ty-scip ../project ./project.scip
# Override the package identity recorded in global symbols
ty-scip --project-name example --project-version 1.2.3 ../project
Options:
--output PATH: write the index toPATH; cannot be combined with the positional output path.--cwd PATH: resolve relative project and output paths fromPATH.--quiet: suppress successful-run diagnostics; errors still go to stderr.--project-name NAME: override the SCIP package name.--project-version VERSION: override the SCIP package version.-h,--help: print help.-V,--version: print the version.
Normal output is quiet on stdout. A summary of indexed definitions,
references, unresolved and ambiguous queries, external targets, safely skipped
links, and parser diagnostics is written to stderr. Set
TY_SCIP_SAMPLE_LIMIT=N to include up to N deterministic examples from each
unresolved and ambiguous category.
The positional project path is where ty starts configuration discovery; an
ancestor ty.toml or pyproject.toml may determine the actual project root.
Project discovery, source selection, import resolution, and Python-environment
behavior come from ty. Configure them with ty.toml or [tool.ty] in
pyproject.toml; Pyright configuration is not read. File symlinks are selected,
but ty does not traverse symlinked directories. Package name and version come
from the command-line overrides first, then static PEP 621 [project]
metadata, then an empty deterministic fallback.
See migrating from scip-python for the supported command mapping and deliberately unsupported options.
What it indexes
The current index includes:
- first-party
.pyand.pyifiles selected by ty; - modules, classes, callables, parameters, type parameters, properties, fields, variables, imports, and function-local bindings;
- unambiguous first-party name, attribute, import, re-export, and keyword references;
- analyzer-confirmed names inside quoted annotations, without scanning ordinary string contents;
- normalization of overloads and repeated definitions that denote one binding;
- generated dataclass/NamedTuple/TypedDict constructor fields and TypedDict string-key reads when ty resolves them to declared fields;
- stable lexical symbols for named nested functions and classes while anonymous and ordinary function-local bindings remain document-local;
- class-member identities for instance attributes that ty proves belong to a direct method whose inferred callable semantics preserve normal receiver behavior, including inherited reads and safe decorated methods;
- direct first-party class-base implementation relationships;
- SCIP definition, import, read, write, and augmented read/write roles, symbol kinds including semantically verified properties, display names, docstrings, source-faithful callable/class/annotated-assignment/type-alias signatures, and enclosing ranges; and
- both SCIP 0.10 typed ranges and equivalent legacy range fields.
Missing semantic evidence is an omission, not a guessed link. Proven runtime
standard-library targets use a python-stdlib package identity with ty's
configured Python major/minor version. Typing-only and installed third-party
targets remain counted omissions. Distinct multi-target results remain
ambiguous, document-local identities are not linked across files, and
transformed-method receiver attributes are skipped.
See compatibility and limitations for the detailed feature matrix and the ty APIs evaluated for future work.
Compatibility and evidence
The dual range encoding passes SCIP 0.10 lint on the focused fixtures and
supports the SCIP 0.8-based conversion path used by scip-cli 2.7.0.
Compatibility is tested at the query layer because protobuf validity alone
does not prove that converted mentions survive. Both tested linter versions
intermittently misreport valid cross-document relationship targets on the
larger OpenGHG index; every reported target has symbol information and a
definition occurrence, and the error set changes between runs of identical
bytes.
The version 0.1.0 release gate indexed all 281 documents in the frozen OpenGHG
checkout with 22,975 definitions and 53,264 references, and repeated candidate
runs produced byte-identical indexes. The converted index contained 542 chunks
and 20,586 mentions and passed the isolated scip-cli search, code, members,
references, dependencies, and reverse-dependencies gate. The locked comparison
to the patched scip-python reference retains six reviewed source ranges where
ty-scip omits a reference target. Index replacement uses an exclusively
created sibling temporary file followed by an atomic rename. Two
planning tasks produced accurate scopes and 24/24 valid cited locations, but
the benchmarked arm did not beat built-in search: it used about 34% more total
tokens, 6.5% more uncached input, and 2% more elapsed time. These results
support ty-scip as a fast structural-navigation backend, not an agent
efficiency claim.
Development
Run the smallest complete local gate before submitting a change:
cargo fmt --all --check
cargo clippy --locked --all-targets -- -D warnings
cargo test --locked
cargo build --release --locked
When Cargo.lock or the Ruff pin changes, install the pinned maintenance tool
and regenerate the reviewed third-party notice bundle:
cargo install cargo-about --locked --version 0.9.2 --features cli
python scripts/licenses.py
python scripts/licenses.py --check
To validate the actual binary-wheel contents and installed command:
python -m pip install maturin==1.15.0
maturin build --release --locked
python scripts/check_wheel.py target/wheels/*.whl
These Python scripts are packaging checks, not a Python wrapper or runtime
dependency of ty-scip.
Semantic changes need a decoded-SCIP regression that proves both the desired link and the relevant false-link case. Before changing the Ruff pin, follow the update checklist in compatibility and limitations. The remaining analyzer seams are recorded as narrow candidate upstream ty APIs.
License
Copyright 2026 Brendan Murphy. Released under the MIT License. Binary distributions also carry the generated third-party notices.
Release files for ty-scip 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| ty_scip-0.1.0-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| ty_scip-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details |
| ty_scip-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | Python 3 | none | Linux glibc 2.17+ ARM64 | Details |
| ty_scip-0.1.0-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details |
| ty_scip-0.1.0-py3-none-macosx_10_12_x86_64.whl | Python 3 | none | macOS 10.12+ x86-64 | Details |
Total release size: 51.2 MB
Release files / ty_scip-0.1.0-py3-none-win_amd64.whl
| Download URL | ty_scip-0.1.0-py3-none-win_amd64.whl |
|---|---|
| Size | 10.5 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
9e0c7b615aa7ac1926ed1b1a4518533b9f8ecdf8fad316e9252dc0f81dd2ee27
|
|
BLAKE2b-256 checksum How to use checksums |
2df5de558720b1568d697ef72b831f4ff627aa977bb25b70020ddf388892783f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.
Transparency logRelease files / ty_scip-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | ty_scip-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 10.5 MB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
516ee97b28bcbdc141c0bcdb5682cc715b1a5a56e6ba4d7f6e4130b66574af54
|
|
BLAKE2b-256 checksum How to use checksums |
19ea68e1c7467dd8a92dad29011e48b9f602c0fd48dc0715022944d90ac8baa2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.
Transparency logRelease files / ty_scip-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | ty_scip-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 10.0 MB |
| Tags | Linux glibc 2.17+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
4b30c256f9a69d707567e8042e9815c9bd0d64629c336ccde964a7bf67be240a
|
|
BLAKE2b-256 checksum How to use checksums |
8661ca3fd4665f0aaf059698754d1ebbfd7cd208e0e6358346d55a8e6ddd101b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.
Transparency logRelease files / ty_scip-0.1.0-py3-none-macosx_11_0_arm64.whl
| Download URL | ty_scip-0.1.0-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 9.9 MB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
7384e73a3a2475cd44e0ac2e1467bf5d104d74aba912615e1b16e9613cd50706
|
|
BLAKE2b-256 checksum How to use checksums |
65b302e1f3dc3eee4376770c210c9ec143cc1becde8719e7539a1b77e7302745
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.
Transparency logRelease files / ty_scip-0.1.0-py3-none-macosx_10_12_x86_64.whl
| Download URL | ty_scip-0.1.0-py3-none-macosx_10_12_x86_64.whl |
|---|---|
| Size | 10.3 MB |
| Tags | Python 3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
76c81e17c8a125e75066f5231821431c8f4ebc1c0a90c48d37977de7f4aa72e7
|
|
BLAKE2b-256 checksum How to use checksums |
c19d1cf174528a892c95acbf634fbfd7d3066e04d89df350359e6c84e6ad3298
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.
Transparency log