# Modifica Lazy Initialization per theGrifo1553 ## Problema Originale Prima della modifica, `theGrifo1553` veniva istanziato immediatamente all'import del modulo `leo_grifo_1553`: ```python # VECCHIO CODICE (problematico) theGrifo1553 = GrifoInstrumentInterface(0.2) ``` **Conseguenze:** - La connessione hardware 1553 avveniva all'import, anche in modalità `--simulate` - Il mock doveva sostituire `sys.modules` PRIMA che il test importasse i moduli - Impossibile importare lo script senza hardware disponibile - Fallimento import se `PlatformSimulator/bin` non nel path ## Soluzione Implementata Introdotto un **lazy proxy** (`_LazyGrifoProxy`) che ritarda la creazione dell'istanza reale fino al primo utilizzo: ```python # NUOVO CODICE (lazy) class _LazyGrifoProxy: """Proxy that lazily constructs GrifoInstrumentInterface on first use.""" def __init__(self, timeout: float = 0.2): self._timeout = timeout self._instance = None def _ensure(self): """Initialize only when needed.""" if self._instance is None: self._instance = GrifoInstrumentInterface(self._timeout) def __getattr__(self, item): """Delegate to real instance after ensuring it exists.""" # Support hasattr() without initialization for known methods known_methods = ['check', 'get', 'set', 'getInterface', 'run'] if item in known_methods and self._instance is None: def lazy_method(*args, **kwargs): self._ensure() return getattr(self._instance, item)(*args, **kwargs) return lazy_method self._ensure() return getattr(self._instance, item) theGrifo1553 = _LazyGrifoProxy(0.2) ``` ## Vantaggi ### 1. Compatibilità Totale con Modalità Simulazione - ✅ Il mock può sostituire `sys.modules['leo_grifo_1553']` DOPO l'import iniziale - ✅ Nessuna connessione hardware tentata finché non si usa `--simulate` - ✅ Import sicuro anche senza `PlatformSimulator/bin` nel path ### 2. Compatibilità Totale con Target Reale - ✅ Primo accesso a metodo/attributo → istanza reale creata automaticamente - ✅ API identica: `check()`, `get()`, `set()`, `getInterface()`, `run()` - ✅ Passaggio come parametro funziona: `check(theGrifo1553, ...)` - ✅ `hasattr()` supportato: il mock usa `hasattr()` per controlli ### 3. Trasparenza Totale Il proxy è completamente trasparente per il codice esistente: - Non richiede modifiche a `GRIFO_M_PBIT.py` - Non richiede modifiche a `test_common_function.py` - Non richiede modifiche a `GRIFO_M_PBIT_mock.py` ## Verifica sul Target Reale ### Test 1: Verifica Import Lazy Esegui lo script di test per verificare che il proxy funzioni: ```powershell cd TestEnvironment\scripts python test_lazy_proxy.py ``` **Output atteso:** ``` ✓ Proxy is lazy - real instance not yet created ✓ hasattr() checks pass without initialization ✓ Mock replacement works correctly ALL TESTS PASSED ✓ ``` ### Test 2: Esecuzione sul Target Reale (Senza --simulate) **Pre-requisiti:** - Hardware 1553 connesso e funzionante - `PlatformSimulator/bin` nel PYTHONPATH o ambiente configurato - Modulo `interpreter` disponibile e funzionante **Comando:** ```powershell cd TestEnvironment\scripts python GRIFO_M_PBIT.py ``` **Comportamento atteso:** 1. Import dello script: **SUCCESSO** (nessuna connessione hardware ancora) 2. Chiamata a `theGrifo1553.getInterface()` in `test_proc()`: **Qui avviene la connessione** 3. Prima chiamata `check(theGrifo1553, ...)`: proxy delega all'istanza reale 4. Test procede normalmente come prima della modifica **Verifica connessione lazy:** Aggiungi temporaneamente log all'inizio di `test_proc()`: ```python def test_proc(): import logging logging.info(f"theGrifo1553 prima dell'uso: {repr(theGrifo1553)}") interface = theGrifo1553.getInterface() # <- QUI avviene la connessione logging.info(f"theGrifo1553 dopo getInterface(): {repr(theGrifo1553)}") ``` **Output atteso nel log:** ``` theGrifo1553 prima dell'uso: theGrifo1553 dopo getInterface(): ``` ### Test 3: Esecuzione in Simulazione (Con --simulate) **Comando:** ```powershell python GRIFO_M_PBIT.py --simulate ``` **Comportamento atteso:** 1. Import dello script: **SUCCESSO** 2. Rilevamento flag `--simulate`: import di `GRIFO_M_PBIT_mock` 3. Mock sostituisce `sys.modules['leo_grifo_1553']` con modulo fake 4. Proxy originale **NON viene mai inizializzato** (nessuna connessione hardware) 5. Tutte le chiamate vanno al mock, test procede in simulazione ## Compatibilità Verificata ✅ **Modulo leo_grifo_1553.py** - Import sicuro anche senza hardware - Lazy initialization funzionante - API identica per codice esistente ✅ **Script GRIFO_M_PBIT.py** - Nessuna modifica necessaria - Funziona con e senza `--simulate` - Check/get/set funzionano identicamente ✅ **Mock GRIFO_M_PBIT_mock.py** - Sostituisce `sys.modules` correttamente - `hasattr()` checks funzionano - Nessuna inizializzazione hardware in simulate ✅ **Helper test_common_function.py** - `check(theGrifo1553, ...)` funziona - Passaggio proxy come parametro OK - Nessuna modifica necessaria ## Risoluzione Problemi ### Problema: "AttributeError: 'GrifoInstrumentInterface' object has no attribute 'xyz'" **Causa:** Metodo/attributo non esiste nell'interfaccia reale. **Soluzione:** Verifica nome metodo corretto. I metodi supportati dal proxy sono: - `check(expected, msg, field, **kwargs)` - `get(msg, field, **kwargs)` - `set(value, msg, field, **kwargs)` - `getInterface()` → ritorna oggetto `grifo_1553` nativo - `run(enable: bool)` ### Problema: "ImportError: No module named 'interpreter'" **Causa:** Ambiente non configurato per hardware reale. **Soluzione:** Esegui con uno di questi metodi: 1. **Wrapper Python:** `python python_simulate_wrapper.py` (solo simulate) 2. **Batch Production:** Usa `run.bat` o configura PYTHONPATH manualmente 3. **Modalità Simulate:** Aggiungi flag `--simulate` (non richiede interpreter) ### Problema: "Connessione hardware avviene all'import" **Causa:** Il proxy potrebbe non essere stato applicato correttamente. **Soluzione:** 1. Verifica che `leo_grifo_1553.py` contenga `_LazyGrifoProxy` 2. Verifica che `theGrifo1553 = _LazyGrifoProxy(0.2)` sia l'ultima riga del file 3. Esegui `test_lazy_proxy.py` per verificare il comportamento ## File Modificati - `TestEnvironment/env/leo_grifo_1553.py` - Aggiunto `_LazyGrifoProxy` (linee ~140-190) - `TestEnvironment/scripts/test_lazy_proxy.py` - Script di test nuovo (creato) ## File NON Modificati (compatibilità preservata) - `TestEnvironment/scripts/GRIFO_M_PBIT.py` - Nessuna modifica necessaria - `TestEnvironment/scripts/GRIFO_M_PBIT_mock.py` - Nessuna modifica necessaria - `TestEnvironment/env/test_common_function.py` - Nessuna modifica necessaria - `TestEnvironment/env/leo_grifo_common.py` - Nessuna modifica necessaria ## Conclusioni La modifica garantisce: - ✅ **100% compatibilità con codice esistente** (nessuna modifica ai test) - ✅ **Target reale funziona identicamente** (connessione lazy al primo uso) - ✅ **Simulazione funziona correttamente** (mock sostituisce prima dell'init) - ✅ **Import sicuro** (no hardware all'import) - ✅ **Trasparenza totale** (API identica per utente finale) Puoi eseguire sul target reale con sicurezza: il comportamento è identico, solo la temporizzazione della connessione hardware è cambiata (da import-time a first-use-time).