3.14.6 Classi derivate da unpickler

In modo predefinito, la deserializzazione importerà qualsiasi classe trovata nei dati serializzati. Potete controllare esattamente ciò che viene deserializzato e ciò che viene invocato, personalizzando un proprio unpickler. Sfortunatamente, questa operazione risulterà diversa in funzione del fatto che si utilizzi il modulo pickle oppure cPickle.3.10Nel modulo pickle, si deve derivare una sotto classe da Unpickler, ridefinendo il metodo load_global(). Tale metodo dovrebbe leggere due linee dal flusso di dati serializzati, in cui la prima riga sarà il nome del modulo contenente la classe, e la seconda riga sarà il nome della classe dell'istanza. Quindi cerca nella classe, possibilmente importando il modulo a cui appartiene, scovando l'attributo, e poi aggiungendo ciò che trova nello stack dell'unpickler. Successivamente, questa classe verrà assegnata all'attributo __class__ di una classe vuota, come espediente per creare magicamente un'istanza senza chiamare il metodo __init__() proprio della classe. Il vostro lavoro (sta a voi decidere di accettarlo o meno), sarebbe quello di avere un metodo load_global() che inserisca nello stack dell'unpickler una versione conosciuta come sicura di qualsiasi classe si giudichi sicura da deserializzare. Spetta a voi scrivere una tale classe. Oppure potreste sollevare un errore nel caso desideraste disabilitare del tutto l'unpickling di istanze. Se questo suona come un escamotage, avete ragione. Per questo scopo fate riferimento al codice sorgente.

Le cose sono un po' più pulite con cPickle, ma non di molto. Per controllare ciò che viene deserializzato, potete impostare l'attributo find_global ad una funzione oppure a None. Se il valore è None allora qualsiasi tentativo di deserializzare delle istanze solleverà un'eccezione UnpicklingError. Se invece è una funzione, allora essa dovrebbe accettare il nome di un modulo e quello di una classe e restituire il corrispondente oggetto di classe. La funzione è responsabile di ricercare la classe e di eseguire qualsiasi import necessario, e può sollevare un errore per prevenire che istanze della classe vengano deserializzate.

La morale della favola è che si dovrebbe prestare molta attenzione all'origine delle stringhe che la vostra applicazione deserializza.



Footnotes

...cPickle.3.10
Una parola d'avvertimento: i meccanismi qui descritti usano attributi interni e metodi che saranno soggetti a cambiamenti in future versioni di Python. Abbiamo intenzione di fornire, un giorno, un'interfaccia comune per controllare questi comportamenti, che lavorerà sia con pickle che con cPickle.
Vedete Circa questo documento... per informazioni su modifiche e suggerimenti.