Skip to content

Instantly share code, notes, and snippets.

@ricpol
Last active September 5, 2020 13:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ricpol/2d9df82a8961bd4c61396084725ab6cc to your computer and use it in GitHub Desktop.
Save ricpol/2d9df82a8961bd4c61396084725ab6cc to your computer and use it in GitHub Desktop.
Tradurre in Italiano la documentazione di Python. Ipotesi di lavoro.

Tradurre in Italiano la documentazione di Python.

Questo documento delinea una roadmap per un progetto di traduzione della documentazione di Python. Si trova pubblicato sulla mailing list di Python.it e come Gist pubblico del suo autore (Riccardo Polignieri).

DISCLAIMER STANDARD prima di cominciare: ebbene sì, questo documento è lungo e in certe parti anche piuttosto tecnico (orrore!). Non voglio scoraggiare gli eventuali futuri collaboratori del progetto, specialmente se principianti. Se l'idea dovesse prender piede, farò una guida molto semplice su come collaborare al progetto, da traduttori. Questo documento si rivolge a chi intende discutere sulle tecniche, sugli strumenti e sul piano di lavoro che conviene adottare.

Che cosa è la documentazione di Python.

Per cominciare, chiariamo i termini del problema. La documentazione di Python, così come la conoscono tutti, è una serie di pagine html che partono da https://docs.python.org. In realtà, non è proprio così semplice.

Le pagine html.

Per cominciare, ci sono diverse release di Python: ad ogni minor release corrisponde una versione diversa della documentazione html. Per esempio, https://docs.python.org/3.7/ è la documentazione di Python 3.7, mentre https://docs.python.org/3.8/ è la documentazione di Python 3.8. Le differenze tra una versione e l'altra possono essere lievi, ma anche rilevanti in alcuni punti.

Si noti che le micro release invece non hanno versioni differenti della documentazione. Per esempio, Python 3.7.2 e Python 3.7.9 hanno la stessa documentazione. Tuttavia, questo non significa che la documentazione di Python 3.7 è stata scritta al momento della release 3.7.0 e mai più modificata. Al contrario, ogni versione viene costantemente e silenziosamente aggiornata. Quindi, se immaginate di scaricare oggi una "istantanea" della documentazione di Python 3.7.9, tra qualche giorno potreste notare delle differenze (e questo anche se nel frattempo neppure la micro release è stata incrementata).

Naturalmente, più le versioni "invecchiano" e più raramente le relative documentazioni sono modificate. Le versioni legacy di Python 3.0-3.6, per esempio, ormai sono ferme da tempo. Ma non c'è una regola fissa. Se qualcuno scopre un errore nella documentazione di Python 3.6, per dire, questa potrebbe ancora essere modificata oggi, in teoria.

I sorgenti ReStructuredText.

Una cosa importante da capire è che tutto l'insieme delle pagine html, a cui di solito ci riferiamo quando parliamo della "documentazione di Python", è in realtà solo l'output finale, quello pubblicato e visibile.

La documentazione vera, dietro le quinte, è invece un insieme di documenti di puro testo, scritti a mano in formato
ReStructuredText e poi "tradotti" automaticamente in html da Sphinx. Chi scrive (e poi successivamente modifica) la documentazione, quindi, non scrive direttamente in html, ma scrive invece in ReStructuredText. Poi ci pensa Sphinx a produrre l'output voluto.

I vantaggi di usare Sphinx sono numerosissimi. Si pensi solo alla gestione delle migliaia di link che costellano le pagine della documentazione. Facciamo un esempio pratico, per capire. Proprio all'inizio del documento "Sorting HOW TO", troviamo questa frase:

Python lists have a built-in list.sort() method ...

Il documento ReStructuredText corrispondente contiene semplicemente questo:

Python lists have a built-in :meth:list.sort method ...

Ma se invece guardiamo il sorgente html di questa frase, per esempio nella versione per Python 3.8, troviamo invece tutto questo, che è stato generato da Sphinx:

Python lists have a built-in <a class="reference internal" 
href="../library/stdtypes.html#list.sort" title="list.sort">
<code class="xref py py-meth docutils literal notranslate">
<span class="pre">list.sort()</span></code></a> method ...

Come si vede, Sphinx ne fa davvero parecchio, di lavoro dietro le quinte al posto nostro. E questo è solo un esempio minimo di tutta la fatica che ci risparmia. Senza contare che Sphinx, oltre all'output html, può anche generare quello in pdf, in epub e altro ancora.

