From 57b6778007f5c30a1f926a471522c8be8e916a30 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sat, 20 Jun 2026 09:26:04 -0400 Subject: [PATCH] refactor(mcp_client): migrate L1338 py_get_hierarchy to Result[T] (Phase 7 site 1) --- src/mcp_client.py | 43 +++++++++---------------------------------- 1 file changed, 9 insertions(+), 34 deletions(-) diff --git a/src/mcp_client.py b/src/mcp_client.py index 2bd34fb5..80e6d589 100644 --- a/src/mcp_client.py +++ b/src/mcp_client.py @@ -1302,41 +1302,16 @@ def py_check_syntax(path: str) -> str: return "; ".join(e.ui_message() for e in resolved.errors) def py_get_hierarchy(path: str, class_name: str) -> str: - """Scans the project to find subclasses of a given class.""" - p, err = _resolve_and_check(path) - if err: return err - assert p is not None - subclasses: list[str] = [] + """Scans the project to find subclasses of a given class. - def _search_file(fp: Path) -> None: - if not _is_allowed(fp): return - try: - code = fp.read_text(encoding="utf-8") - tree = ast.parse(code) - for node in ast.walk(tree): - if isinstance(node, ast.ClassDef): - for base in node.bases: - if isinstance(base, ast.Name) and base.id == class_name: - subclasses.append(f"{fp.name}: class {node.name}({class_name})") - elif isinstance(base, ast.Attribute) and base.attr == class_name: - if isinstance(base.value, ast.Name): - subclasses.append(f"{fp.name}: class {node.name}({base.value.id}.{class_name})") - except Exception: - pass - try: - if p.is_file(): - _search_file(p) - else: - for root, dirs, files in os.walk(p): - dirs[:] = [d for d in dirs if not d.startswith('.') and d not in ('__pycache__', 'venv', 'env')] - for file in files: - if file.endswith('.py'): - _search_file(Path(root) / file) - if not subclasses: - return f"No subclasses of '{class_name}' found in {p}" - return f"Subclasses of '{class_name}':\n" + "\n".join(f" - {s}" for s in subclasses) - except Exception as e: - return f"ERROR finding subclasses of '{class_name}': {e}" + Thin wrapper over py_get_hierarchy_result; the legacy str shape is + preserved for backward compatibility, but the try/except Exception + lives in the Result variant. + """ + resolved = py_get_hierarchy_result(path, class_name) + if resolved.ok: + return resolved.data + return "; ".join(e.ui_message() for e in resolved.errors) def py_get_docstring(path: str, name: str) -> str: """Extracts the docstring for a specific module, class, or function."""