[Docs] Tradurre in Italiano la documentazione di Python. Una proposta.

Riccardo Polignieri ric.pol a libero.it
Sab 5 Set 2020 21:48:33 CEST


# 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](https://gist.github.com/ricpol/2d9df82a8961bd4c61396084725ab6cc)
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](https://docutils.sourceforge.io/rst.html) e poi "tradotti"
automaticamente in html da [Sphinx](https://www.sphinx-doc.org). 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](https://docs.python.org/3.8/howto/sorting.html),
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](https://github.com/python/cpython).

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

- [il branch di Python 3.8](https://github.com/python/cpython/tree/3.8),
- [il branch di Python 3.9](https://github.com/python/cpython/tree/3.9),
- e [quello di Python 3.10](https://github.com/python/cpython/tree/master)

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](https://github.com/python/cpython/commits/3.8/Doc/howto/sockets.rst)
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](https://github.com/ricpol/pytutorial-it) e sono pubblicati
[su ReadTheDocs](https://pytutorial-it.readthedocs.io).

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](https://app.github-file-watcher.com/) 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](https://docs.readthedocs.io/en/stable/custom_domains.html).

### 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.




Maggiori informazioni sulla lista Docs