La repository Git.

I sorgenti ReStructuredText della documentazione sono conservati insieme a tutto il resto del codice di CPython: ovvero nella repository Git pubblicata su GitHub.

Come molte repository Git, anche quella di Python presenta diversi branch, che in questo caso corrispondono alle diverse minor release. Per esempio,

Questo è il modo in cui Git consente di tenere separato il codice delle varie versioni. Si noti che la versione "di sviluppo" (in questo momento la 3.10) è semplicemente il master branch della repository. Quando uscirà Python 3.9.0, allora questo branch diventerà quello della versione stabile; dall'attuale master branch verrà ricavato un nuovo branch per la versione in pre-release (a questo punto, la 3.10); e il master branch si riferirà a questo punto alla nuova frontiera di sviluppo (3.11). E così via.

La documentazione fa semplicemente parte del codice. Ogni branch ha una sua versione della directory "doc/", che contiene la documentazione. Si noti che questa non è mantenuta in una repository separata, come invece avviene per
altri progetti.

Ogni singolo documento ReStructuredText della traduzione viene periodicamente aggiornato. A ogni aggiornamento corrisponde un commit di Git. Possiamo esaminare la storia dei commit di ogni singolo documento, in ogni branch separatamente, per vedere che cosa è stato modificato nel tempo (almeno in quel branch: non è detto che le stesse modifiche siano state riportate anche in altri branch!). Per esempio, la storia del "Socket HOW TO" per la versione di Python 3.8 si trova qui e ci dice per esempio che l'ultima modifica è stata fatta il 17 maggio 2020, come parte del commit 7a3522d. Un commit può modificare più di un file. Nel nostro "Socket HOW TO", quel commit ha cambiato semplicemente una parola.

Con un poco di pratica dell'interfaccia web di GitHub, possiamo imparare a passare da un branch all'altro, navigare tra i documenti, vedere la storia dei commit, esaminare le modifiche apportate da un singolo commit e così via. Naturalmente, se sappiamo usare Git dalla riga di comando della nostra shell, possiamo fare tutto questo anche in modo più rapido ed efficace.

Che cosa vuol dire "tradurre la documentazione".

Come si sarà capito a questo punto, non esiste una documentazione di Python, per almeno due motivi:

  • perché in realtà c'è una documentazione diversa per ogni release;
  • perché ogni singola documentazione viene continuamente modificata nel tempo.

Ha importanza tutto questo?

Purtroppo sì, un'importanza fondamentale. Python è un linguaggio che evolve, e il Python di qualche anno fa è diverso da quello di oggi. E questo vale anche per la sua documentazione. Ora, supponiamo di avere una bacchetta magica e di riuscire a "scattare un'istantanea" di una versione qualsiasi (diciamo, la 3.8) della documentazione oggi, e tradurla istantaneamente. Questo sarebbe certo un lavoro enorme. Ma a chi servirebbe? e quanto? e per quanto tempo?

  • Non tutti, oggi, usano Python 3.8. Chi usa ancora Python 3.7 avrà una documentazione... leggermente diversa.
  • Tra qualche mese uscirà Python 3.9. E tra un anno, Python 3.10. Chi userà le future versioni avrà una documentazione sempre più datata nel tempo.
  • Anche Python 3.8 cambia, sia pure leggermente, nel tempo; e così la sua documentazione. Anche se usate Python 3.8, come potete essere sicuri di quanto è aggiornata la traduzione che state leggendo?

Ora, si potrebbe dire che, in fondo, bisogna sapersi accontentare. Va già bene che la traduzione è stata fatta, no? Se anche è leggermente diversa dall'originale, che cosa vuoi che sia.

Purtroppo non è così. La prova più chiara di questo è che Python.it ha già fatto, in passato, un gigantesco sforzo di traduzione della documentazione. E dopo qualche mese, era diventato leggermente obsoleto. E dopo qualche anno, era diventato molto obsoleto. E dopo qualche anno ancora, è diventato così obsoleto che è stato messo off-line e archiviato.

La cosa che rammarica di più, ripensandoci, è che si trattava davvero di un eccellente sforzo di traduzione. Purtroppo però non era forse stato pensato, fin dall'inizio, con una chiara strategia in mente su come mantenerlo aggiornato nel tempo.

Che cosa non va bene.

