from __future__ import annotations import ast import unittest from pathlib import Path class PurityTests(unittest.TestCase): def test_package_has_no_process_launching_calls(self) -> None: package = Path(__file__).parents[1] / "restream_playout" forbidden_imports = {"subprocess"} forbidden_calls = {"os.system", "os.popen", "subprocess.run", "subprocess.Popen", "subprocess.call"} violations: list[str] = [] for path in package.glob("*.py"): tree = ast.parse(path.read_text(encoding="utf-8"), filename=str(path)) for node in ast.walk(tree): if isinstance(node, ast.Import): for name in node.names: if name.name in forbidden_imports: violations.append(f"{path.name}: imports {name.name}") elif isinstance(node, ast.ImportFrom) and node.module in forbidden_imports: violations.append(f"{path.name}: imports from {node.module}") elif isinstance(node, ast.Call) and isinstance(node.func, ast.Attribute): if isinstance(node.func.value, ast.Name): call = f"{node.func.value.id}.{node.func.attr}" if call in forbidden_calls: violations.append(f"{path.name}: calls {call}") self.assertEqual(violations, [])