22
33Opinionated Python bindings for the [ tree-sitter-stack-graphs] ( https://github.com/github/stack-graphs ) rust library.
44
5- It exposes very few, easy to use functions to index files and query references .
5+ It exposes a minimal, opinionated API to leverage the stack-graphs library for reference resolution in source code .
66
7- This is a proof of concept draft, to test scripting utilities using stack-graphs easily .
7+ The rust bindings are built using [ PyO3 ] ( https://pyo3.rs ) and [ maturin ] ( https://maturin.rs ) .
88
9- It uses pyo3 and maturin to generate the bindings .
9+ Note that this is a work in progress, and the API is subject to change. This project is not affiliated with GitHub .
1010
1111## Installation & Usage
1212
1313``` bash
14- pip install stack-graphs-python-bindings # or poetry, ...
14+ pip install stack-graphs-python-bindings
1515```
1616
17+ ### Example
18+
19+ Given the following directory structure:
20+
21+ ``` bash
22+ tests/js_sample
23+ ├── index.js
24+ └── module.js
25+ ```
26+
27+ ` index.js ` :
28+
29+ ``` javascript
30+ import { foo } from " ./module"
31+ const baz = foo
32+ ```
33+
34+ ` module.js ` :
35+
36+ ``` javascript
37+ export const foo = " bar"
38+ ```
39+
40+ The following Python script:
41+
1742``` python
1843import os
19- from stack_graphs_python import index , Querier, Position, Language
44+ from stack_graphs_python import Indexer , Querier, Position, Language
2045
2146db_path = os.path.abspath(" ./db.sqlite" )
2247dir = os.path.abspath(" ./tests/js_sample" )
2348
2449# Index the directory (creates stack-graphs database)
25- index([dir ], db_path, language = Language.JavaScript)
50+ indexer = Indexer(db_path, [Language.JavaScript])
51+ indexer.index_all([dir ])
2652
2753# Instantiate a querier
2854querier = Querier(db_path)
2955
30- # Query a reference at a given position (0-indexed line and column):
56+ # Query a reference at a given position (0-indexed line and column):
3157# foo in: const baz = foo
3258source_reference = Position(path = dir + " /index.js" , line = 2 , column = 12 )
3359results = querier.definitions(source_reference)
3460
3561for r in results:
36- print (f " { r.path } , l: { r.line } , c: { r.column } " )
62+ print (r )
3763```
3864
39- Will result in :
65+ Will output :
4066
4167``` bash
42- [...]/stack-graphs-python-bindings/ tests/js_sample/index.js, l: 0, c: 9
43- [...]/stack-graphs-python-bindings/ tests/js_sample/module.js, l: 0, c: 13
68+ Position(path= " [...]/tests/js_sample/index.js" , line= 0, column=9)
69+ Position(path= " [...]/tests/js_sample/module.js" , line= 0, column=13)
4470```
4571
4672That translates to:
4773
4874``` javascript
4975// index.js
5076import { foo } from " ./module"
77+ // ^ line 0, column 9
5178
5279// module.js
5380export const foo = " bar"
81+ // ^ line 0, column 13
5482```
5583
84+ > ** Note** : All the paths are absolute, and line and column numbers are 0-indexed (first line is 0, first column is 0).
85+
86+ ## Known stack-graphs / tree-sitter issues
87+
88+ - Python: module resolution / imports seems to be broken: < https://github.com/github/stack-graphs/issues/430 >
89+ - Typescript: module resolution doesn't work with file extensions (eg. ` import { foo } from "./module" ` is ok, but ` import { foo } from "./module.ts" ` is not). ** An issue should be opened on the stack-graphs repo** . See: ` tests/ts_ok_test.py `
90+ - Typescript: tree-sitter-typescript fails when passing a generic type to a decorator: < https://github.com/tree-sitter/tree-sitter-typescript/issues/283 >
91+
5692## Development
5793
5894### Ressources
@@ -67,7 +103,7 @@ https://pyo3.rs/v0.21.2/getting-started
67103### Setup
68104
69105``` bash
70- # Setup venv and install maturin through pip
106+ # Setup venv and install dev dependencies
71107make setup
72108```
73109
@@ -76,3 +112,37 @@ make setup
76112``` bash
77113make test
78114```
115+
116+ ### Manual testing
117+
118+ ``` bash
119+ # build the package
120+ make develop
121+ # activate the venv
122+ . venv/bin/activate
123+ ```
124+
125+ ### Roadmap
126+
127+ Before releasing 0.1.0, which I expect to be a first stable API, the following needs to be done:
128+
129+ - [ ] Add more testing, especially:
130+ - [ ] Test all supported languages (Java, ~~ Python~~ , ~~ TypeScript~~ , ~~ JavaScript~~ )
131+ - [ ] Test failing cases, eg. files that cannot be indexed
132+ - [ ] Add options to the classes:
133+ - [ ] Verbosity
134+ - [ ] Force for the Indexer
135+ - [ ] Fail on error for the Indexer, or continue indexing
136+ - [ ] Handle the storage (database) in a dedicated class, and pass it to the Indexer and Querier
137+ - [ ] Add methods to query the indexing status (eg. which files have been indexed, which failed, etc.)
138+ - [ ] Rely on the main branch of stack-graphs, and update the bindings accordingly
139+ - [ ] Better error handling, return clear errors, test them and add them to the ` .pyi ` interface
140+ - [ ] Lint and format the rust code
141+ - [ ] CI/CD for the rust code
142+ - [ ] Lint and format the python code
143+ - [ ] Propper changelog, starting in 0.1.0
144+
145+ I'd also like to add the following features, after 0.1.0:
146+
147+ - [ ] Expose the exact, lower-level API of stack-graphs, for more flexibility, in a separate module (eg. ` stack_graphs_python.core ` )
148+ - [ ] Benchmark performance
0 commit comments