Technical Briefing – fake‑bpy-module
The Problem
Developers writing Blender add‑ons need reliable code‑completion for the Blender Python API, but the real API is large, version‑specific, and only available at runtime inside Blender. This repository ships fake API modules that IDEs can index offline, giving accurate import‑completion and type‑hinting without launching Blender.
What This Does
The repo contains ~540 files organized into src/, tests/, tools/, and documentation. Core responsibilities live in:
src/fake_bpy_module/analyzer/– parses Blender’s.pysource and generates fake modules (directives.py,nodes.py,analyzer.py).src/fake_bpy_module/generator/– writes the completed module files (code_writer.py,translator.py,writers.py).src/gen.py– the top‑level driver that orchestrates analysis → generation.src/fake_bpy_module/transformer/transformer_base.py– a hub used by 20 other modules; changes here ripple widely.
Measured import‑graph: 69 internal modules, 61 import edges, no cycles. The most connected module is src/fake_bpy_module/transformer/transformer (Ca = 1, Ce = 20, instability = 0.95).
How It Is Wired
- Entry points –
maininsrc/gen.py:197reaches 179 functions and is called once (typically from a CI job or manual script).runinsrc/fake_bpy_module/analyzer/directives.py:275reaches 42 functions and is invoked from 67 call sites. - Traced paths –
main → analyze [filesystem via Path(config.bgl_c_file).open];setUp [filesystem via Path(self.output_dir).mkdir]. - Call density –
analyzeis called from 67 places,BaseAnalyzerfrom 63,compare_with_file_contentsfrom 61,astextfrom 61. The transformer filesrc/fake_bpy_module/transformer/transformer_base.pyhas 20 dependents, making it a high‑blast‑radius hub. - File‑level responsibilities – e.g.,
src/fake_bpy_module/analyzer/nodes.pydefinesappend_child,element,deepcopyand is called from 22 other files;src/fake_bpy_module/generator/writers.py(22 functions, 5 classes) is called from 3 files and writes output files.
How To Use It
| Step | Command / File | Evidence |
|---|---|---|
| Install released package | pip install fake-bpy-module (or pip install fake-bpy-module-<ver> for a specific Blender version) | pyproject.toml, setup.py |
| Generate modules from source | python src/gen.py (runs the main entry point) | src/gen.py |
| Run the test suite | python -m pytest tests/ (342 test files) | tests/ directory |
| Build inside Docker | docker build -f tools/docker/Dockerfile_blender . or tools/docker/Dockerfile_upbge | tools/docker/ |
| Configure IDE | Add the generated module path to IDE’s Python completion; for PyCharm set idea.max.intellisense.filesize > 2600 (README) | README.md |
No environment variables or secrets are required for basic use.
Real‑World Use
A Blender add‑on developer can import import bpy in their IDE; the fake module provides stubs for every Blender type/operator, so autocomplete suggests bpy.ops.object.delete(), bpy.types.Mesh, etc., even when offline. The generated stubs stay in sync with the Blender version selected via the fake-bpy-module-<ver> packages or by running gen.py after a new Blender release.
Code Health & Issues
Static analysis (36 findings: 18 high, 18 medium) and a separate CODE HEALTH AUDIT (10 findings: 3 high, 6 medium, 1 low).
- [HIGH] Pin third‑party GitHub Actions to a commit SHA –
.github/workflowsdeclare@v1.3.1forpypa/gh-action-pypi-publish; a tag can move, exposing secrets. Fix: replace with 40‑char SHA. - [HIGH] Commit a lockfile beside the manifest –
pyproject.tomlhas no lockfile; transitive dependencies may differ between installs. Fix: runpip lockand commit the generated file. - [HIGH] Make CI invoke the test suite it has – 4 workflows contain no test command; a green check that never runs assertions is misleading. Fix: add
pytest(or equivalent) step to existing workflows. - [MEDIUM] Declare least‑privilege permissions for GITHUB_TOKEN – 4 workflows declare no
permissionswhile referencing secrets. Fix: addpermissions: contents: readat the top and widen per‑job as needed. - [MEDIUM] Enable Dependabot or Renovate – 2 manifests, no update bot configured. Fix: add
.github/dependabot.ymlcoveringpipandgithub-actions. - [MEDIUM] Pin the container base image by digest –
tools/gen_module/Dockerfileusespython:3.10-bullseye. Fix:python:3.10-bullseye@sha256::<digest>and enable Dependabot Docker monitoring. - [MEDIUM] Gate pull requests on a dependency vulnerability scan – no dependency‑scan action in CI. Fix: add
dependency-review-actiononpull_requestorosv-scanneron push/schedule. - [MEDIUM] Set
persist-credentials: falseon checkout – checkout retains the token; later steps could read pushable credentials. Fix: addwith: persist-credentials: falseand pass an explicit token only to the push step. - [LOW] Set
timeout-minuteson workflow jobs – 4 jobs have no timeout, risking overlap on a two‑hourly schedule. Fix: add a realistictimeout-minutesto each job.
These findings stem from deterministic static analysis; they are not opinions.
The Bottom Line
The repository delivers a practical solution for offline Blender‑API code completion, with a clear entry point (src/gen.py) and a modular architecture that, while functional, suffers from deep nesting, duplicated blocks, and a high‑impact hub (transformer_base.py). The CI setup is incomplete (missing test invocation, unpinned Actions, no lockfile), and the Docker base image is mutable. Teams that need stable, reproducible completions should pin dependencies, commit a lockfile, and add the recommended CI safeguards; otherwise the risk of divergent builds or hidden vulnerabilities is non‑trivial.
Word count: ~430.