From 8cf28c27f649ab269653ca42ffccef27e8fa37c6 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Tue, 24 Feb 2026 23:42:46 -0800 Subject: [PATCH 1/2] fix: use existing executable or unversioned python Co-Authored-By: Claude --- README.md | 4 ++-- slack_cli_hooks/hooks/get_hooks.py | 2 +- tests/slack_cli_hooks/hooks/test_get_hooks.py | 15 +++++++++++++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b03fb66..5645307 100644 --- a/README.md +++ b/README.md @@ -57,8 +57,8 @@ Below is an example `/slack.json` file that overrides the default `start`: ```json { "hooks": { - "get-hooks": "python3 -m slack_cli_hooks.hooks.get_hooks", - "start": "python3 app.py" + "get-hooks": "python -m slack_cli_hooks.hooks.get_hooks", + "start": "python app.py" } } ``` diff --git a/slack_cli_hooks/hooks/get_hooks.py b/slack_cli_hooks/hooks/get_hooks.py index 7399961..937b40d 100644 --- a/slack_cli_hooks/hooks/get_hooks.py +++ b/slack_cli_hooks/hooks/get_hooks.py @@ -7,7 +7,7 @@ PROTOCOL: Protocol # Wrap sys.executable in quotes to prevent execution failures if a white space is present in the absolute python path -EXEC = f"'{sys.executable}'" or "python3" +EXEC = f"'{sys.executable}'" if sys.executable else "python" hooks_payload = { diff --git a/tests/slack_cli_hooks/hooks/test_get_hooks.py b/tests/slack_cli_hooks/hooks/test_get_hooks.py index 6b5ed86..478fd4f 100644 --- a/tests/slack_cli_hooks/hooks/test_get_hooks.py +++ b/tests/slack_cli_hooks/hooks/test_get_hooks.py @@ -1,7 +1,22 @@ +import importlib +import sys +from unittest.mock import patch + +from slack_cli_hooks.hooks import get_hooks from slack_cli_hooks.hooks.get_hooks import hooks_payload class TestGetHooks: + def test_exec_uses_sys_executable(self): + with patch.object(sys, "executable", "/usr/bin/python3"): + importlib.reload(get_hooks) + assert get_hooks.EXEC == "'/usr/bin/python3'" + + def test_exec_falls_back_to_python_when_sys_executable_is_empty(self): + with patch.object(sys, "executable", ""): + importlib.reload(get_hooks) + assert get_hooks.EXEC == "python" + def test_hooks_payload(self): hooks = hooks_payload["hooks"] From c4d5644e129a27126dd3dbb3b643354197643574 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Thu, 26 Feb 2026 10:20:27 -0800 Subject: [PATCH 2/2] fix: windows execute --- slack_cli_hooks/hooks/get_hooks.py | 5 ++++- tests/slack_cli_hooks/hooks/test_get_hooks.py | 7 ++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/slack_cli_hooks/hooks/get_hooks.py b/slack_cli_hooks/hooks/get_hooks.py index 937b40d..1ef2246 100644 --- a/slack_cli_hooks/hooks/get_hooks.py +++ b/slack_cli_hooks/hooks/get_hooks.py @@ -7,7 +7,10 @@ PROTOCOL: Protocol # Wrap sys.executable in quotes to prevent execution failures if a white space is present in the absolute python path -EXEC = f"'{sys.executable}'" if sys.executable else "python" +if sys.executable: + EXEC = f"& '{sys.executable}'" if sys.platform == "win32" else f"'{sys.executable}'" +else: + EXEC = "python" hooks_payload = { diff --git a/tests/slack_cli_hooks/hooks/test_get_hooks.py b/tests/slack_cli_hooks/hooks/test_get_hooks.py index 478fd4f..fa24dea 100644 --- a/tests/slack_cli_hooks/hooks/test_get_hooks.py +++ b/tests/slack_cli_hooks/hooks/test_get_hooks.py @@ -8,10 +8,15 @@ class TestGetHooks: def test_exec_uses_sys_executable(self): - with patch.object(sys, "executable", "/usr/bin/python3"): + with patch.object(sys, "executable", "/usr/bin/python3"), patch.object(sys, "platform", "linux"): importlib.reload(get_hooks) assert get_hooks.EXEC == "'/usr/bin/python3'" + def test_exec_uses_call_operator_on_windows(self): + with patch.object(sys, "executable", "C:\\Python\\python.exe"), patch.object(sys, "platform", "win32"): + importlib.reload(get_hooks) + assert get_hooks.EXEC == "& 'C:\\Python\\python.exe'" + def test_exec_falls_back_to_python_when_sys_executable_is_empty(self): with patch.object(sys, "executable", ""): importlib.reload(get_hooks)