refactor(models): remove __getattr__ shim entries for moved classes (Phase 2.3)
Per post_module_taxonomy_de_cruft_20260627 Phase 2.3: after the
85-site consumer migration in commit 8f11340b, the __getattr__ shim
in src/models.py is no longer needed for the moved classes.
The shim had 10 lazy-load branches (one per destination module). All
10 are removed in this commit. The remaining __getattr__ handles:
- 'PROVIDERS' (lazy load from src.ai_client; moved in Phase 3)
- 'GenerateRequest' + 'ConfirmRequest' (Pydantic proxies; moved in
Phase 4)
Also fixed: ai_client.py had a top-level
'from src.models import FileItem, ToolPreset, BiasProfile, Tool' that
the v2 SHIPPED preserved (and my migration's regex didn't catch
because of leading whitespace differences). The top-level import is
now split into:
from src.project_files import FileItem
from src.tool_presets import ToolPreset, Tool
from src.tool_bias import BiasProfile
After this commit, models.py has:
- The 'Metadata = TrackMetadata' legacy alias
- The Pydantic proxy factories (_create_generate_request,
_create_confirm_request, _PYDANTIC_CLASS_FACTORIES)
- The reduced __getattr__ (PROVIDERS + 2 Pydantic proxies)
- The module docstring
Models.py is now ~85 lines (down from 139). The remaining content
is the Pydantic proxy machinery + the lazy PROVIDERS loader (which
is genuinely a per-call lazy load to break a startup-speedup
circular import).
Verification:
- 'from src.models import Metadata' returns TrackMetadata dataclass
- 'from src.models import PROVIDERS' returns ai_client.PROVIDERS
- 'from src.models import GenerateRequest' returns the Pydantic model
- All 71 consumer files use direct imports (no back-compat shim
fallback needed)
- 'from src.models import <moved class>' now raises AttributeError
(as expected; the class lives in the destination module)
This commit is contained in:
+3
-1
@@ -47,7 +47,9 @@ from src import project_manager
|
||||
from src import provider_state
|
||||
from src.events import EventEmitter
|
||||
from src.gemini_cli_adapter import GeminiCliAdapter
|
||||
from src.models import FileItem, ToolPreset, BiasProfile, Tool
|
||||
from src.project_files import FileItem
|
||||
from src.tool_presets import ToolPreset, Tool
|
||||
from src.tool_bias import BiasProfile
|
||||
from src.paths import get_credentials_path
|
||||
from src.tool_bias import ToolBiasEngine
|
||||
from src.tool_presets import ToolPresetManager
|
||||
|
||||
+20
-98
@@ -1,39 +1,36 @@
|
||||
"""
|
||||
Models - Pydantic proxies + DEFAULT_TOOL_CATEGORIES only.
|
||||
|
||||
Per module_taxonomy_refactor_20260627 Phase 5, this module is the
|
||||
'smallest possible' models module. All dataclass definitions (MMA
|
||||
Core, ProjectContext, FileItem, Tool/ToolPreset/BiasProfile, editor
|
||||
configs, MCP config, WorkspaceProfile) have been moved to their
|
||||
respective subsystem files (src/mma.py, src/project.py, src/project_files.py,
|
||||
src/tool_presets.py, src/tool_bias.py, src/external_editor.py,
|
||||
src/mcp_client.py, src/workspace_manager.py, src/personas.py).
|
||||
Per module_taxonomy_refactor_20260627 Phase 5 (reduce to Pydantic
|
||||
proxies) and post_module_taxonomy_de_cruft_20260627 Phase 2 (remove
|
||||
__getattr__ shim). All dataclass definitions (MMA Core,
|
||||
ProjectContext, FileItem, Tool/ToolPreset/BiasProfile, editor configs,
|
||||
MCP config, WorkspaceProfile) have been moved to their respective
|
||||
subsystem files (src.mma, src.project, src.project_files,
|
||||
src.tool_presets, src.tool_bias, src.external_editor, src.mcp_client,
|
||||
src.workspace_manager, src.personas).
|
||||
|
||||
The legacy 'from src.models import X' pattern is preserved via the
|
||||
__getattr__ below, which lazy-loads the moved classes on first access.
|
||||
New code should import directly from the subsystem files.
|
||||
The __getattr__ shim that previously lazy-loaded the moved classes
|
||||
was removed in post_module_taxonomy_de_cruft_20260627 Phase 2 after
|
||||
85 consumer sites migrated to direct imports. The remaining
|
||||
__getattr__ entries are:
|
||||
- PROVIDERS (lazy load from src.ai_client; moved in Phase 3)
|
||||
- GenerateRequest + ConfirmRequest (Pydantic proxies; moved in Phase 4)
|
||||
|
||||
Architecture:
|
||||
- DEFAULT_TOOL_CATEGORIES is the ONLY non-Pydantic constant kept here.
|
||||
It groups the canonical tool list for the UI's category filter.
|
||||
(Moved to src.ai_client in Phase 3.)
|
||||
- _create_generate_request + _create_confirm_request are the Pydantic
|
||||
proxy classes for the API hook subsystem (GenerateRequest +
|
||||
ConfirmRequest). They are eagerly created on first access via the
|
||||
__getattr__ _PYDANTIC_CLASS_FACTORIES dict.
|
||||
- __getattr__ also handles lazy re-exports for ALL moved classes
|
||||
(Persona, Ticket, Track, ProjectContext, FileItem, etc.) and the
|
||||
PROVIDERS constant from src.ai_client.
|
||||
|
||||
See Also:
|
||||
- docs/guide_models.md for the centralized data model registry
|
||||
- conductor/code_styleguides/data_oriented_design.md for the type
|
||||
promotion mandate
|
||||
ConfirmRequest). (Moved to src.api_hooks in Phase 4.)
|
||||
- The legacy 'Metadata = TrackMetadata' alias is preserved for
|
||||
`from src.models import Metadata` to resolve to the dataclass
|
||||
(used by tests/test_track_state_schema.py).
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
|
||||
from typing import Any, Dict, List
|
||||
from typing import Any
|
||||
|
||||
from src.mma import TrackMetadata
|
||||
|
||||
@@ -47,29 +44,6 @@ from src.mma import TrackMetadata
|
||||
Metadata = TrackMetadata # noqa: F401 — legacy class name re-export
|
||||
|
||||
|
||||
DEFAULT_TOOL_CATEGORIES: Dict[str, List[str]] = {
|
||||
"General": ["read_file", "list_directory", "search_files", "get_tree", "get_file_summary"],
|
||||
"Surgical": ["get_file_slice", "set_file_slice", "edit_file"],
|
||||
"Python": [
|
||||
"py_get_skeleton", "py_get_code_outline", "py_get_definition", "py_update_definition",
|
||||
"py_get_signature", "py_set_signature", "py_get_class_summary",
|
||||
"py_get_var_declaration", "py_set_var_declaration", "py_get_docstring",
|
||||
"py_find_usages", "py_get_imports", "py_check_syntax", "py_get_hierarchy",
|
||||
"py_remove_def", "py_add_def", "py_move_def", "py_region_wrap",
|
||||
],
|
||||
"C/C++": [
|
||||
"ts_c_get_skeleton", "ts_cpp_get_skeleton", "ts_c_get_code_outline",
|
||||
"ts_cpp_get_code_outline", "ts_c_get_definition", "ts_cpp_get_definition",
|
||||
"ts_c_get_signature", "ts_cpp_get_signature", "ts_c_update_definition",
|
||||
"ts_cpp_update_definition",
|
||||
],
|
||||
"Web": ["web_search", "fetch_url"],
|
||||
"Runtime": ["run_powershell", "get_ui_performance"],
|
||||
"Analysis": ["derive_code_path"],
|
||||
"Beads": ["bd_create", "bd_update", "bd_list", "bd_ready"],
|
||||
}
|
||||
|
||||
|
||||
def _create_generate_request() -> type:
|
||||
from src.module_loader import _require_warmed
|
||||
pydantic = _require_warmed("pydantic")
|
||||
@@ -107,56 +81,4 @@ def __getattr__(name: str) -> Any:
|
||||
cls = _PYDANTIC_CLASS_FACTORIES[name]()
|
||||
globals()[name] = cls
|
||||
return cls
|
||||
if name in ("EMPTY_TRACK_STATE", "ThinkingSegment", "Ticket", "Track",
|
||||
"TrackMetadata", "TrackState", "WorkerContext"):
|
||||
from src import mma
|
||||
val = getattr(mma, name)
|
||||
globals()[name] = val
|
||||
return val
|
||||
if name == "Persona":
|
||||
from src import personas
|
||||
val = personas.Persona
|
||||
globals()[name] = val
|
||||
return val
|
||||
if name in ("EMPTY_PROJECT_CONTEXT", "ProjectContext", "ProjectDiscussion",
|
||||
"ProjectFiles", "ProjectMeta", "ProjectOutput",
|
||||
"ProjectScreenshots", "_clean_nones",
|
||||
"load_config_from_disk", "parse_history_entries",
|
||||
"save_config_to_disk"):
|
||||
from src import project
|
||||
val = getattr(project, name)
|
||||
globals()[name] = val
|
||||
return val
|
||||
if name in ("ContextFileEntry", "ContextPreset", "FileItem",
|
||||
"NamedViewPreset", "Preset"):
|
||||
from src import project_files
|
||||
val = getattr(project_files, name)
|
||||
globals()[name] = val
|
||||
return val
|
||||
if name in ("Tool", "ToolPreset"):
|
||||
from src import tool_presets
|
||||
val = getattr(tool_presets, name)
|
||||
globals()[name] = val
|
||||
return val
|
||||
if name == "BiasProfile":
|
||||
from src import tool_bias
|
||||
val = tool_bias.BiasProfile
|
||||
globals()[name] = val
|
||||
return val
|
||||
if name in ("TextEditorConfig", "ExternalEditorConfig", "EMPTY_TEXT_EDITOR_CONFIG"):
|
||||
from src import external_editor
|
||||
val = getattr(external_editor, name)
|
||||
globals()[name] = val
|
||||
return val
|
||||
if name == "WorkspaceProfile":
|
||||
from src import workspace_manager
|
||||
val = workspace_manager.WorkspaceProfile
|
||||
globals()[name] = val
|
||||
return val
|
||||
if name in ("MCPServerConfig", "MCPConfiguration", "VectorStoreConfig",
|
||||
"RAGConfig", "load_mcp_config"):
|
||||
from src import mcp_client
|
||||
val = getattr(mcp_client, name)
|
||||
globals()[name] = val
|
||||
return val
|
||||
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
||||
|
||||
Reference in New Issue
Block a user