Skip to main content

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 *_t type as a resolved TypeAlias (e.g. Vector3D_t: TypeAlias = list[float], and string enums as CameraType_t: TypeAlias = Literal["SEQUENCE", "REF_FRAME"]),
  • emits the WidgetCallback*Enum constant classes and their int members,
  • adds @deprecated where the doc marks status: deprecated,
  • marks every function positional-only with a trailing /, since tde4 is all C builtins that reject keyword arguments (createCamera(mode="...") raises TypeError: takes no keyword arguments),
  • narrows optional args the doc gets wrong: x: T | None = Nonex: T = ..., since 3DE rejects an explicit None.

A few small by-name override tables handle the rest:

  • _RETURN_TYPE_OVERRIDES corrects returns the doc gets wrong at runtime: tuple[...]list[...] (3DE returns lists, not tuples), and lists whose elements can be None,
  • _RETURN_SHAPE_COMMENTS / _TYPE_ALIAS_COMMENTS add a trailing comment restating the per-position meaning a widened list[...] can't express,
  • _TYPE_ALIAS_OVERRIDES for types whose base can't be auto-derived (e.g. LSFResult_t),
  • _SUPPLEMENTAL_FUNCTIONS for the acos/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 = NoneT = ...: 3DE rejects an explicit None; the arg must be omitted, not passed as None.
  • tuple[...]list[...]: 3DE returns a list at 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 for tde4/vl_sdv, verified twice: mypy against the stubs (static) and assert_type (from stubgenlib.test_helpers) against the real module (runtime), so stubs and shipped modules must agree. tde4 only 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

types_3dequalizer-4.8.1.0-py2.py3-none-any.whl (19.5 kB view details)

Uploaded Python 2Python 3

File details

Details for the file types_3dequalizer-4.8.1.0-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for types_3dequalizer-4.8.1.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 eb505e0fb5f1b4992ef54d5abd5c5a63bcaac5c1c8b15bfcc24bdb2fad66d20c
MD5 4e962e3fedae8e015dfa2f1e66a1a4d7
BLAKE2b-256 59ebb77efb73813cec855023b6af0325b8fa6d4baf37c8c9ddb47e3a5a3576b3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page