Metadata-Version: 2.4
Name: py-stack-graphs
Version: 0.1.0
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Compilers
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Programming Language :: Rust
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: License :: OSI Approved :: MIT License
Summary: Python bindings for stack graphs — name resolution for any programming language
Keywords: stack-graphs,name-resolution,tree-sitter,code-analysis,cross-reference
License: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Repository, https://github.com/austerecryptid/py-stack-graphs

# py-stack-graphs

Python bindings for [stack graphs](https://github.com/github/stack-graphs) — name resolution for any programming language.

Stack graphs resolve references to definitions across files without needing the full language toolchain. Built on tree-sitter grammars with scope rules that define how names flow through imports, scopes, and re-exports.

## Install

```bash
pip install py-stack-graphs
```

## Usage

```python
from py_stack_graphs import StackGraphIndex

idx = StackGraphIndex()
count = idx.index_project("/path/to/project", language="python")
print(f"Indexed {count} files")

# Resolve a specific reference
defs = idx.resolve("src/app.py", line=42, column=10)
for d in defs:
    print(f"  -> {d.symbol} at {d.file}:{d.line}")

# Get all references in a file with resolutions
refs = idx.all_references("src/app.py")
for ref in refs:
    if ref.resolved_to:
        print(f"  {ref.symbol} -> {ref.resolved_to.symbol}")
    else:
        print(f"  {ref.symbol} (unresolved)")
```

## Supported Languages

| Language | Feature flag | Grammar |
|---|---|---|
| Python | `python` (default) | tree-sitter-stack-graphs-python |
| TypeScript | `typescript` (default) | tree-sitter-stack-graphs-typescript |
| JavaScript | `javascript` (default) | tree-sitter-stack-graphs-javascript |

## How it works

```
Source code
    ↓
tree-sitter (parse to CST)
    ↓
stack graph rules (scope + name binding)
    ↓
stack graph (nodes = defs/refs, edges = scope flow)
    ↓
path stitching (resolve refs → defs)
    ↓
Python API (StackGraphIndex)
```

Stack graphs sit between tree-sitter (structural only) and full LSP (complete type inference):

- **Tree-sitter**: `foo.bar()` → "calls foo.bar" (unresolved string)
- **Stack graphs**: `foo.bar()` → "calls MyModule.MyClass.bar" (resolved via imports/scopes)
- **LSP**: `foo.bar()` → "calls MyModule.MyClass.bar, returns int" (fully typed)

## Building from source

Requires Rust toolchain:

```bash
pip install maturin
maturin develop
```

## License

MIT

