Context
Cathedral Painter is a desktop image editor written in Python, with a plugin system and a planned Steam release. Editors in this class are almost always C++ projects, and for good reason. The bet here was that Python could hold up under a real paint workload if the architecture is strict about what the interpreter is allowed to touch.
The hard part
Interactive painting from an interpreted language. Drag a brush across a large canvas and the result has to appear in the same frame; touch those pixels in Python and the UI freezes. So the core rule of the whole codebase is that Python never handles pixels on the hot path. It decides what needs to happen. Native code and the GPU do the work.
Color is the second problem, and it's less forgiving than speed. Wrong color math looks fine right up until a designer opens the file somewhere else. The editor runs an ICC color pipeline so what you paint is what exports.
Approach
The canvas is split into tiles, and an edit only recomposites the tiles it touched, so a brush stroke costs what the stroke covered no matter how big the canvas is. A Skia GPU surface, driven through OpenGL inside the PySide6 UI, draws the result at interactive speed.
Pixel work goes to the libraries built for it: libvips, NumPy, and Pillow handle the processing. Python's actual job is orchestration and UI, which it is good at.
Plugins are plain Python. Extending the editor means writing the same language the editor is written in, not learning a native SDK.
Tradeoffs
Python was the right call. The plugin system alone justifies it: anyone who can write a little Python can write a working filter, and that's the difference between an editor with an ecosystem and an editor with a feature list.
The cost shows up at the edges. Shipping means compiling the whole application with Nuitka rather than asking users to install an interpreter, and compiling a large Qt app to native code is its own project. GPU rendering needs a CPU fallback for machines where OpenGL misbehaves. Every new feature gets checked for whether it sneaks Python onto the hot path, because one careless loop undoes the whole premise.
Where it stands
14.7k lines of Python so far: the tile compositor, the ICC color pipeline, the plugin system, and the PySide6 UI around all of it. The Steamworks SDK is already integrated for the planned Steam release — a product on a store has to install cleanly and start fast on hardware I've never seen.