Dopo un anno di sviluppo, è stata pubblicata una significativa versione del linguaggio di programmazione Python 3.11. Il nuovo ramo sarà supportato per un anno e mezzo, dopodiché per ulteriori tre anni e mezzo verranno forniti aggiornamenti per risolvere le vulnerabilità.
Contemporaneamente è iniziato il testing alpha del ramo Python 3.12 (secondo il nuovo programma di sviluppo, il lavoro su un nuovo ramo inizia cinque mesi prima del rilascio del ramo precedente e, al momento del rilascio successivo, raggiunge la fase di testing alpha). Il ramo Python 3.12 sarà in fase di release alpha per sette mesi, durante i quali verranno aggiunte nuove funzionalità e verranno corretti i bug. Successivamente, per tre mesi, si svolgerà il testing delle versioni beta, durante il quale l'aggiunta di nuove funzionalità sarà vietata e l'attenzione sarà concentrata sulla risoluzione dei bug. Gli ultimi due mesi prima del rilascio, il ramo sarà in fase di candidato per il rilascio, durante la quale verrà effettuata la finalizzazione.
Tra le novità introdotte in Python 3.11:
- È stato effettuato un lavoro significativo di ottimizzazione delle prestazioni. Il nuovo ramo include modifiche relative all'accelerazione e all'espansione inline delle chiamate di funzione, all'uso di interpreti rapidi per operazioni comuni (x+x, x*x, x-x, a[i], a[i] = z, f(arg), C(arg), o.method(), o.attr = z, *seq), oltre a ottimizzazioni sviluppate dai progetti Cinder e HotPy. A seconda del tipo di carico, c'è un aumento della velocità di esecuzione del codice dal 10% al 60%. In media, le prestazioni durante il passaggio al test suite pyperformance sono aumentate del 25%.
È stato rielaborato il meccanismo di caching del bytecode, il che ha permesso di ridurre il tempo di avvio dell'interprete del 10-15%. Gli oggetti con codice e bytecode ora vengono staticamente posizionati dall'interprete, il che ha permesso di eliminare le fasi di demarshalling del bytecode estratto dalla cache e la conversione degli oggetti con codice per la loro allocazione in memoria dinamica.
- Durante la visualizzazione della tracciatura delle chiamate nei messaggi diagnostici, è stata fornita la possibilità di mostrare informazioni sull'espressione che ha causato l'errore (in precedenza veniva evidenziata solo la riga senza dettagli su quale parte della riga abbia causato l'errore). Informazioni dettagliate sulla tracciatura possono anche essere ottenute tramite l'API e utilizzate per mappare singole istruzioni di bytecode a una posizione specifica nel codice sorgente, utilizzando il metodo codeobject.co_positions() o la funzione C API PyCode_Addr2Location(). Questa modifica semplifica notevolmente il debugging dei problemi relativi a oggetti dizionario annidati, chiamate di funzioni multiple ed espressioni aritmetiche complesse. Traceback (most recent call last): File «calculation.py», riga 54, in result = (x / y / z) * (a / b / c) ~~~~~~^~~ ZeroDivisionError: divisione per zero
- È stata aggiunta la supporto per i gruppi di eccezioni, che consente al programma di generare e gestire simultaneamente più eccezioni diverse. Per raggruppare diverse eccezioni e chiamarle insieme, sono stati introdotti nuovi tipi di eccezioni ExceptionGroup e BaseExceptionGroup, e per estrarre singole eccezioni da un gruppo è stata aggiunta l'espressione «except*».
- Nella classe BaseException è stato aggiunto il metodo add_note(), che consente di allegare una nota testuale all'eccezione, ad esempio, aggiungendo informazioni di contesto non disponibili durante la generazione dell'eccezione.
- È stato aggiunto un tipo speciale Self, che rappresenta la classe chiusa corrente. Self può essere utilizzato per annotare metodi che restituiscono un'istanza della propria classe in modo più semplice rispetto all'uso di TypeVar. class MyLock: def __enter__(self) -> Self: self.lock() return self
- È stato aggiunto un tipo speciale LiteralString, che può includere solo stringhe letterali compatibili con il tipo LiteralString (ossia stringhe normali e stringhe con tipo LiteralString, ma non stringhe arbitrarie e non miste con tipo str). Il tipo LiteralString può essere utilizzato per limitare il passaggio di argomenti stringa a funzioni, dove un'assegnazione arbitraria di parti di stringa potrebbe portare a vulnerabilità, ad esempio, durante la creazione di stringhe per query SQL o comandi shell. def run_query(sql: LiteralString) -> … … def caller( arbitrary_string: str, query_string: LiteralString, table_name: LiteralString, ) -> None: run_query(«SELECT * FROM students») # ok run_query(literal_string) # ok run_query(«SELECT * FROM » + literal_string) # ok run_query(arbitrary_string) # Errore run_query( # Errore f»SELECT * FROM students WHERE name = {arbitrary_string}» )
- È stato aggiunto il tipo TypeVarTuple, che consente di utilizzare generici variabili, a differenza di TypeVar che copre un numero arbitrario di tipi.
- È stato incluso nella libreria standard il modulo tomllib con funzioni per il parsing del formato TOML.
- È stata fornita la possibilità di contrassegnare singoli elementi dei dizionari tipizzati (TypedDict) con le etichette Required e NotRequired per determinare i campi obbligatori e facoltativi (per impostazione predefinita, tutti i campi dichiarati sono obbligatori se il parametro total non è impostato su False). class Movie(TypedDict): title: str year: NotRequired[int] m1: Movie = {«title»: «Black Panther», «year»: 2018} # OK m2: Movie = {«title»: «Star Wars»} # OK (il campo year è facoltativo) m3: Movie = {«year»: 2022} # Errore, campo obbligatorio title non compilato)
- È stata aggiunta alla libreria asyncio la classe TaskGroup con l'implementazione di un gestore di contesto asincrono che attende il completamento di un gruppo di attività. Aggiungere attività al gruppo avviene tramite il metodo create_task(). async def main(): async with asyncio.TaskGroup() as tg: task1 = tg.create_task(some_coro(…)) task2 = tg.create_task(another_coro(…)) print(«Entrambe le attività sono ora completate.»)
- È stato aggiunto il decoratore per classi, metodi e funzioni @dataclass_transform, il cui utilizzo permette al sistema di controllo dei tipi statici di trattare l'oggetto come se si utilizzasse il decoratore @dataclasses.dataclass. Nell'esempio seguente, la classe CustomerModel sarà verificata in modo analogo a una classe decorata con @dataclasses.dataclass, ossia come avente un metodo __init__ che consente le variabili id e name. @dataclass_transform() class ModelBase: … class CustomerModel(ModelBase): id: int name: str
- Nelle espressioni regolari è stata aggiunta la possibilità di utilizzare la raggruppamento atomico ((?>(...)) e i quantificatori possessivi (*+, ++, ?+, {m,n}+).
- È stata aggiunta l'opzione della riga di comando «-P» e la variabile d'ambiente PYTHONSAFEPATH per disabilitare il collegamento automatico a sys.path di percorsi di file potenzialmente non sicuri.
- L'utilità py.exe per la piattaforma Windows è stata notevolmente migliorata, con supporto per la sintassi «-V:/» oltre a «-.».
- Molti macro nell'API C sono stati convertiti in funzioni inline normali o statiche.
- I moduli uu, cgi, pipes, crypt, aifc, chunk, msilib, telnetlib, audioop, nis, sndhdr, imghdr, nntplib, spwd, xdrlib, cgitb, mailcap, ossaudiodev e sunau sono stati dichiarati obsoleti e verranno rimossi nella versione Python 3.13. Le funzioni PyUnicode_Encode* sono state rimosse.
Fonte: opennet.ru
