diff --git a/tests/property/test_http_server_independence_properties.py b/tests/property/test_http_server_independence_properties.py index 365f0f2..8f1155e 100644 --- a/tests/property/test_http_server_independence_properties.py +++ b/tests/property/test_http_server_independence_properties.py @@ -8,6 +8,10 @@ import sys +def _is_aci_module(name: str) -> bool: + return name == "aci" or name.startswith("aci.") + + def get_transitive_imports(module_name: str) -> set[str]: """ Get all transitive imports for a module. @@ -15,17 +19,34 @@ def get_transitive_imports(module_name: str) -> set[str]: This function imports the module and collects all modules that were loaded as a result. """ + aci_modules = { + name: module + for name, module in sys.modules.items() + if _is_aci_module(name) + } + # Import from a clean aci module state, then restore the previous state. + for mod in aci_modules: + del sys.modules[mod] + # Record modules before import before_import = set(sys.modules.keys()) - # Import the module - __import__(module_name) - - # Record modules after import - after_import = set(sys.modules.keys()) + try: + # Import the module + __import__(module_name) - # Return newly imported modules - return after_import - before_import + # Record modules after import + after_import = set(sys.modules.keys()) + return after_import - before_import + finally: + loaded_aci_modules = [ + name + for name in sys.modules.keys() + if _is_aci_module(name) + ] + for mod in loaded_aci_modules: + del sys.modules[mod] + sys.modules.update(aci_modules) def test_http_server_does_not_import_cli(): @@ -38,11 +59,6 @@ def test_http_server_does_not_import_cli(): This ensures the HTTP server can be used without depending on CLI code. """ - # Clear any cached imports of aci modules to get clean import - modules_to_clear = [key for key in sys.modules.keys() if key.startswith("aci")] - for mod in modules_to_clear: - del sys.modules[mod] - # Get transitive imports of http_server transitive_imports = get_transitive_imports("aci.http_server") @@ -62,11 +78,6 @@ def test_http_server_imports_from_services_container(): The HTTP server SHALL import service creation from `aci.services.container`. """ - # Clear any cached imports - modules_to_clear = [key for key in sys.modules.keys() if key.startswith("aci")] - for mod in modules_to_clear: - del sys.modules[mod] - # Import http_server transitive_imports = get_transitive_imports("aci.http_server") diff --git a/tests/property/test_mcp_server_independence_properties.py b/tests/property/test_mcp_server_independence_properties.py index 6f8be99..99cf754 100644 --- a/tests/property/test_mcp_server_independence_properties.py +++ b/tests/property/test_mcp_server_independence_properties.py @@ -8,6 +8,10 @@ import sys +def _is_aci_module(name: str) -> bool: + return name == "aci" or name.startswith("aci.") + + def get_transitive_imports(module_name: str) -> set[str]: """ Get all transitive imports for a module. @@ -15,17 +19,34 @@ def get_transitive_imports(module_name: str) -> set[str]: This function imports the module and collects all modules that were loaded as a result. """ + aci_modules = { + name: module + for name, module in sys.modules.items() + if _is_aci_module(name) + } + # Import from a clean aci module state, then restore the previous state. + for mod in aci_modules: + del sys.modules[mod] + # Record modules before import before_import = set(sys.modules.keys()) - # Import the module - __import__(module_name) + try: + # Import the module + __import__(module_name) - # Record modules after import - after_import = set(sys.modules.keys()) - - # Return newly imported modules - return after_import - before_import + # Record modules after import + after_import = set(sys.modules.keys()) + return after_import - before_import + finally: + loaded_aci_modules = [ + name + for name in sys.modules.keys() + if _is_aci_module(name) + ] + for mod in loaded_aci_modules: + del sys.modules[mod] + sys.modules.update(aci_modules) def test_mcp_services_does_not_import_cli(): @@ -38,11 +59,6 @@ def test_mcp_services_does_not_import_cli(): This ensures the MCP server can be used without depending on CLI code. """ - # Clear any cached imports of aci modules to get clean import - modules_to_clear = [key for key in sys.modules.keys() if key.startswith("aci")] - for mod in modules_to_clear: - del sys.modules[mod] - # Get transitive imports of mcp.services transitive_imports = get_transitive_imports("aci.mcp.services") @@ -62,11 +78,6 @@ def test_mcp_services_imports_from_services_container(): The MCP server SHALL import service creation from `aci.services.container`. """ - # Clear any cached imports - modules_to_clear = [key for key in sys.modules.keys() if key.startswith("aci")] - for mod in modules_to_clear: - del sys.modules[mod] - # Import mcp.services transitive_imports = get_transitive_imports("aci.mcp.services") @@ -86,11 +97,6 @@ def test_mcp_handlers_does_not_import_cli(): This ensures the MCP handlers can be used without depending on CLI code. """ - # Clear any cached imports of aci modules to get clean import - modules_to_clear = [key for key in sys.modules.keys() if key.startswith("aci")] - for mod in modules_to_clear: - del sys.modules[mod] - # Get transitive imports of mcp.handlers transitive_imports = get_transitive_imports("aci.mcp.handlers") @@ -111,11 +117,6 @@ def test_mcp_handlers_imports_repository_resolver(): The MCP handlers SHALL import repository resolution from `aci.services.repository_resolver`. """ - # Clear any cached imports - modules_to_clear = [key for key in sys.modules.keys() if key.startswith("aci")] - for mod in modules_to_clear: - del sys.modules[mod] - # Import mcp.handlers transitive_imports = get_transitive_imports("aci.mcp.handlers")