"""Regression tests for the App.__getattr__ passthrough bug. The bug: `App.__getattr__` delegates unknown attributes to the controller via `getattr(self.controller, name)`. If the controller doesn't have the attribute either, `getattr` returns None (the default). This breaks `hasattr(app, 'unknown_attr')`: - hasattr() checks the instance dict first - If not found, it calls __getattr__ - __getattr__ returns None instead of raising AttributeError - hasattr() sees a non-exception result, returns True - Caller's `if not hasattr(...)` is False, never initializes the attr The fix: __getattr__ should raise AttributeError for attributes that the controller also doesn't have, so hasattr() works correctly. """ import pytest import sys import os from typing import Any ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) sys.path.insert(0, ROOT) def test_hasattr_returns_false_for_unset_attribute(mock_app: Any) -> None: """hasattr(app, 'definitely_unique_test_attr_xyz123') must return False when neither App nor controller has the attribute. This is the exact pattern that fails in render_approve_script_modal (gui_2.py:4894): `if not hasattr(app, 'foo'): app.foo = False`. """ app = mock_app # Use a unique attribute name guaranteed not to exist attr_name = "definitely_unique_test_attr_xyz123" # Assert hasattr returns False assert hasattr(app, attr_name) is False, ( f"hasattr returned True for {attr_name!r} which is not set on App " "or controller. This breaks the `if not hasattr: initialize` " "pattern in render_approve_script_modal (gui_2.py:4894)." )