Quindi, cominciamo col dire che cosa assolutamente non bisognerebbe fare.

  1. Non si può tradurre l'html. Le pagine html della documentazione non hanno in realtà niente a che vedere con la documentazione! Sono solo degli artefatti generati automaticamente da Sphinx. Includono molti elementi che hanno senso solo all'interno dei template di Sphinx, e in generale non importa a nessuno che cosa contengono. Se domani cambiasse la versione di Sphinx in uso, tutte le pagine html potrebbero cambiare di colpo senza che nemmeno una parola della documentazione "vera" fosse modificata.

  2. Non si può tradurre "una versione" della documentazione. Anche se si decidesse, per dire, di tradurre la versione 3.9 (e supponendo di ignorare che, in realtà, non esiste neppure una "versione 3.9" ben definita, come abbiamo visto), questo comunque non servirebbe in prospettiva. Ben presto la traduzione invecchierebbe e non ci sarebbe modo di aggiornarla, senza introdurre una forma di version control.

Che cosa va bene invece.

  1. Tradurre i sorgenti rst. Perché quelli sono la vera documentazione. Per esempio, i link espressi in formato ReStructuredText vengono tradotti da Sphinx automaticamente in link html, tenendo conto dei template, della versione a cui si riferiscono e così via. Inoltre solo i sorgenti rst sono "versionati", ovvero messi "sotto Git". Questo consente di conoscere sempre quanto è aggiornato il file originale che si sta traducendo, e quindi anche quanto è aggiornata la traduzione di quel file.

  2. Tradurre file versionati. I file originali della documentazione sono versionati (fanno parte della repository Git di Python). Questo consente di sapere facilmente quando viene effettuato anche il minimo cambiamento. I file tradotti dovrebbero essere "ancorati" a un preciso commit dei corrispondenti originali, ed essere essi stessi versionati di conseguenza. Solo così si può sapere con precisione quanto è recente la traduzione di ogni singolo file.

  3. Separare traduzione e pubblicazione. Non è necessario tradurre immediatamente ogni singola modifica che viene fatta nell'originale. Uno dei vantaggi del versionamento è che si sa sempre con precisione quanto è aggiornata la traduzione pubblicata di un file. Si può quindi anche lasciare indietro la traduzione per un lungo periodo, perché è facile in qualsiasi momento fare un diff degli aggiornamenti che l'originale ha subito nel frattempo.

La traduzione del Tutorial come esempio di soluzione possibile.

La traduzione che ho fatto recentemente del Tutorial di Python può essere presa come proof of concept della procedura che sarebbe conveniente adottare.

Gli originali tradotti sono ospitati in una repository Git e sono pubblicati su ReadTheDocs.

La repository contiene 4 branch, che rispecchiano il Tutorial di altrettante versioni di Python: la 3.7 (legacy), 3.8 (attuale), 3.9 (in pre-release) e 3.10 (di sviluppo).

Parallelamente, ReadTheDocs consente di selezionare l'output html (e pdf, ed epub) della versione desiderata. In realtà tutto il processo di pubblicazione è automatizzato, grazie a Sphinx (che costruisce l'output), GitHub (che mette a disposizione gli hook necessari per avviare il processo) e ReadTheDocs (che ospita il risultato). In pratica, qualsiasi commit fatto sulla repository innesca un aggiornamento automatico del contenuto pubblicato.

Questa organizzazione permette di concentrarsi sull'unica cosa che importa davvero, ossia tradurre gli originali. Tutto il resto è automatizzato. La parte più difficile consiste nel tener traccia dei successivi commit che vengono fatti sull'originale. Ho predisposto alcuni alert automatici con GitHub File Watcher per questo, ma in realtà un'ispezione manuale periodica della history della repository originale è più che sufficiente.

Naturalmente non sono obbligato a "marcare stretto" tutti i cambiamenti. Posso "lasciar correre" l'originale qualche commit in avanti, e poi raggiungerlo in una volta sola. Molti commit, a dire il vero, sono delle correzioni di grammatica nell'originale che non hanno conseguenze sulla traduzione.

Ancora una volta va sottolineato l'enorme lavoro che fa Sphinx dietro le quinte per semplificare le cose. Per esempio, di nuovo, i link: il problema è che nel Tutorial molti link rimandano a pagine dello stesso Tutorial (tradotte, quindi); la maggior parte tuttavia rimanda ad altre pagine della documentazione (non tradotte). Se dovessi tradurre i file html di output, dovrei discriminare caso per caso, inserendo a mano il link corretto. Ma in realtà mi basta invece tradurre gli originali rst, e Sphinx si occupa di creare il link giusto di volta in volta (grazie all'estensione InterSphinx), verso le mie pagine oppure verso quelle della documentazione originale.

