Unofficial python stubs for Science.D.Visions 3DEqualizer4 (tde4, vl_sdv)
Project description
Unofficial python stubs for Science.D.Visions 3DEqualizer4
Type stubs for the following 3DEqualizer's scriptable modules:
tde4: the main scripting API.vl_sdv: the bundled vector / matrix / transform math library.
Installing
pip install types-3dequalizer
The package version tracks the 3DEqualizer version it was generated from, plus a suffix for the stub revision.
Generating
tde4 is a built-in C module baked into the 3DE interpreter (no file on disk),
so it only exists inside a running 3DE process and can't be imported or
introspected standalone. Instead we parse the vendor's Python Doc (LLM), a
JSON API doc that carries full annotations, a semantic type system, defaults and
deprecation status, so no GUI is needed.
| Module | Source | How it's generated |
|---|---|---|
tde4 |
the Python Doc (LLM) JSON ($TDE4_LLM_DOC) |
parsed by stubgen_3dequalizer.py |
vl_sdv |
$TDE4_ROOT/sys_data/py_vl_sdv/vl_sdv.py (pure python) |
custom mypy inspection of the real module |
Download the "Python Doc (LLM)" (the (LLM) JSON, not the
(Human) HTML) from
3dequalizer.com → Tech Docs
→ Python Scripting Interface, for the 3DE version you're generating.
Set the paths in .env, then generate from the repo root:
TDE4_LLM_DOC=/path/to/tde4_with_examples.wtrl.core.rfc-2119.json
TDE4_ROOT=/path/to/3DE4_win64_r<version>
nox -s 'generate(3dequalizer)'
This calls the generator, renames the output to the PEP 561 *-stubs
layout, and runs mypy + mypy-silent over it.
How the stubs are built
The doc provides real Python annotations per parameter and return, emitted mostly verbatim. On top of that the generator:
- emits each referenced
*_ttype as a resolvedTypeAlias(e.g.Vector3D_t: TypeAlias = list[float], and string enums asCameraType_t: TypeAlias = Literal["SEQUENCE", "REF_FRAME"]), - emits the
WidgetCallback*Enumconstant classes and theirintmembers, - adds
@deprecatedwhere the doc marksstatus: deprecated, - marks every function positional-only with a trailing
/, sincetde4is all C builtins that reject keyword arguments (createCamera(mode="...")raisesTypeError: takes no keyword arguments), - narrows optional args the doc gets wrong:
x: T | None = None→x: T = ..., since 3DE rejects an explicitNone.
A few small by-name override tables handle the rest:
_RETURN_TYPE_OVERRIDEScorrects returns the doc gets wrong at runtime:tuple[...]→list[...](3DE returns lists, not tuples), and lists whose elements can beNone,_RETURN_SHAPE_COMMENTS/_TYPE_ALIAS_COMMENTSadd a trailing comment restating the per-position meaning a widenedlist[...]can't express,_TYPE_ALIAS_OVERRIDESfor types whose base can't be auto-derived (e.g.LSFResult_t),_SUPPLEMENTAL_FUNCTIONSfor theacos/sin/... math wrappers that are live but absent from the doc.
From doc entry to stub line
Take convertObjectPGroupTransformation3DEToWorld; it hits both runtime
corrections at once. It flows top to bottom, one box per step:
┌─ 1 · INPUT - one entry in the LLM doc (__WTRL_OBJECTS__) ────────────────┐
│ "signature": { │
│ "parameters": [ │
│ {"name": "camera_id", "annotation": "CameraID_t"}, │
│ {"name": "pgroup_scale", "annotation": "float | None", │
│ "default": "None"}, # ← optional │
│ ... ], │
│ "returns": "tuple[Matrix3D_t, Vector3D_t]" # ← a tuple │
│ } │
└──────────────────────────────────────────────────────────────────────────┘
│
▼ _Spec.callables() → _build_signature(name, obj)
┌─ 2 · _render_parameter() - one per parameter ────────────────────────────┐
│ camera_id "CameraID_t" → camera_id: CameraID_t │
│ pgroup_scale "float | None" + default → pgroup_scale: float = ... │
│ (drop " | None", add " = ...")│
└──────────────────────────────────────────────────────────────────────────┘
│
▼
┌─ 3 · _RETURN_TYPE_OVERRIDES[name] - the return type ─────────────────────┐
│ tuple[Matrix3D_t, Vector3D_t] → list[Matrix3D_t | Vector3D_t] │
└──────────────────────────────────────────────────────────────────────────┘
│
▼
┌─ 4 · OUTPUT - a line in tde4-stubs/__init__.pyi ─────────────────────────┐
│ def convertObjectPGroupTransformation3DEToWorld( │
│ camera_id: CameraID_t, ..., pgroup_scale: float = ..., /, │
│ ) -> list[Matrix3D_t | Vector3D_t]: ... # [transform matrix, position] │
└──────────────────────────────────────────────────────────────────────────┘
Why the two corrections (steps 2 and 3):
- Optional arg
T | None = None→T = ...: 3DE rejects an explicitNone; the arg must be omitted, not passed asNone. tuple[...]→list[...]: 3DE returns alistat runtime, not a tuple.
The *_t names (CameraID_t, Matrix3D_t, Vector3D_t) aren't resolved here:
_resolve_all_type_aliases walks each type's doc_lines (transitively, so
Matrix3D_t pulls in Vector3D_t) and emits the aliases near the top. Finally
_render_module assembles everything and _render_header adds only the imports
the body actually uses.
Testing
Tests are split by where they run:
tests/: generator unit tests; pure python, run standalone.tests_live/: API-usage tests fortde4/vl_sdv, verified twice: mypy against the stubs (static) andassert_type(fromstubgenlib.test_helpers) against the real module (runtime), so stubs and shipped modules must agree.tde4only exists inside 3DE, so these run there.
From the repo root:
nox -s 'mypy(3dequalizer)' # static: type-check every suite against the stubs
nox -s 'test(3dequalizer)' # the generator unit tests (tests/)
The live suite runs inside 3DE, whose python lacks our dev deps, so from the project dir put its virtualenv on PYTHONPATH first:
export PYTHONPATH="$(echo .venv/*/site-packages)" # Windows: set PYTHONPATH=.venv\Lib\site-packages
<3de-executable> -no_gui -run_script tests_live/run_tests.py
<3de-executable> is the 3DEqualizer binary (use its full path, or your studio's
launch wrapper); -no_gui -run_script are 3DEqualizer's own flags.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file types_3dequalizer-4.8.1.0-py2.py3-none-any.whl.
File metadata
- Download URL: types_3dequalizer-4.8.1.0-py2.py3-none-any.whl
- Upload date:
- Size: 19.5 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.17
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb505e0fb5f1b4992ef54d5abd5c5a63bcaac5c1c8b15bfcc24bdb2fad66d20c
|
|
| MD5 |
4e962e3fedae8e015dfa2f1e66a1a4d7
|
|
| BLAKE2b-256 |
59ebb77efb73813cec855023b6af0325b8fa6d4baf37c8c9ddb47e3a5a3576b3
|