un flag sconosciuto non e' l'azione di default: guardia su 18 script, indice USDE orario, pulizia
MISURATO oggi durante la revisione: `trades_db.py --help` non stampava l'uso, cadeva in sync() e riscriveva meta.ultimo_sync. Nessuno dei 18 script di scripts/live/ usava argparse: un flag sbagliato era il ramo else. Su journal.py avrebbe scritto pagina e riga di DB, su analista.py avrebbe speso una chiamata al modello e mandato un Telegram. - src/live/cli.valida: prima istruzione di ogni __main__, prima di connect()/sync/rete. --help -> 0 con l'uso; flag ignoto, valore mancante o posizionale -> 2 con l'elenco dei previsti (P4). NIENTE argparse: cambierebbe messaggi, codici d'uscita e --help di script che il cron gia' chiama. - 18 script cablati (i 3 che scrivono + 14 + cc01), flag invariati. - tests/test_cli_flag.py (30): elenco DERIVATO dalla cartella (P1), valida come prima istruzione, uso che documenta i flag, e i flag che il CRON usa davvero restano accettati (P15/P16); end-to-end su --help e flag ignoto con trades.db non toccato (M15). Verificato a mano: monitor_health --quiet, trades_db --sync --quiet, book_execute dry-run. Debito §5.15, primo passo: balance_watch (orario) registra `usde_usdc` a ogni campione — None con la ragione se illeggibile, mai 1,0. Il cablaggio nel bound quando la serie ha storia. Pulizia dalla revisione: tests/helpers.carica_script al posto della 15a copia del loader importlib (5 file del libro live); il fill di prova via upsert_fills invece di un INSERT che lasciava verified NULL; asserzioni non ancorate al padding; movimenti_capitale accetta le righe gia' lette (una SELECT invece di due ai due lati di una scrittura del cron). Test 910 verdi (+52). Diario 2026-09-02c. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XDJsH3iDSaBns3ccpPBwiu
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
"""Utilita' condivise dei test. `tests/` e' su sys.path (c'e' un conftest), quindi si importa
|
||||
con `from helpers import carica_script`.
|
||||
|
||||
PERCHE' ESISTE (2026-09-02). `scripts/` non e' un package importabile per nome, quindi ogni test
|
||||
che tocca uno script si caricava il modulo a mano con `importlib.util.spec_from_file_location`:
|
||||
**15 copie della stessa dozzina di righe**, con nomi di modulo diversi per lo stesso file e
|
||||
differenze silenziose (chi registra in `sys.modules` e chi no — e chi non lo fa rompe `pickle`,
|
||||
`dataclasses` e i decoratori che risolvono per nome). Una funzione sola, con la registrazione
|
||||
fatta sempre.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def carica_script(rel: str, nome: str | None = None):
|
||||
"""Carica per PERCORSO uno script del repo (es. "scripts/live/trades_db.py").
|
||||
|
||||
`nome` e' il nome sotto cui il modulo viene registrato in `sys.modules`; il default e' il
|
||||
nome del file. Registrare PRIMA di eseguire e' voluto: un modulo che si auto-importa o usa
|
||||
`dataclasses` durante l'esecuzione deve trovarsi.
|
||||
"""
|
||||
p = (ROOT / rel).resolve()
|
||||
assert p.exists(), f"script inesistente: {rel}"
|
||||
nome = nome or p.stem
|
||||
spec = importlib.util.spec_from_file_location(nome, p)
|
||||
mod = importlib.util.module_from_spec(spec)
|
||||
sys.modules[nome] = mod
|
||||
spec.loader.exec_module(mod)
|
||||
return mod
|
||||
Reference in New Issue
Block a user