Python Environment¶
Explains the features and limitations of the ZBrush Python environment.
The ZBrush 2026.1.0 Python Runtime Environment is based on CPython 3.11.9 and offers largely the same experience as a standard CPython installation. It however differs in its usage and features from a common Python installation in a few important aspects, which are explained in the following sections.
Virtual Machine¶
The main difference between the ZBrush Python Virtual Machine (VM) and a standard CPython VM is that the ZBrush Python VM is embedded into the ZBrush application itself. This means that when you run a Python script or plugin in ZBrush, it is executed within the context of the ZBrush application, rather than in a separate Python interpreter process. Find below a summary of the most important differences which follow from this fact:
Note
See also Best Practices for the practical implications of these differences when writing scripts and plugins for ZBrush.
Difference |
Description |
|---|---|
Interpreter Persistence |
The ZBrush Python VM is a persistent Python instance that runs as long as ZBrush is running, and is shared between all scripts and plugins the user might run. This means that any state you change in the Python environment (e.g., global variables, imported modules, installed packages) will persist between script executions and might affect other scripts. |
Working Directory |
The working directory of the ZBrush Python VM is always the ZBrush application directory (i.e., where |
Module Search Paths |
Other than for a standard CPython instance, the directory of an executed script or plugin is not automatically added to the module search paths (i.e., |
VM Executable |
The ZBrush Python VM is the ZBrush executable itself (i.e., |
Stream Handler |
The ZBrush Python VM uses a custom stream handler to redirect standard output and error streams to the ZBrush console. This means that you cannot easily overwrite the stream handlers as this will break the output redirection from and to the ZBrush console. |
The following support limitations apply when using the ZBrush Python SDK:
The multiprocessing module is not supported.
The subprocess module is not supported, when used to invoke the ZBrush Python VM itself, e.g., subprocess.run([sys.executable, “my_script.py”], …). Other usages of the subprocess module are supported.
Most third-party libraries will work, but all third-party libraries are explicitly out of scope of support. This means that if you encounter issues with third-party packages, you must resolve them yourself or seek help from the package maintainers or community. We can only provide support for issues related to the ZBrush Python SDK itself. Third party libraries that attempt to spawn new Python processes (e.g., via multiprocessing or subprocess) will not work.
Environment Variables¶
ZBrush respects the following two environment variables to configure the Python environment:
PYTHONPATH¶
The PYTHONPATH variable is used to define additional module search paths for the ZBrush Python VM. It behaves largely the same way as in a standard CPython VM. I.e., you can place here libraries you want to import in your scripts without manipulating the default search paths.
Warning
Be careful on systems where multiple applications use the PYTHONPATH variable, as it might lead to Python version or package conflicts. Such environment can only contain libraries that are compatible with the Python version used by ZBrush.
Other than a standard CPython VM, ZBrush will also scan all PYTHONPATH directories for init.py files and execute them on startup. This allows for automatically adding ‘plugins’ to the palettes of ZBrush that load when ZBrush starts up. E.g., you could create directory structure as follows:
TimePlugin
├── init.py
└── README.md
Which is a ‘plugin’ that users can install by adding the TimePlugin directory to a directory in one of their PYTHONPATH paths. The init.py file could then contain code like this:
"""Implements a simple plugin that displays the current time in a dialog when a button is pressed.
"""
from zbrush import commands as zbc
from datetime import datetime
def show_time(sender: str) -> None:
"""Implements a button callback function that displays the current time when invoked.
"""
zbc.message_ok(f"The current time is: {datetime.now().strftime('%H:%M:%S')}", "Current Time")
if __name__ == "__main__":
# Add a 'Show Time' button directly to the ZScript palette.
zbc.add_button("ZScript:Show Time", "Displays the current time in a dialog.", show_time)
ZBRUSH_PLUGIN_PATH¶
The ZBRUSH_PLUGIN_PATH variable is used to define additional plugin search paths for the ZBrush Python VM. It behaves mostly the same way as PYTHONPATH, but other than it, it will execute all *.py files found in the defined directories on startup.
See also¶
Editor Configuration
Explains how to configure a code editor for ZBrush script development.
Importing Libraries
Explains how to provide and import libraries in your plugins.
Style Guide
Explains the code style and conventions used in this SDK.