Python Bindings (Shiboken / PySide)

Natron embeds a Python 3 interpreter and exposes much of its API to Python. This powers parameter expressions, user scripts and callbacks, PyPlugs, and custom GUI panels — everything documented in the Developers Guide. This chapter covers the machinery that produces those bindings, which maintainers must regenerate when the C++ API changes.

The pieces

  • The ``Py*`` C++ classes (Engine/PyNode.*, PyParameter.*, PyRoto.*, PyTracker.*, PyAppInstance.*, PyNodeGroup.*, PyExprUtils.*, PyGlobalFunctions.*; Gui/PyGuiApp.*, PythonPanels.*). These are deliberately small, stable, scripting-friendly facades over the engine/GUI objects. They live in the NATRON_PYTHON_NAMESPACE (see Design Techniques and Idioms). The Python API surface is defined by these classes — not by the whole engine.

  • Shiboken — the binding generator (part of PySide). It reads the C++ headers plus a typesystem XML file and emits C++ “wrapper” sources that expose the classes to Python.

  • The typesystem filesEngine/typesystem_engine.xml and Gui/typesystem_natronGui.xml (plus Shiboken/typesystem_widgets.xml). They tell Shiboken which classes/functions to expose, how to map types, what to rename, and what to skip. When you add or change a Py* class, you edit the matching typesystem file.

  • The generated wrappersnatronengine_* and natrongui_* wrapper sources produced into the build directory (referenced from Engine.pro / Gui.pro and the CMake files). They are build artifacts, not hand-edited.

  • The PySide module gluePyside_*_Python.h and the version-specific PySide2_*_Python.h / PySide6_*_Python.h headers select the right PySide headers for the Qt version in use.

Qt 5 vs Qt 6: two toolchains

The binding toolchain is tied to the Qt version:

  • Qt 5 builds use Shiboken2 / PySide2.

  • Qt 6 builds use Shiboken6 / PySide6.

The CMake build already selects between them from the NATRON_QT6 option (see Building Natron from Source), and the presence of both PySide2_* and PySide6_* headers shows the port is under way. The bindings must be regenerated with the matching Shiboken when switching Qt major versions; a mismatch is a common source of the “Qt.Alignment flags unrecognized” class of errors (issue #854). See Qt 6 Migration Plan.

Working on the bindings

  • To expose a new method or class to Python: add/adjust the Py* facade in C++, then declare it in the relevant typesystem_*.xml, then rebuild so Shiboken regenerates the wrappers.

  • Keep the Py* API stable and minimal. User scripts, PyPlugs and the official tutorials depend on it; breaking it breaks users’ projects just as surely as breaking the serialization format.

  • The reference documentation for the Python API under devel/PythonReference is generated from these bindings; regenerate it when the API changes (see the documentation build notes in Contributing and Workflow).

  • To add a third-party Python dependency for scripts, callbacks or PyPlugs, install it into Natron’s bundled interpreter with natron-python -m pip install <package> rather than the system Python — this keeps the package on the same Python that Natron actually runs.