github m3trik/pythontk v0.9.3
pythontk v0.9.3

3 hours ago
  • 2026-08-02 — Hand-off launches can sanitize the child env: ScriptLaunchSpec.launch_env + AppLauncher.handoff_env. A DCC bridge launches app B from inside app A, so B inherits A's whole environment — including an OCIO var pointing inside A's own install tree (Blender's bundled ocio_profile_version: 2.5 config), which B's OpenColorIO runtime may be unable to load: Maya 2025 (OCIO 2.3) failed color-management init on every bridge launch. ScriptLaunchSpec gains an optional launch_env callable (not a dict — the env must reflect launch-time state, and specs are built at import time; launch_args precedent), threaded through ScriptLaunchDeliverer.deliver into AppLauncher.launch(env=...). The policy half is AppLauncher.handoff_env(source_root): copy of this process's env without OCIO when — and only when — its path lies under source_root (the running app's install tree; nobody points a studio pipeline config into a versioned DCC install dir, so a config outside it is deliberate cross-app state and inherits untouched). App-agnostic: the DCC bridges supply their own roots (blendertk from bpy.app.binary_path, mayatk from $MAYA_LOCATION). The deliverer treats the hook as best-effort: a raising hook logs a warning and launches with the inherited env rather than costing the send. test_app_launcher.py +3 (private stripped with the rest of the env intact; foreign inherited; no-OCIO/no-root inherit); test_bridge.py +1 (hook env reaches the launcher; raising hook degrades, send still succeeds).

  • 2026-08-02 — Workspace.promote + Workspace.for_path: the two workspace primitives both DCC adapters had each hand-rolled. promote(root, scene_exts, rules=None) is the inverse of create — instead of imposing a layout it describes the one already on disk (scene files loose in the root ⇒ scene rule .; an existing textures/ with no sourceimages/ ⇒ that is the sourceImages rule) — and was duplicated verbatim in mtk.promote_workspace and btk.promote_workspace, differing only in the scene extensions. A divergence there would have made the two DCCs describe the same folder differently, which is precisely what the shared marker format exists to prevent. for_path(path) is the resolver tail both current_workspace implementations shared: nearest marked ancestor, else the path's own folder as an unmarked workspace. Also new: module constant SCENE_RULES — one tuple so scene_dir (reader) and promote (writer) can't disagree about which rules mean "scene". promote only writes the per-format aliases (mayaAscii/mayaBinary) a caller's rule set already carries, so a custom template never silently grows rules it didn't ask for. test_workspace.py +9 → 39.

  • 2026-08-02 — WorkspaceTemplates: named file-rule sets are now a SHARED, unnamespaced store, not a Blender-only one. A workspace.mel is deliberately a shared Maya/Blender project — but the templates that say how a new project is built lived under PresetStore("workspace_templates", package="blendertk"), so a studio layout saved from Blender's Workspace Editor was invisible to Maya, and mayatk's new create_workspace twin would have had to grow a second, divergent store. ptk.WorkspaceTemplates (in file_utils/workspace.py, beside the Workspace model it serves) is that one store: user_config_root()/workspace_templates, no owning package, with list / rules / save / delete classmethods. rules(name=None) resolves the active (last-saved) template, strips uitk PresetManager's _meta bookkeeping block, and never returns an empty dict — an empty template would otherwise build ruleless projects. store() is rebuilt per call rather than cached, so a $UITK_PRESETS_ROOT sandbox set after first use still takes effect (tests rely on this), and it migrates a pre-existing blendertk/workspace_templates directory on first access — those are user data. test_workspace.py +8 → 30.

Don't miss a new pythontk release

NewReleases is sending notifications on new releases.