de83909db9
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
67 lines
3.4 KiB
Python
67 lines
3.4 KiB
Python
"""Argomenti da riga di comando degli script operativi: un flag ignoto NON e' l'azione di default.
|
|
|
|
PERCHE' ESISTE (2026-09-02). Nessuno degli script di `scripts/live/` usava argparse: leggevano
|
|
`sys.argv` con `in` e `index`, quindi un flag sbagliato non era un errore — era il ramo `else`.
|
|
Costo misurato lo stesso giorno, durante una revisione: `trades_db.py --help` non ha stampato
|
|
l'uso, e' caduto in `sync()` e ha riscritto `meta.ultimo_sync`. Gli altri due sono peggio:
|
|
`journal.py --help` avrebbe scritto la pagina di oggi e una riga nel DB, `analista.py --help`
|
|
avrebbe speso una chiamata al modello e mandato un messaggio Telegram.
|
|
|
|
TRE REGOLE, e nient'altro:
|
|
1. **Nessun argparse.** Gli script hanno flag posizionali-per-nome (`--report`, `--secco`) e
|
|
flag con valore (`--giorno 2026-08-21`); argparse cambierebbe i messaggi d'errore, il
|
|
codice d'uscita e il comportamento di `--help` di 18 script che il cron gia' chiama. Qui
|
|
serve il contrario: **lasciare intatto cio' che gira** e rifiutare cio' che non e' previsto.
|
|
2. **Il cron non deve cambiare.** I flag dichiarati sono quelli che gli script gia' accettano:
|
|
`valida()` non ne aggiunge e non ne toglie (P15: una regola si prova contro il codice che
|
|
dovrebbe eseguirla). L'unica novita' e' `--help`, che prima non esisteva.
|
|
3. **Si esce PRIMA di qualunque effetto.** `valida()` va chiamata come prima istruzione del
|
|
blocco `__main__`, prima di `connect()`, prima del sync, prima della rete.
|
|
|
|
Codici d'uscita: 0 per `--help` (l'utente ha chiesto l'uso), 2 per un flag ignoto (errore d'uso,
|
|
distinto dal 1 con cui gli script segnalano un esito negativo del loro lavoro).
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
|
|
|
|
class UsoSbagliato(Exception):
|
|
"""Flag non previsto da questo script. Portato con l'elenco di cio' che e' previsto (P4)."""
|
|
|
|
|
|
def valida(nome: str, uso: str, *, flag: tuple[str, ...] = (), con_valore: tuple[str, ...] = (),
|
|
argv: list[str] | None = None, esci: bool = True) -> list[str]:
|
|
"""Controlla `argv` contro i flag dichiarati. Ritorna gli argomenti; solleva o esce se ignoti.
|
|
|
|
`flag` sono i booleani (`--quiet`), `con_valore` quelli che consumano l'argomento seguente
|
|
(`--giorno 2026-08-21`). `--help`/`-h` stampano `uso` ed escono 0. Con `esci=False` non
|
|
tocca `sys.exit` e solleva `UsoSbagliato`: e' la forma che i test usano.
|
|
"""
|
|
args = list(sys.argv[1:] if argv is None else argv)
|
|
if "--help" in args or "-h" in args:
|
|
if not esci:
|
|
return args
|
|
print(uso.strip())
|
|
raise SystemExit(0)
|
|
noti, ignoti, attesa_valore = set(flag) | set(con_valore), [], False
|
|
for a in args:
|
|
if attesa_valore: # e' il valore di un flag noto, non un flag
|
|
attesa_valore = False
|
|
continue
|
|
if not a.startswith("-"):
|
|
ignoti.append(a); continue # posizionale: nessuno di questi script ne ha
|
|
if a not in noti:
|
|
ignoti.append(a); continue
|
|
attesa_valore = a in con_valore
|
|
if attesa_valore:
|
|
ignoti.append(f"{args[-1]} (manca il valore)")
|
|
if ignoti:
|
|
msg = (f"{nome}: argomento non previsto: {', '.join(ignoti)}\n"
|
|
f" previsti: {' '.join(sorted(noti)) or '(nessuno)'}\n\n{uso.strip()}")
|
|
if not esci:
|
|
raise UsoSbagliato(msg)
|
|
print(msg, file=sys.stderr)
|
|
raise SystemExit(2)
|
|
return args
|