You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@magpie.apache.org by po...@apache.org on 2026/09/18 16:57:03 UTC

(magpie) branch main updated: fix(agent-isolation): pick a python that can import gi for the touch overlay (#1279)

This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/magpie.git


The following commit(s) were added to refs/heads/main by this push:
     new 4643ee4d fix(agent-isolation): pick a python that can import gi for the touch overlay (#1279)
4643ee4d is described below

commit 4643ee4db116a050f04db1bfcc528e288a1e14c4
Author: Jarek Potiuk <ja...@potiuk.com>
AuthorDate: Fri Sep 18 18:56:58 2026 +0200

    fix(agent-isolation): pick a python that can import gi for the touch overlay (#1279)
    
    `python3` alone is not a reliable probe for PyGObject. A Homebrew,
    pyenv or asdf python ahead of the system one on PATH has no gi, while
    a distro's python3-gi is bound to /usr/bin/python3. On such a machine
    the probe reports "no PyGObject" while a working gi sits one path
    away, and the full-screen overlay silently degrades to the small
    zenity dialog.
    
    That degradation is quiet and easy to misread: the overlay still
    appears, just as a plain box, so it looks like the window was
    redesigned rather than like a missing dependency.
    
    Resolve the interpreter instead of assuming it -- try python3, then
    /usr/bin/python3, and take the first that imports gi. A machine with a
    working PyGObject on PATH is unaffected, and zenity stays the last
    resort. arm()'s availability guard uses the same resolver, so it
    cannot bail on a host whose only gi lives off PATH.
    
    Exposed as the `_gi_python` internal mode alongside the existing
    `_watch` / `_overlay` modes, so the resolver is testable: the new test
    asserts whatever it picks can actually import gi.
    
    Generated-by: Claude (Opus 5)
---
 tools/agent-isolation/gpg-touch-overlay.sh         | 27 +++++++++++++++++++---
 .../tests/test_gpg_touch_overlay.py                | 22 ++++++++++++++++++
 2 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/tools/agent-isolation/gpg-touch-overlay.sh b/tools/agent-isolation/gpg-touch-overlay.sh
index f2a37a1c..3819fcd5 100755
--- a/tools/agent-isolation/gpg-touch-overlay.sh
+++ b/tools/agent-isolation/gpg-touch-overlay.sh
@@ -94,7 +94,7 @@ readonly SIGNING_SUBCOMMANDS='commit|tag|merge|rebase|revert|cherry-pick|am|push
 arm() {
     if [[ -z ${MAGPIE_GPG_TOUCH_DRY_RUN:-} ]]; then
         [[ -n ${DISPLAY:-}${WAYLAND_DISPLAY:-} ]] || return 0
-        command -v zenity >/dev/null 2>&1 || python3 -c 'import gi' >/dev/null 2>&1 || return 0
+        command -v zenity >/dev/null 2>&1 || _gi_python >/dev/null || return 0
     fi
 
     local payload command_text
@@ -208,6 +208,25 @@ _watch() {
     done
 }
 
+# Resolve an interpreter that can actually import gi, printing it on
+# stdout. `python3` alone is not a reliable probe: a Homebrew, pyenv or
+# asdf python ahead of the system one on PATH has no PyGObject, while a
+# distro's python3-gi is bound to /usr/bin/python3. Probing only the
+# PATH python on such a machine reports "no PyGObject" while a perfectly
+# good gi sits one path away, and the full-screen overlay silently
+# degrades to the zenity box.
+_gi_python() {
+    local py
+    for py in python3 /usr/bin/python3; do
+        command -v "$py" >/dev/null 2>&1 || continue
+        if "$py" -c 'import gi' >/dev/null 2>&1; then
+            printf '%s\n' "$py"
+            return 0
+        fi
+    done
+    return 1
+}
+
 # The window is exec'd so this pid *is* the window: one kill closes it,
 # with no orphaned child left drawing on the screen.
 #
@@ -215,8 +234,9 @@ _watch() {
 # does. zenity is the fallback for a machine without PyGObject — a small
 # dialog, but better than a silent block.
 _overlay() {
-    if python3 -c 'import gi' >/dev/null 2>&1; then
-        exec python3 "$OVERLAY_WINDOW" >/dev/null 2>&1
+    local py
+    if py="$(_gi_python)"; then
+        exec "$py" "$OVERLAY_WINDOW" >/dev/null 2>&1
     fi
     exec zenity --warning --title="$TITLE" --width=560 --text="$BODY" >/dev/null 2>&1
 }
@@ -226,6 +246,7 @@ case "${1:-}" in
     disarm)   disarm ;;
     _watch)   _watch ;;
     _overlay) _overlay ;;
+    _gi_python) _gi_python ;;
     *)
         printf '%s: expected arm|disarm, got "%s"\n' "${0##*/}" "${1:-}" >&2
         exit 2
diff --git a/tools/agent-isolation/tests/test_gpg_touch_overlay.py b/tools/agent-isolation/tests/test_gpg_touch_overlay.py
index 9b49d6a7..17d3b7f8 100644
--- a/tools/agent-isolation/tests/test_gpg_touch_overlay.py
+++ b/tools/agent-isolation/tests/test_gpg_touch_overlay.py
@@ -110,3 +110,25 @@ def test_unknown_mode_is_rejected() -> None:
     )
     assert result.returncode == 2
     assert "arm|disarm" in result.stderr
+
+
+def test_gi_python_only_reports_an_interpreter_that_can_import_gi() -> None:
+    """Whatever the resolver picks must actually be able to import gi.
+
+    `python3` alone is not a reliable probe: a Homebrew, pyenv or asdf
+    python ahead of the system one on PATH has no PyGObject, while a
+    distro's python3-gi is bound to /usr/bin/python3. Probing only the
+    PATH python there reports "no PyGObject" while a working gi sits one
+    path away, and the overlay silently degrades to the zenity box.
+    """
+    result = subprocess.run(
+        ["bash", str(SCRIPT), "_gi_python"], capture_output=True, text=True
+    )
+    if result.returncode != 0:
+        assert result.stdout.strip() == ""
+        pytest.skip("no interpreter on this machine can import gi")
+
+    interpreter = result.stdout.strip()
+    assert interpreter
+    probe = subprocess.run([interpreter, "-c", "import gi"], capture_output=True)
+    assert probe.returncode == 0, f"{interpreter} was selected but cannot import gi"