Infine, la mia scelta di seguire 4 branch è arbitraria: si tratta delle versioni che ritengo più utili mantenere aggiornate. Ma niente mi impedirebbe, per esempio, di creare un branch anche per la versione 3.6. All'inverso, in futuro probabilmente smetterò di seguire il branch della versione 3.7, e semplicemente non lo aggiornerò più. Questo è senz'altro possibile: basta smettere di fare commit su quel branch, e la traduzione corrispondente resterà ferma (e invecchierà un poco, probabilmente). Se in futuro poi dovessi cambiare idea, potrei riprendere ad aggiornare quel branch in ogni momento. Infatti ogni branch della mia repository è sincronizzato con il branch corrispondente della repository originale.

Architettura del progetto di traduzione.

Quello che propongo è in sostanza un ampliamento della mia repository GitHub, che attualmente contiene solo il Tutorial.

La mia repository servirebbe come "copia di lavoro", anche per integrare gli eventuali contributi di traduttori volenterosi. La "repository ufficiale" potrebbe essere un clone ospitato sul GitHub di Python.it, che farebbe periodicamente pull dalla mia. Dalla repository ufficiale potrebbero essere impostati degli hook per pubblicare automaticamente l'output di Sphinx sul sito di Python.it, se possibile. Nella peggiore delle ipotesi, se non si può impostare un workflow automatico per la pubblicazione, si potrà comunque produrre l'output di Sphinx e aggiornarlo manualmente.

Francamente, la cosa migliore sarebbe in ogni caso lasciare a ReadTheDocs il compito di fare il lavoro di pubblicazione. Se si desidera pubblicare su un sotto-dominio di Python.it (docs.python.it, per dire), ReadTheDocs consente anche di usare dei custom domain.

Quali "versioni" tradurre.

Come ho detto, non esistono "versioni" della documentazione, ma piuttosto dei branch separati nella repository originale. Ogni branch viene aggiornato indipendentemente (anche se in pratica, molti commit vengono copiati
in diversi branch a colpi di cherry-picking... ma questo non ci riguarda).

Una "traduzione" consiste idealmente nello scegliere un branch, tradurre i suoi documenti, e poi seguire passo-passo i commit successivi nell'originale e aggiornare di conseguenza anche la traduzione. Il progetto complessivo può contenere più "traduzioni", ovvero seguire più branch. Per esempio, attualmente il mio Tutorial tradotto segue 4 branch.

Quali e quanti branch occorre seguire?, ovvero quante "traduzioni" bisogna fare? Qui si possono scegliere diverse strade.

Una possibilità è quella di tradurre (e mantenere aggiornato) il master branch della repository originale (che attualmente punta a Python 3.10). In questo modo è facile tradurre la documentazione nella sua versione "più aggiornata possibile". Ogni volta che il master branch diventa una "versione concreta", ovvero da questo viene derivato un topic branch per la versione, mentre il master sposta più in avanti l'orizzonte dello sviluppo, a noi basterà fare lo stesso. Avremo così il topic branch della versione specifica, e inoltre continueremo a seguire il master. A seconda delle possibilità, potremo a quel punto scegliere se mantenere aggiornati entrambi, oppure continuare ad aggiornare sempre e solo il master.

Non è necessario aspettare che il master "diventi naturalmente" un topic. Per esempio, il mio modo di tradurre il tutorial è stato questo:

  • prima ho "congelato" il master a un determinato commit e ho tradotto questa "istantanea";
  • poi ho verificato se nel frattempo al master non erano stati fatti nuovi commit, e ho aggiornato;
  • poi ho "congelato" il branch della versione 3.8, sempre segnandomi il commit relativo, e ho fatto un diff, file per file, con il master. In questo modo ho verificato in che punti le due versioni erano diverse, file per file, e ho modificato la traduzione di conseguenza, ottenendo quindi il mio branch 3.8;
  • ho verificato se nel frattempo nel branch 3.8 non erano stati fatti nuovi commit, e ho aggiornato;
  • poi ho ripetuto lo stesso procedimento per i branch delle versioni 3.7 e 3.9.

In realtà è stato un lavoro piuttosto veloce perché, in genere, i cambiamenti tra un branch e l'altro non sono molti. Un certo numero di file è identico in tutte le versioni.

