[Python] doctest con funzioni che aprono files

Giovanni Marco Dall'Olio dalloliogm a gmail.com
Ven 28 Nov 2008 17:59:47 CET


2008/11/26 Daniele Varrazzo <piro a develer.com>:
>
>
> On Wed, 26 Nov 2008 19:11:24 +0100, "Giovanni Marco Dall'Olio"
> <dalloliogm a gmail.com> wrote:
>
>>> Tu sei sicuro che una docstring nella quale hai buttato dentro tutto il
>>> codice boilerplate per fargli aprire un file temporaneo abbia ancora una
>>> qualche utilità come docstring?
>>
>> Per alcune cose che devo fare, si.
>> Sto contribuendo al progetto biopython, una collezione di moduli per
>> la bioinformatica in python.
>
> Lo conosco, ho studiato bioinformatica per la tesi di laurea e ci ho
> lavorato a Siena per 2-3 annetti :)

Davvero? Con biopython specificamente?
Se ti va di dare qualche contributo nella ml, e' ben accetto :)

>> Visto che questi moduli devono essere utilizzati da terze parti,
>> aggiungere un esempio del file di input nel doctest e' una cosa
>> utilissima.
>> In questo modo, un utente che si ritrovi a riutilizzare le mie
>> librerie, potra' avere una idea chiara del formato per il quale un
>> modulo e' stato scritto (pensa soprattutto a quando devi parsare un
>> particolare formato di testo).
>
> Ok, quindi nella docstring metti anche il formato del file di testo da
> parsare.

Ci sono diversi formati con nomi simili e a volte anche omonimi, e
aggiungere un esempio del formato di input nella doc permette agli
utenti di non rischiare di utilizzare il parser sbagliato, che e' una
cosa buona.

Inoltre e' un grosso aiuto durante lo sviluppo del modulo.


>> Certamente, anche se devo ammettere di non aver usato molto unittest.
>
> Questo mi spiega ancora meglio come mai usi così estensivamente doctest e
> non unittest :)

ufff grazie mille per le risposte, pero' per favore, lasciamo i
dibattiti doctest vs unittest ad altre discussioni.
Non ho detto che uso esclusivamente uno dei due, ne' che ho intenzione
di farlo; solo mi serve sapere un dettaglio dell'implementazione.

> Secondo me hai sbagliato in partenza a far sì che le tue funzioni di
> parsing accettino un filename in input. Se le tue funzioni accettassero un
> file object invece avresti i seguenti vantaggi (i primi che mi vengono in
> mente):


Si, pero' a volte e' necessario scrivere delle funzioni che accettino
nomi di file.
Per esempio, ci sono dei moduli che chiamano programmi esterni (io
sono contrario, perche' lo farei in altra maniera): quello che ho
fatto fino ad adesso e' aggiungere un doctest per illustrare il
formato del file, crearlo con NamedTemporaryFile, e passare
NamedTempFile.name.

Un'altra obiezione e' che e' meno chiaro passare un oggetto di tipo
file gia' aperto. Lavoro a fianco di persone che conoscono poco di
python, e se apro il file in una funzione e lo parso in un'altra, si
perdono, non capiscono il perche'.

Altrimenti in linea di massima sarei d'accordo con te, mi sembra che
sia anche la linea di condotta utilizzata in biopython.


>  - potresti parsare stdin (e quindi mettere una serie di script in pipe).
>   Per esempio parsare un file preso da internet con "curl URL | python
> parser.py"
>
>  - potresti usare la doctest con lo StringIO :)

Si, per adesso ho fatto cosi'.
Creare un oggetto file-like con StringIO richiede solo 2 passaggi, e
quindi e' molto comodo usarlo con doctest.
Il problema e' che non posso utilizzarlo con funzioni che aprono il
file al loro interno.
Se solo StringIO avesse un attributo come 'name' di NamedTempFile, o
anche solo una maniera di passarne un riferimento, sarebbe molto piu'
comodo.


> Lo svantaggio nell'aprire un file normale è minimo: anzichè fare
> parse(filename) farai parse(open(filename)).
>
> È anche facile fare una funzione che, in caso di stringa, la "apra"
> assumendo un filename ("if isinstance(file, basestring): file =
> open(file)"), ma poi vorrai anche distinguere una url per aprirla con
> urllib, ma a volte la stringa contiene i dati... la cosa migliore per fare
> un parser generico credo sia accettare solo un file object in input e
> lasciare che sia il cliente della funzione ad accontentarla (mi sembra una
> corretta divisione delle responsibilità).

Si, anche questo si puo' fare... per fortuna non credo che avro' a che
fare con oggetti urllib e simili.
Grazie mille per le risposte :)

p.s. avete mai notato che doctest non usa doctest per la sua
documentazione (a parte pochi casi)? :)


> --
> Daniele Varrazzo - Develer S.r.l.
> http://www.develer.com
>



-- 

My blog on bioinformatics (now in English): http://bioinfoblog.it


Maggiori informazioni sulla lista Python