Skip to content

All emitted SymbolInformation entries have kind=UnspecifiedKind (0) — breaks downstream kind-filtered tooling #212

Description

@LilPoppy

Summary

scip-python 0.6.6 emits SymbolInformation.kind == UnspecifiedKind (0) for every symbol in the index — both in-project and external. Downstream tooling that filters resolved targets by symbol kind (e.g., kind in {Function, Method, ...} for callable resolution) becomes dead-letter on real-world output, because every kind is 0.

Observed (real Python 3.12 codebase, ~6101 LOC, 102 files)

Across the indexed corpus producing 2156 in-project SymbolInformation entries + 85 external_symbols, every info.kind == 0. Sample:

scip-python python cobnet-framework 0.0.1 `pkg.app.context`/DefaultApplicationContext#
  kind: UnspecifiedKind (0)

(Expected: Class)

Reproduction

docker run --rm -v "$PWD:/work" -w /work node:20-slim bash -c \
  "apt-get update -qq && apt-get install -y -qq python3 python3-pip > /dev/null && \
   npm install -g @sourcegraph/scip-python > /dev/null && \
   scip-python index --cwd /work --output /work/index.scip"

Inspect the resulting index.scip (using any SCIP reader / the vendored scip_pb2.py):

from scip_python import scip_pb2  # or any equivalent SCIP reader
idx = scip_pb2.Index()
idx.ParseFromString(open('index.scip', 'rb').read())
kinds = {s.kind for doc in idx.documents for s in doc.symbols}
print('Distinct kinds emitted:', kinds)  # → {0}

Impact

A downstream code semantic analysis project found that this gap made its calls.symbol and instantiates edge-resolution paths emit zero edges on real input, despite passing 125 unit tests that used synthesized SCIP fixtures with kinds explicitly set. The workaround was a lenient-on-unknown-kind code path (accept kind=0 as a callable candidate, tag the result confidence as scip-resolved-kind-unknown), but a proper fix in scip-python would let consumers distinguish callable-targets from non-callable-targets with type confidence.

The most common downstream consumer pattern this breaks:

CALLABLE_KINDS = frozenset({
    scip_pb2.SymbolInformation.Kind.Function,
    scip_pb2.SymbolInformation.Kind.Method,
    scip_pb2.SymbolInformation.Kind.Constructor,
    # ...
})

if info.kind not in CALLABLE_KINDS:
    # rejected — but every real-world `info.kind` is 0, so EVERYTHING is rejected
    return None

Versions

  • scip-python: 0.6.6 (latest on npm as of 2026-05-17; confirmed via npm view @sourcegraph/scip-python versions --json)
  • node: 20.x (node:20-slim)
  • pyright: bundled (transitive of scip-python)

Asks

  1. Confirm whether kind emission is on the roadmap / known regression / intentional behavior
  2. If a fix is planned, please document the version cutover so downstream tooling can detect-and-promote (e.g., upgrade confidence="scip-resolved-kind-unknown""scip-resolved" once the indexer version is ≥ X.Y.Z)

Happy to provide a larger SCIP dump or test fixture if helpful.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions