Packaging System¶
ZooUI uses modern Python packaging standards (PEP 517 / PEP 660) with
hatchling as the build backend. A single pyproject.toml defines build
configuration, dependency metadata, and entry points.
Build Configuration¶
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "zooui"
version = "X.Y.Z"
requires-python = ">=3.12"
dependencies = [
"PySide6>=6.7",
"Pillow>=12.0",
"pyvips>=3.0",
"platformdirs>=3",
]
[project.scripts]
zooui = "zooui.app:main"
[project.gui-scripts]
zooui-gui = "zooui.app:main"
The current release version is 0.7.2.
Entry Points¶
ZooUI provides three ways to launch the application:
zooui/zooui-guiConsole-script and gui-script wrappers installed by pip into the user’s
PATH. Both callzooui.app:main(). On Windows,zooui-guisuppresses the console window.python -m zoouiModule entry point via
zooui/__main__.py:import sys from zooui.app import main sys.exit(main())
python main.pySource-checkout launcher at the repository root. A thin shim that imports from
zooui.app:from zooui.app import main if __name__ == "__main__": main()
The importable entry point lives in zooui.app. All launch paths
converge on zooui.app.main().
System Dependency Check¶
Before any heavy imports (PySide6, pyvips), _check_system_deps()
verifies that libvips (the C library) is present and loadable via
ctypes.CDLL(). If libvips is missing or broken (e.g., incompatible
conda channel mixing), the application exits with platform-specific install
instructions.
pdftoppm is checked with shutil.which() and prints a warning only —
PDF viewing is optional.
Package Data¶
All bundled data (icon, home scene, SVG shapes, test images) lives in
zooui/data/. Because the data directory resides inside the package,
hatchling includes it in the wheel automatically — no force-include or
MANIFEST.in chicanery is required.
Path Resolution (zooui.utils._packaging)¶
The function data_dir() returns the absolute path
to the zooui/ package directory, adapting to three runtime modes:
Mode |
Resolution |
Returns |
|---|---|---|
Source checkout |
|
|
Pip install |
|
|
Frozen (PyInstaller) |
|
extraction root |
Callers append "data" to reach bundled resources:
icon_path = os.path.join(data_dir(), "data", "icon.png")
Since the path resolution is centralized, switching between source, pip, and frozen builds requires no changes to the rest of the codebase.
XDG Runtime Paths (zooui.utils._xdg)¶
All writable user data follows the XDG Base Directory specification via
platformdirs, eliminating the legacy ~/.zooui/ dot-directory:
Purpose |
XDG Variable |
Default Path |
|---|---|---|
Config |
|
|
Backups, color history |
|
|
Tile cache, SVG cache |
|
|
Logs |
|
|
The module zooui.utils._xdg exports purpose-named functions
(get_config_file(), get_data_dir(), get_cache_dir(),
get_state_dir(), get_colorstore_dir()) so callers never need to
construct XDG paths manually.
Usage Instructions Embedding¶
The Help > Usage dialog displays RST content from an embedded Python module
(zooui/resources/_usage_rst.py) rather than reading a file from docs/.
This ensures the dialog works in pip-installed environments where the
documentation tree is absent.
The embedded copy is kept in sync with the canonical source
(docs/source/usageinstructions/userinterface.rst) by the version bump
script (scripts/bump_version.py). Sphinx-specific RST roles (:kbd:,
:file:, :doc:, :ref:) are automatically converted to standard
docutils markup during the sync via _sanitize_rst_for_dialog().
Wheel and sdist¶
Build the distribution artifacts:
python -m build
This produces:
dist/zooui-0.6.2-py3-none-any.whl
dist/zooui-0.6.2.tar.gz
The wheel is pure-Python (py3-none-any) — Qt binaries come from the
PySide6 dependency, not ZooUI itself.
The MANIFEST.in lists files for the source distribution:
graft zooui
include README.md
include LICENSE
include pyproject.toml
global-exclude __pycache__
global-exclude *.pyc
PyInstaller (Standalone Executable)¶
For standalone Windows builds, the packaging/ directory contains a
PyInstaller workflow including a .spec file, DLL bundle directory, and
build script. See packaging/README.md for details.
Release Workflow¶
Update
CHANGELOG.mdBump version:
python scripts/bump_version.py patch(orminor)Tag:
python scripts/bump_version.py patch --tagBuild:
python -m buildUpload:
twine upload dist/*
The bump script updates zooui/__init__.py, pyproject.toml,
zooui/data/home.pzs, and the embedded usage RST in one step.