2026-04-03 11:46:22 +02:00

146 lines
8.9 KiB
Markdown

# blender-python-stubs
![Python](https://img.shields.io/badge/Python-3776AB?style=for-the-badge&logo=python&logoColor=white)
![Blender](https://img.shields.io/badge/Blender-E87D0D?style=for-the-badge&logo=blender&logoColor=white)
![License: MIT](https://img.shields.io/badge/License-MIT-green.svg?style=for-the-badge)
[![PyPI](https://img.shields.io/pypi/v/blender-python-stubs?style=for-the-badge&logo=pypi&logoColor=white)](https://pypi.org/project/blender-python-stubs/)
Strict type stubs for the Blender Python API. Provides autocomplete, type checking, and inline documentation for `bpy`, `mathutils`, `bmesh`, `gpu`, `freestyle`, and all other Blender Python modules. Generated stubs pass [basedpyright](https://docs.basedpyright.com) `all` mode with 0 errors and use zero `typing.Any`.
## Installation
```bash
pip install blender-python-stubs
```
The version matches your target Blender version:
| Blender Version | Install Command | PyPI |
| --------------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| 5.1 | `pip install "blender-python-stubs>=5.1,<5.2"` | [![PyPI](https://img.shields.io/badge/PyPI-5.1-blue?logo=pypi)](https://pypi.org/project/blender-python-stubs/5.1.0.1/) |
| 5.0 | `pip install "blender-python-stubs>=5.0,<5.1"` | [![PyPI](https://img.shields.io/badge/PyPI-5.0-blue?logo=pypi)](https://pypi.org/project/blender-python-stubs/5.0.1.0/) |
| 4.5 | `pip install "blender-python-stubs>=4.5,<4.6"` | [![PyPI](https://img.shields.io/badge/PyPI-4.5-blue?logo=pypi)](https://pypi.org/project/blender-python-stubs/4.5.8.1/) |
| 4.4 | `pip install "blender-python-stubs>=4.4,<4.5"` | |
| 4.3 | `pip install "blender-python-stubs>=4.3,<4.4"` | |
| 4.2 | `pip install "blender-python-stubs>=4.2,<4.3"` | |
| 4.1 | `pip install "blender-python-stubs>=4.1,<4.2"` | |
| 4.0 | `pip install "blender-python-stubs>=4.0,<4.1"` | |
## Usage
Install alongside your Blender addon project for type checking with mypy, pyright, basedpyright, ty or your IDE.
```python
import bpy
# Full autocomplete and type checking
obj = bpy.context.active_object
assert obj is not None
obj.location.x = 1.0
# Collection types with proper methods
bpy.data.objects.new("Cube", bpy.data.meshes.new("Mesh"))
bpy.data.images.remove(bpy.data.images["old"])
# GPU module fully typed
import gpu
shader = gpu.shader.from_builtin('UNIFORM_COLOR')
gpu.state.blend_set('ALPHA')
```
## Features
- **Full Blender API coverage** — `bpy.types`, `bpy.ops`, `bpy.props`, `bpy.utils`, `bpy.path`, `bpy.app`, `mathutils`, `bmesh`, `gpu`, `gpu_extras`, `bpy_extras`, `freestyle`, `aud`, `blf`, `bl_math`, `imbuf`, `idprop`
- **Accurate collection types** — `bpy.data.objects` returns `BlendDataObjects` (not generic `bpy_prop_collection`), exposing `new()`, `remove()`, and other collection-specific methods
- **Readonly properties** — uses `@property` decorators for readonly RNA attributes
- **Context members** — `bpy.context.active_object`, `selected_objects`, `edit_object`, and ~100 other screen context attributes are properly typed
- **Constructor signatures** — GPU types, mathutils types (`Vector`, `Matrix`, `Euler`, etc.) have typed `__init__` methods
- **Literal enum types** — string parameters like `gpu.state.blend_set(mode)` use `Literal["NONE", "ALPHA", ...]` instead of plain `str`
- **Docstrings** — inline documentation on properties, methods, and functions
- **Classmethod detection** — `Matrix.Identity()`, `Vector.Fill()`, etc. correctly typed as `@classmethod`
- **Dunder methods** — `__getitem__`, `__len__`, `__add__`, `__matmul__`, and other operators introspected with correct return types (e.g. `Matrix[0]` returns `Vector`)
- **Operator metadata** — `bpy.ops.mesh.primitive_cube_add.poll()`, `.idname()`, `.get_rna_type()`, and `.bl_options` are typed via introspected `_BPyOpsSubModOp` wrapper
- **GPU uniform types** — `shader.uniform_float()` accepts `Matrix`, `Vector`, `Euler`, `Quaternion`, and `Color` in addition to `float | Sequence[float]`, matching the C implementation
- **Typed `Context.copy()`** — returns a `ContextDict` TypedDict instead of `dict[str, object]`, so unpacking into `context.temp_override(**ctx)` type-checks correctly
- **Dynamic array types** — `Image.pixels` typed as `bpy_prop_array[float]` (not `list[float]` or `float`)
- **Zero `Any` usage** — precise types throughout, no `typing.Any` fallbacks
- **[basedpyright](https://docs.basedpyright.com) `all` mode** — 0 errors on generated stubs (4.0+), validated with `typeCheckingMode: "all"` (the strictest setting)
## How It Works
Stubs are generated by running introspection **inside Blender itself**. A script runs in Blender's embedded Python interpreter using `--background` mode and collects:
1. **RNA type definitions** via `rna_info.BuildRNAInfo()` — all `bpy.types` classes, their properties, methods, inheritance, and readonly status
2. **C extension signatures** via `inspect.signature()` and RST docstring parsing — for `mathutils`, `bmesh.types`, `gpu.types`, `aud`, etc.
3. **Screen context members** via `dir(bpy.context)` — dynamically injected context attributes with type inference from runtime values, hardcoded overrides, and name-pattern heuristics
4. **Collection wrapper classes** via RNA `srna` attributes — maps `bpy.data.objects` to `BlendDataObjects(bpy_prop_collection[Object])` instead of generic `bpy_prop_collection[Object]`
The introspection data is then passed through a stub generator that handles type cleaning, import resolution, docstring formatting, and `black` formatting.
## Comparison with Alternatives
### vs [fake-bpy-module](https://github.com/nutti/fake-bpy-module)
| Feature | blender-python-stubs | fake-bpy-module |
| ------------------------ | -------------------------- | ----------------------------- |
| `@property` for readonly | Yes (1700+) | No |
| `Any` usage | 0 | 1800+ |
| Collection wrapper types | `BlendDataObjects` | `bpy_prop_collection[Object]` |
| `bpy_struct` methods | Introspected | Missing |
| `rna_type` attribute | Yes | Missing |
| Operator metadata | `poll()`, `idname()`, etc. | Missing |
| Constructor `__init__` | Yes (mathutils, gpu, etc.) | No |
| Literal enum types | Yes | Yes (via stub_internal) |
| Context members | ~100 typed | ~100 typed |
| basedpyright `all` mode | 0 errors (4.0+) | Not tested |
| Docstrings | Yes | Yes |
### vs [bpystubgen](https://github.com/mysticfall/bpystubgen)
bpystubgen generates stubs from Blender's Sphinx documentation, not from runtime introspection. This means it can miss C-level methods, dynamic context members, and runtime-only type information. Our approach introspects the actual running Blender instance, ensuring stubs match the real API.
## Supported Versions
Blender 4.0 through 5.1. Each Blender version gets its own stub package version.
## Generating Stubs
To generate stubs for a specific Blender version, run:
```bash
uv run poe generate 5.1
```
This will automatically download the corresponding Blender executable and run the introspection and stub generation process. You can also type-check the generated stubs:
```bash
uv run poe typecheck-stubs 5.1
```
## Contributing
Pull requests are welcome. The project uses:
- `uv` for dependency management
- `poe` for task running
- `basedpyright` for type checking
- `black` for formatting
- `ruff` for linting
```bash
# Run all checks (format, lint, typecheck, tests)
uv run poe check
```
## Disclaimer
This project was coded with assistance of AI.
## License
[MIT](LICENSE)
---
Made with ❤️ at [Autour de Minuit (ADV)](https://blog.autourdeminuit.com/) <img src="https://upload.wikimedia.org/wikipedia/commons/0/0c/Blender_logo_no_text.svg" alt="blender" width="20"/>