Files
manual_slop/tests/test_models_no_top_level_tomli_w.py
T
ed e430df86f1 refactor(project): create src/project.py with ProjectContext + 5 sub + config IO (split from models.py)
Per the 4-criteria decision rule (C1=cross-system, C3=tests, C4=size);
ProjectContext is the typed return of project_manager.flat_config();
the 5 sub-dataclasses model the actual nested dict structure of
flat_config()'s return; load_config_from_disk / save_config_to_disk
are the canonical config I/O primitives (renamed from the private
_load_config_from_disk / _save_config_to_disk).

This commit:
 1. Creates src/project.py with ProjectContext + 5 sub (ProjectMeta,
    ProjectOutput, ProjectFiles, ProjectScreenshots, ProjectDiscussion)
    + EMPTY_PROJECT_CONTEXT + _clean_nones + load_config_from_disk +
    save_config_to_disk + parse_history_entries.
 2. Removes the original class + function definitions from src/models.py.
 3. Adds backward-compat re-exports in src/models.py (the same pattern
    used by Phase 3a mma.py and Phase 3g personas.py).
 4. Updates src/app_controller.py to use the new public function names
    (load_config_from_disk / save_config_to_disk).
 5. Updates tests/test_models_no_top_level_tomli_w.py to use the new
    public name (the test still asserts lazy-loading; the lazy load
    happens in the new project.py module).
 6. Updates scripts/audit_no_models_config_io.py FORBIDDEN_PATTERNS to
    reference the new public names (models.load_config_from_disk /
    models.save_config_to_disk) + the new src.project path.

Verification: VC6
  uv run python -c 'from src.project import ProjectContext, ProjectMeta,
  ProjectOutput, ProjectFiles, ProjectScreenshots, ProjectDiscussion,
  _clean_nones, load_config_from_disk, save_config_to_disk,
  parse_history_entries'  # OK
  uv run python -c 'from src.models import ProjectContext, ...'  # OK
  (re-exports work)

Pre-existing test regression (NOT caused by this commit):
  tests/test_models_no_top_level_tomli_w.py::test_models_does_not_import_tomli_w_at_module_level
  was already failing because the Phase 3g 'from src.personas import Persona'
  re-export in src/models.py loads src.personas at module level, which
  loads tomli_w. The Phase 5 reduce-models.py pass moves the persona
  import into __getattr__ (lazy), which will make this test pass again.

Tests verified: tests/test_project_context_20260627.py (10/10 PASS),
tests/test_project_serialization.py (2/2 PASS), tests/test_thinking_persistence.py
(4/4 PASS), tests/test_presets.py (3/3 PASS), tests/test_persona_models.py
(2/2 PASS), tests/test_ticket_queue.py (PASS), tests/test_dag_engine.py
(PASS), tests/test_orchestration_logic.py (PASS).
2026-06-26 09:46:12 -04:00

72 lines
2.2 KiB
Python

"""Tests that src/models.py has no top-level tomli_w import (sub-track 2).
Per spec.md:2.2 Layer 1 (startup_speedup_20260606), the main thread's
import chain must not include heavy modules. tomli_w (~30ms cold) is
loaded on first call to save_config() instead of at module import time.
"""
import sys
import subprocess
import textwrap
import os
from pathlib import Path
ROOT = Path(__file__).parent.parent
def _run_in_subprocess(snippet: str, timeout: int = 30) -> subprocess.CompletedProcess:
script = textwrap.dedent(snippet)
return subprocess.run(
[sys.executable, "-c", script],
capture_output=True,
text=True,
cwd=str(ROOT),
timeout=timeout,
)
def test_models_does_not_import_tomli_w_at_module_level() -> None:
"""import src.models should NOT trigger tomli_w to be in sys.modules."""
res = _run_in_subprocess("""
import sys
import src.models
print('tomli_w' in sys.modules)
""")
assert res.stdout.strip() == "False", (
f"tomli_w should not be in sys.modules after import src.models. "
f"Got: {res.stdout!r}, stderr: {res.stderr!r}"
)
def test_models_can_still_call_save_config_after_lazy_load() -> None:
"""save_config() must work even though tomli_w is lazy-loaded."""
import src.models
config = {
"ai": {"provider": "minimax", "model": "MiniMax-M3", "temperature": 0.0},
"theme": {"palette": "solarized_dark", "font_size": 16.0},
}
try:
src.models.save_config_to_disk(config)
except Exception as e:
pytest.fail(f"save_config raised after lazy tomli_w: {e}")
finally:
# Clean up: restore original config if we modified it
pass
def test_save_config_uses_tomli_w_on_demand() -> None:
"""First call to save_config() should trigger tomli_w import (subsequent calls hit sys.modules cache)."""
import src.models
# Drop tomli_w from sys.modules if it was already loaded (e.g. by other tests)
if "tomli_w" in sys.modules:
del sys.modules["tomli_w"]
assert "tomli_w" not in sys.modules
# Call save_config - this should trigger the import
try:
src.models.save_config_to_disk({"test_key": "test_value"})
except Exception:
# We don't care if the save itself fails; we just want to verify
# the import happened.
pass
assert "tomli_w" in sys.modules, "save_config() should have imported tomli_w on demand"