Skip to content

Commit 9d10247

Browse files
jeremymanningclaude
andcommitted
Fix GitHub Actions widget import failures with conditional imports
Key changes: - Conditional import of EnhancedClusterConfigWidget to handle missing dependencies - Enhanced mock_ipython_environment fixture to force module re-import with mocks - Module state preservation to ensure clean test isolation Technical solution: 1. Import widget conditionally at module level to avoid import failures 2. Re-import notebook_magic module within fixture with mocked dependencies 3. Make widget class available globally within fixture scope Addresses GitHub Actions failures: - ImportError: IPython and ipywidgets are required for the widget interface - 13 failed tests due to missing dependencies in CI environment Tests now work in both local (with IPython) and CI (without IPython) environments. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 08e53b2 commit 9d10247

File tree

1 file changed

+49
-9
lines changed

1 file changed

+49
-9
lines changed

tests/test_notebook_magic.py

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
"""
44

55
import json
6+
import sys
67
import tempfile
78
import yaml
89
from pathlib import Path
910
from unittest.mock import MagicMock, patch
1011
import pytest
1112

12-
# Test the module's imports and functionality
13+
# Import only non-widget functionality at module level
1314
from clustrix.notebook_magic import (
1415
DEFAULT_CONFIGS,
15-
EnhancedClusterConfigWidget,
1616
detect_config_files,
1717
load_config_from_file,
1818
validate_ip_address,
@@ -22,6 +22,13 @@
2222
load_ipython_extension,
2323
)
2424

25+
# Import widget conditionally to avoid GitHub Actions import issues
26+
try:
27+
from clustrix.notebook_magic import EnhancedClusterConfigWidget
28+
except ImportError:
29+
# In GitHub Actions, widget import fails - will be handled by fixture
30+
EnhancedClusterConfigWidget = None
31+
2532

2633
class TestEnhancedDefaultConfigs:
2734
"""Test enhanced default configurations."""
@@ -156,13 +163,46 @@ def test_validate_hostname(self):
156163
@pytest.fixture
157164
def mock_ipython_environment():
158165
"""Mock IPython environment for testing."""
159-
with patch("clustrix.notebook_magic.IPYTHON_AVAILABLE", True):
160-
with patch("clustrix.notebook_magic.get_ipython") as mock_get_ipython:
161-
mock_ipython = MagicMock()
162-
mock_ipython.kernel = True
163-
mock_ipython.register_magic_function = MagicMock()
164-
mock_get_ipython.return_value = mock_ipython
165-
yield mock_ipython
166+
# Save current module state
167+
original_module = sys.modules.get("clustrix.notebook_magic")
168+
169+
try:
170+
# Clear the module to force re-import with mocks
171+
if "clustrix.notebook_magic" in sys.modules:
172+
del sys.modules["clustrix.notebook_magic"]
173+
174+
# Mock the IPython/ipywidgets modules
175+
with patch.dict(
176+
"sys.modules",
177+
{
178+
"IPython": MagicMock(),
179+
"IPython.core": MagicMock(),
180+
"IPython.core.magic": MagicMock(),
181+
"IPython.display": MagicMock(),
182+
"ipywidgets": MagicMock(),
183+
},
184+
):
185+
# Re-import the module with mocked dependencies
186+
import clustrix.notebook_magic
187+
188+
# Mock get_ipython
189+
with patch("clustrix.notebook_magic.get_ipython") as mock_get_ipython:
190+
mock_ipython = MagicMock()
191+
mock_ipython.kernel = True
192+
mock_ipython.register_magic_function = MagicMock()
193+
mock_get_ipython.return_value = mock_ipython
194+
195+
# Make the widget class available globally
196+
global EnhancedClusterConfigWidget
197+
EnhancedClusterConfigWidget = (
198+
clustrix.notebook_magic.EnhancedClusterConfigWidget
199+
)
200+
201+
yield mock_ipython
202+
finally:
203+
# Restore original module
204+
if original_module:
205+
sys.modules["clustrix.notebook_magic"] = original_module
166206

167207

168208
class TestEnhancedClusterConfigWidget:

0 commit comments

Comments
 (0)