From 914f7461dc1b0ff3a3b30df4a879e3f81a2cb4c9 Mon Sep 17 00:00:00 2001 From: thakoreh Date: Sun, 5 Apr 2026 10:43:52 -0700 Subject: [PATCH] fix: add missing shutil import for Matrix E2EE setup Cherry-picked from PR #5136 by thakoreh. setup_gateway() uses shutil.which('uv') at line 2126 but shutil was never imported at module level, causing NameError during Matrix E2EE auto-install. Adds top-level import and regression test. --- hermes_cli/setup.py | 1 + tests/hermes_cli/test_setup_matrix_e2ee.py | 31 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 tests/hermes_cli/test_setup_matrix_e2ee.py diff --git a/hermes_cli/setup.py b/hermes_cli/setup.py index 98b7541523..201c7b54ab 100644 --- a/hermes_cli/setup.py +++ b/hermes_cli/setup.py @@ -14,6 +14,7 @@ Config files are stored in ~/.hermes/ for easy access. import importlib.util import logging import os +import shutil import sys from pathlib import Path from typing import Optional, Dict, Any diff --git a/tests/hermes_cli/test_setup_matrix_e2ee.py b/tests/hermes_cli/test_setup_matrix_e2ee.py new file mode 100644 index 0000000000..ebdb5a44c7 --- /dev/null +++ b/tests/hermes_cli/test_setup_matrix_e2ee.py @@ -0,0 +1,31 @@ +"""Test that setup.py has shutil available for Matrix E2EE auto-install.""" +import ast + +import pytest + + +def _parse_setup_imports(): + """Parse setup.py and return top-level import names.""" + with open("hermes_cli/setup.py") as f: + tree = ast.parse(f.read()) + names = set() + for node in ast.walk(tree): + if isinstance(node, ast.Import): + for alias in node.names: + names.add(alias.name) + elif isinstance(node, ast.ImportFrom): + for alias in node.names: + names.add(alias.name) + return names + + +class TestSetupShutilImport: + def test_shutil_imported_at_module_level(self): + """shutil must be imported at module level so setup_gateway can use it + for the matrix-nio auto-install path (line ~2126).""" + names = _parse_setup_imports() + assert "shutil" in names, ( + "shutil is not imported at the top of hermes_cli/setup.py. " + "This causes a NameError when the Matrix E2EE auto-install " + "tries to call shutil.which('uv')." + )