Skip to content

v0.3.0 — Python support via a pyright-backed COMPILER tier

Choose a tag to compare

@anishmoncivarghese anishmoncivarghese released this 30 Aug 12:51
· 25 commits to main since this release

Sonde now indexes Python, alongside TypeScript and Swift.

npm install -g @cheppulabs/sonde
cd your-python-project
sonde init --resolve

Read this before pointing it at Python

Two limitations, stated up front because they are cheap to disclose now and
expensive to discover later.

Python needs --resolve. Without it, Python indexes at the tree-sitter tier
only, which measured 62.81% unresolved reference sites on a real 56-file
project and 57.39% on pydantic — far past the 30% ceiling this project requires
before it will call a language supported. That tier is not fit for structural
queries, and Sonde shipped Python only once a compiler-backed tier cleared the
bar. sonde init --resolve is the supported path.

The gate measured placement, not correctness. It asked whether a reference
found a target, not whether the target was the right one. TypeScript's edges
are scored against tsc in ORACLE.md;
Python has no equivalent oracle, because the only available authority is the
same pyright that produced the edges — scoring them against it would measure
nothing. So Python edges are unverified for target correctness. If you find
a wrong one, that is a known gap rather than a surprise, and worth an issue.

The margin is thin on the worse corpus. 27.00% unresolved against a 30%
ceiling, and 29.72% once a known upward bias is fully reversed — roughly three
references from failing. Full arithmetic in
probes/python-placement/FINDINGS.md.

What the numbers actually are

Unresolved reference sites, measured against thresholds committed before the
measurement ran, on two real corpora:

Corpus Tree-sitter only With --resolve
A 56-file application 62.81% 27.00%
pydantic (441 files) 57.39% 17.42%

The first row is why the tree-sitter-only tier was built, measured, and then
refused registration. The gate exists to be able to say no, and it did.

How it works

A bundled pyright drives a COMPILER tier over LSP. No Python interpreter is
required — pyright is a TypeScript program and bundles typeshed — and Sonde
never loads a type checker from your repository, in any language.

Requests are issued serially, because throughput was measured flat across client
concurrency 1, 8, and 32: the server answers on one thread, so a scheduler would
have added complexity and returned nothing. That measurement is why this feature
is small (probes/pyright-feasibility/FINDINGS.md).

Also fixed

  • Python stable keys are now guaranteed unique. Indexing pydantic failed
    outright with UNIQUE constraint failed: symbol.stable_key. The 88 collisions
    came from four distinct causes, each needing different treatment and none
    permitted to use a line number: module-level rebinding is one variable,
    @overload families are one runtime function, property accessors earn
    role-suffixed keys (area, area@setter), and genuine redefinitions take an
    ordinal that survives line moves.
  • The Swift SDK EXTERNAL fallback is scoped to Swift. It fired on any
    reference carrying a scope hint, so Python names colliding with the Swift
    table (append, Task, String, Int, filter) would have been attributed
    to Swift frameworks — and since EXTERNAL is excluded from the placement
    denominator, that would have biased Python's own gate toward passing.

Install size

pyright is now a pinned hard dependency (~19 MB), matching how the TypeScript
compiler is already bundled. TypeScript-only users carry it without using it;
that trade was made deliberately so --resolve works with no extra setup step.


Full detail in CHANGELOG.md.