Un'altra possibilità, invece di cominciare dal master ed eventualmente poi derivare i topic delle singole versioni (come ho fatto io per il Tutorial), è piuttosto di cominciare da un topic e fare il percorso inverso:

  • si "congela" lo stato attuale della documentazione di Python 3.8, e lo si traduce;
  • si aggiorna quando serve;
  • quando viene rilasciata la versione successiva di Python (3.9), si apre un nuovo branch, si fa un diff file per file, e si traducono le differenze;
  • a questo punto si continua a mantenere aggiornata la versione 3.9...
  • ...e volendo anche la 3.8; oppure si abbandona questa al suo destino.

Quali "versioni" pubblicare.

Dipende dalla piattaforma scelta per la pubblicazione. ReadTheDocs consente di mantenere pubblicate più versioni contemporaneamente senza problemi (corrispondono a più branch della repository). Se non si vuole usare ReadTheDocs, è forse più facile mantenere pubblicata solo la versione "stabile" più recente (oggi, la 3.8).

Che cosa dovrebbe fare il collaboratore/traduttore.

Se chi vuole collaborare ha familiarità con Git/GitHub, allora potrà seguire il normale flusso di lavoro di GitHub:

  • aprire una issue per segnalare che intende occuparsi della traduzione di un documento;
  • clonare la repository, aprire un topic branch, tradurre e fare push;
  • aprire una pull request per invitare ad accogliere la sua traduzione.

Se si tratta di una traduzione nuova (ovvero, un documento che non era ancora mai stato tradotto), allora la pull request andrà fatta verso il branch della versione tradotta: se si traduce la versione 3.8 del documento, allora occorre chiedere l'integrazione verso quel branch della repository, e così via.

Anche chi non ha familiarità con Git può comunque collaborare. In questo caso, si dovrebbe segnalare il proprio interesse aprendo una issue; si riceverebbe il documento ReStructuredText da tradurre; lo si rimanderebbe indietro tradotto.

Strumenti e regole per tradurre.

Chi traduce dovrebbe avere comunque un minimo di competenza nell'uso di un editor di testo (non possiamo accettare che si usi Word!); occorre fare attenzione all'encoding utf-8; occorre avere un minimo di competenza con i documenti ReStructuredText (anche se non è necessario uno studio approfondito).

In particolare, il documento ReStructuredText va tradotto lasciando inalterati i link nell'originale, e rispettando alcune convenzioni.

Ci saranno poi alcuni protocolli interni al progetto: per esempio, ogni file dovrà riportare il nome del traduttore e dei successivi revisori; un chiaro riferimento alla versione del documento originale (id del commit); etc.

Inoltre dovrebbero esserci delle linee guida di stile da rispettare, etc. Resta poi fondamentale chiarire che i traduttori devono rispettare la licenza d'uso del progetto (MIT o equivalente).

Tutto questo sarà formalizzato in una piccola "guida per il traduttore".

Che cosa dovrebbe fare il maintainer della repository.

In primo luogo, integrare le traduzioni fatte dai collaboratori, che arrivino sotto forma di pull request o altro.

Se i collaboratori non vorranno/sapranno occuparsi del mantenimento di diverse versioni alternative del documento (come prevedibile), questo sarà compito del maintainer.

Allo stesso modo, è prevedibile che sarà il maintainer ad apportare i piccoli aggiornamenti di traduzione necessari nel tempo, per mantenersi in pari con l'originale.

Occorre poi creare e mantenere una serie di documenti di corredo della repository: un elenco dei collaboratori, delle traduzioni più importanti ancora da fare, etc.; una guida per i collaboratori; e così via.

Che cosa fare adesso.

Intanto, questo documento è aperto alla discussione, con l'avvertenza che per quanto mi riguarda accetterò esclusivamente contributi migliorativi. Rispetto senz'altro ogni possibile "compromesso al ribasso", ma non sono interessato a parteciparvi. Metto a disposizione il lavoro che ho già fatto, e che del resto è sempre stato a disposizione: tutta la repository è liberamente accessibile e pubblicata con licenza MIT. Metto inoltre sul tavolo la mia disponibilità a coordinare il progetto e occuparmi della gestione tecnica della repository.

Dal punto di vista tecnico, credo che la cosa più semplice sia ampliare lo scopo della mia repository che attualmente ospita la sola traduzione del Tutorial, e creare un "clone ufficiale" di proprietà di Python.it. Restano da concordare le modalità di pubblicazione del lavoro su Python.it, a partire dagli spunti che ho fornito qui sopra.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment