Logo Python su fogli sovrapposti con le scritte UTF-8 e 3.15.
Internet / La storia

Python 3.15 rende visibili due presupposti da controllare

UTF-8 diventa predefinito e le importazioni differite esplicite possono rimandare il lavoro al primo utilizzo. Compatibilità dei dati e avvio richiedono piani separati.

GeekRadarData della notizia Pubblicato 4 min di lettura

Il cambiamento più significativo di Python 3.15 potrebbe essere un file di testo che smette di aprirsi correttamente. La versione stabile, pubblicata il 9 ottobre, rende UTF-8 la codifica predefinita e introduce le importazioni differite esplicite. Un cambiamento riduce una storica fonte di differenze fra macchine; l'altro permette agli sviluppatori di decidere quali importazioni possano aspettare fino al momento in cui servono.

L'annuncio della versione contiene aggiunte più vistose, ma queste due meritano attenzione insieme. Entrambe modificano presupposti che possono restare invisibili in un test riuscito: come i byte diventano testo e quando l'importazione di un modulo ne esegue il codice. Un aggiornamento del runtime può farli emergere senza cambiare l'algoritmo principale dell'applicazione.

Il presupposto sulla codifica diventa visibile

Una codifica è l'accordo che associa i byte memorizzati ai caratteri. UTF-8 offre un modo comune di rappresentare testo in più lingue. Storicamente, i programmi Python che omettevano la codifica potevano comportarsi diversamente secondo le impostazioni locali della piattaforma. Un file gestito correttamente sulla macchina di uno sviluppatore poteva fallire o produrre caratteri errati altrove.

Come spiega la PEP 686, Python 3.15 abilita per impostazione predefinita la modalità UTF-8. Il vantaggio è una base più prevedibile. Il problema di compatibilità riguarda i dati precedenti la cui codifica reale non coincide con quella base. Cambiare l'impostazione di Python non converte il contenuto di esportazioni, registri o documenti già archiviati.

Per un file il cui formato prevede UTF-8, rendete esplicito l'accordo:

with open("catalogue.txt", encoding="utf-8") as catalogue:
    text = catalogue.read()

Conta il contratto esplicito, non quelle particolari lettere. Un vecchio file che usa realmente un'altra codifica richiede invece quella corretta. Aggiungere encoding="utf-8" ovunque senza controllare i dati sostituirebbe semplicemente un errore implicito con uno esplicito.

La PEP 686 documenta anche la disattivazione temporanea tramite PYTHONUTF8=0 e l'uso degli avvisi sulla codifica per individuare i presupposti impliciti. Disattivare la modalità può aiutare a isolare una regressione; non definisce un formato durevole per i dati scambiati fra sistemi. La soluzione mantenibile è sapere che cosa legge e scrive ogni punto di scambio.

Le importazioni differite spostano il lavoro al primo utilizzo

La PEP 810 introduce una sintassi esplicita per rimandare un'importazione. Quelle ordinarie conservano il comportamento esistente. Uno sviluppatore può invece scrivere:

lazy import json

def read_settings(raw):
    return json.loads(raw)

Qui il modulo viene caricato quando il programma ne ha bisogno per la prima volta. Può aiutare uno strumento a riga di comando i cui numerosi sottocomandi usano dipendenze diverse: chi richiama una piccola operazione non deve necessariamente pagare all'avvio il costo dei moduli impiegati soltanto da altre operazioni.

Il costo, però, si è spostato. La prima operazione che richiede la dipendenza può impiegare più tempo e un errore d'importazione può emergere più tardi nell'esecuzione. Anche il codice che dipende dagli effetti collaterali eseguiti al livello principale di un modulo richiede attenzione. Rendere indiscriminatamente differite le importazioni cambia quando si svolge il lavoro: è parte del comportamento del programma, anche quando il calcolo finale resta invariato.

Misurate il percorso effettivamente usato. Un avvio vuoto più rapido, seguito subito dallo stesso caricamento rimandato, è meno utile che evitare del tutto il caricamento in un comando frequente. Allo stesso modo, i test devono esercitare il primo utilizzo della dipendenza differita, non soltanto confermare che l'applicazione parta.

Prima il contratto, poi l'ottimizzazione

Questi cambiamenti premiano un ordine deliberato. Prima verificate che file, testo dei sottoprocessi e altri confini dei dati mantengano il significato atteso. Poi introducete importazioni differite dove un costo di avvio misurato le giustifichi. Unire le due migrazioni in un'ampia riscrittura renderebbe più difficile attribuire un errore.

Python 3.15 rientra nella nostra copertura del software open source, ma la lezione supera una singola versione: le impostazioni predefinite fanno parte dell'ambiente di un'applicazione. Renderle più coerenti può rivelare vecchie dipendenze dall'incoerenza. Codifiche esplicite aiutano a rimuoverle; importazioni differite esplicite trasformano i tempi di esecuzione in una scelta esaminabile e verificabile.