Basilisk

Basilisk

The open-source Python language server.
Complete language server, type checker, debugger, and profiler — strict by default.
VS Code, Cursor & Windsurf (Open VSX) • Zed • Neovim. Built in Rust — single binary, no runtime.

Website  •  Install  •  Quick Start  •  Rules  •  Refactoring  •  Compare

--- ## Try it The `examples/` folder has ready-to-go Python files: ```sh cargo run -- check examples/bad.py # everything flagged cargo run -- check examples/good.py # clean cargo run -- check examples/mixed.py # some errors, some clean cargo run -- check examples/ # all three at once ``` --- ## Quick example
Basilisk rejects this Fixed
```python def greet(name): return "Hello " + name ``` ```python def greet(name: str) -> str: return "Hello " + name ```
``` error[BSK-E0001]: Missing parameter type annotation for `name` --> greet.py:1:10 | 1 | def greet(name): | ^^^^ | = help: Add a type annotation: `name: ` = see: https://www.basilisk-python.dev/errors/BSK-E0001 error[BSK-E0002]: Missing return type annotation --> greet.py:1:1 | 1 | def greet(name): | ^^^^^^^^^^^^^^^^ | = see: https://www.basilisk-python.dev/errors/BSK-E0002 ``` --- ## Rules All rules are on by default. There is no way to relax them globally. ### Annotation rules (E0001-E0005) | Code | Triggers when | |------|---------------| | `BSK-E0001` | Function parameter has no type annotation | | `BSK-E0002` | Function is missing a return type annotation | | `BSK-E0003` | Variable assignment has no type annotation | | `BSK-E0004` | `*args` or `**kwargs` has no type annotation | | `BSK-E0005` | Class attribute has no type annotation | ### Type correctness (E0010-E0029) | Code | Triggers when | |------|---------------| | `BSK-E0010` | Import cannot be resolved | | `BSK-E0011` | Explicit `Any` annotation, or a return type mismatch | | `BSK-E0012` | Argument type does not match parameter type | | `BSK-E0013` | Return type does not match declared return type | | `BSK-E0014` | Assignment type does not match declared variable type | | `BSK-E0015` | Wrong number of type arguments (e.g. `list[int, str]`) | | `BSK-E0016` | Method override has incompatible signature | | `BSK-E0017` | Class variable override has incompatible type | | `BSK-E0018` | Reference to an undefined name | | `BSK-E0019` | Variable used before it is assigned | | `BSK-E0020` | `@overload` group has no non-decorated implementation | | `BSK-E0021` | Two `@overload` signatures overlap | | `BSK-E0022` | Dict key type is not hashable | | `BSK-E0023` | `match` statement is not exhaustive | | `BSK-E0024` | Type expression is not valid (e.g. a numeric literal used as a type) | | `BSK-E0025` | Override method is missing the `@override` decorator | | `BSK-E0026` | `TypeVar` declared with a single constraint | | `BSK-E0027` | Duplicate `TypeVar` in a `Generic[...]` base | | `BSK-E0029` | Method defined inside a `TypedDict` class | These are the most common rules. Basilisk ships **151 diagnostic codes** in total (146 errors, 5 warnings) — see the [complete diagnostic reference](https://www.basilisk-python.dev/docs/rules/) (generated from the checker source by `scripts/gen_rules_reference.py`). --- ## Refactoring Basilisk ships a suite of refactoring code actions — available via the lightbulb (code actions) menu in VS Code, Cursor, and Windsurf (via Open VSX), plus Zed and Neovim. No extra extensions required. | Action | Kind | What it does | |--------|------|-------------| | **Extract variable** | `refactor.extract` | Extract expression into a named variable | | **Extract variable (replace all)** | `refactor.extract` | Replace all identical occurrences | | **Extract constant** | `refactor.extract` | Extract to module-level `SCREAMING_SNAKE` constant | | **Extract function** | `refactor.extract` | Extract selected statements into a new function | | **Inline variable** | `refactor.inline` | Replace variable with its value, delete assignment | | **Inline function** | `refactor.inline` | Replace call with function body (single-expression) | | **Move to new file** | `refactor.move` | Move class/function to a new file, leave import behind | | **Move to existing file** | `refactor.move` | Move class/function to a chosen file via command | | **Rename symbol** | — | Scope-aware rename with keyword arg, `self.attr`, docstring, and `__all__` updates | | **Remove parameter** | `refactor.rewrite` | Remove parameter from function + all call sites | | **Add parameter** | `refactor.rewrite` | Add `new_param=None` to function signature | | **Sort parameters** | `refactor.rewrite` | Alphabetically sort parameters (keeps `self`/`cls` first) | | **Implement abstract methods** | `refactor.rewrite` | Generate method stubs for abstract base class | | **Convert Union/Optional** | `refactor.rewrite` | `Union[X, Y]` ↔ `X \| Y`, `Optional[X]` ↔ `X \| None` | | **Convert constructs** | `refactor.rewrite` | f-string ↔ `.format()`, `dict()` ↔ `{}`, `list()` ↔ `[]`, ternary ↔ if/else, NamedTuple class ↔ functional | Extract function detects async functions, methods (`self`/`cls`), and rejects selections containing `yield`, `break`, or `continue`. --- ## Output format Diagnostics use rustc-style output: ``` error[BSK-E0001]: Missing parameter type annotation for `data` --> src/utils.py:14:5 | 14 | def process(data): | ^^^^ | = help: Add a type annotation: `data: ` = note: In Basilisk, all function parameters require explicit types = see: https://www.basilisk-python.dev/errors/BSK-E0001 ``` | Exit code | Meaning | |-----------|---------| | `0` | Clean — no errors | | `1` | Type errors found | | `3` | Internal error | --- ## Architecture Basilisk is a Cargo workspace. Each crate owns one layer of the analysis pipeline. > **Pipeline:** source text → parser → AST → resolver → scopes → checker → diagnostics > > **Incremental:** `basilisk-db` caches ASTs and resolved modules by content hash so only changed files re-run the pipeline. ### Analysis pipeline | Crate | What it does | Status | |-------|-------------|--------| | [basilisk-parser](crates/basilisk-parser/) | Wraps `ruff_python_parser` to parse `.py` source into a typed AST | Done | | [basilisk-resolver](crates/basilisk-resolver/) | Name resolution and scope analysis — catches undefined names and use-before-assignment | Done | | [basilisk-checker](crates/basilisk-checker/) | Core type checker — implements all E0001-E0025 rules | Done | | [basilisk-cli](crates/basilisk-cli/) | The `basilisk` binary — wires the full pipeline together | Done | ### LSP and infrastructure | Crate | What it does | Status | |-------|-------------|--------| | [basilisk-lsp](crates/basilisk-lsp/) | LSP server — diagnostics, hover, go-to-def, code actions, refactoring, debugging | Working | | [basilisk-db](crates/basilisk-db/) | Salsa-based incremental computation for <10ms latency | Working | | [basilisk-config](crates/basilisk-config/) | Configuration parsing (`pyproject.toml`, `basilisk.json`) | Done | | [basilisk-stubs](crates/basilisk-stubs/) | Bundled type stubs (typeshed) — no internet needed | Working | | [basilisk-uv](crates/basilisk-uv/) | uv package manager integration for the LSP | Working | | [basilisk-common](crates/basilisk-common/) | Shared constants and types — zero deps, WASM-compatible | Done | | [basilisk-test-utils](crates/basilisk-test-utils/) | Shared E2E test helpers | Done | ### Future capabilities | Crate | What it does | Status | |-------|-------------|--------| | [basilisk-mojo](crates/basilisk-mojo/) | Mojo-inspired ownership/immutability analysis (`Borrowed`, `InOut`, `Owned`) | Phase 4 | | [basilisk-compiler](crates/basilisk-compiler/) | Compiles typed Python to native code | Future | | [basilisk-plugin](crates/basilisk-plugin/) | WASM plugin host for Django, Pydantic, SQLAlchemy type extensions | Phase 5 | ### Editor extensions | Extension | Editor | Status | |-----------|--------|--------| | [vscode-extension](vscode-extension/) | VS Code | Working | | [basilisk.nvim](basilisk.nvim/) | Neovim 0.10+ | Working | | [basilisk-zed](basilisk-zed/) | Zed | Phase 2 | --- ## Development ```sh cargo build # build all crates cargo test # run all tests cargo clippy # lint (zero warnings policy) cargo fmt # format ``` Rust 1.87+ required. --- ## License MIT. Built by [NIMBLESITE PTY LTD](https://www.nimblesite.co).