01: YAML e la frattura tra 1.1 e 1.2
Indice · successivo → 02 - Struttura - documenti, mapping, indentazione
1.1 Cos’è YAML e a cosa serve
YAML sta per YAML Ain’t Markup Language, acronimo ricorsivo, come GNU. Non è un linguaggio di markup: è un formato di serializzazione dati pensato per essere scritto e letto da esseri umani.
Tre cose lo distinguono da JSON: commenti, sintassi minimale (niente parentesi graffe, niente virgole) e frammenti riusabili (anchor). È per questo che ha vinto nel mondo delle configurazioni: un file di automazione Home Assistant o un workflow CI sono scritti e riletti da persone, non da programmi.
Il prezzo di quella leggibilità è la tipizzazione implicita: YAML indovina il tipo dei valori dall’aspetto. Ed è lì che nascono tutti i problemi.
1.2 Le versioni
| Versione | Data | Stato |
|---|---|---|
| 1.0 | 2004 | storia |
| 1.1 | 2005 | quello che implementano molti parser reali |
| 1.2 | 2009 | il cambiamento importante |
| 1.2.2 | 1 ott 2021 | la specifica corrente, senza modifiche normative rispetto alla 1.2 |
| 1.3.0 | bozza 2022 | mai pubblicata, ferma |
La 1.2 ha fatto una cosa sola, ma enorme: ha sostituito la libreria di tipi di YAML 1.1 con il “core schema”, molto più stretto. Elenco ufficiale dei cambiamenti:
- Solo le stringhe
trueefalsevengono lette come booleani (incluseTrueeTRUE);y,yes,one i loro opposti diventano stringhe.- Gli underscore
_non si possono più usare dentro i numeri.- I valori ottali richiedono il prefisso
0o:010ora vale 10, non 8.- I formati binario e sessagesimale sono stati rimossi.
- I tipi
!!pairs,!!omap,!!set,!!timestampe!!binarysono stati rimossi.- Le chiavi speciali merge
<<e value=sono state rimosse.
Tradotto: in YAML 1.2 NO è la stringa “NO”, 12:30 è la stringa “12:30”, 2026-08-21
è una stringa, e << non esiste.
1.3 Il problema: quasi nessuno ha aggiornato
Ecco lo stato reale dell’ecosistema ad agosto 2026:
| Libreria | Ultima versione | Semantica |
|---|---|---|
| PyYAML (Python) | 6.0.3 | YAML 1.1 |
| ruamel.yaml (Python) | 0.19.x | YAML 1.2 core |
| js-yaml (JS) | 5.3.0 | YAML 1.2 core |
yaml (JS, eemeli) | 2.9.x | YAML 1.2 |
| go-yaml v3 | - | ibrido dichiarato, progetto non manutenuto |
Python è 1.1, JavaScript è 1.2, Go è a metà. E PyYAML è, di gran lunga, il parser YAML più diffuso al mondo: sta sotto Home Assistant, Ansible, e mille script.
1.4 La dimostrazione
Stesso file, due parser. ✅ verificato eseguendo PyYAML 6.0.3 e lo schema core 1.2:
| Scrivi | YAML 1.1 (PyYAML) | YAML 1.2 core |
|---|---|---|
NO | False | 'NO' |
on | True | 'on' |
Yes | True | 'Yes' |
0777 | 511 (ottale) | 777 (decimale!) |
0o777 | '0o777' (stringa) | 511 |
01234 | 668 (ottale) | 1234 |
08 | '08' (stringa) | 8 |
12:30 | 750 (sessagesimale) | '12:30' |
2026-08-21 | oggetto data | '2026-08-21' |
1e3 | '1e3' (stringa) | 1000.0 |
1.10 | 1.1 | 1.1 |
1_000 | 1000 | '1_000' |
Guarda bene la riga 0777: cambia valore, da 511 a 777, senza alcun errore. E
01234 in 1.1 è 668 mentre 01890 (che contiene un 8, cifra non ottale) resta stringa:
lo stesso campo si comporta in modo diverso a seconda del dato.
Nota anche 1.10 → 1.1: quello succede in entrambi gli schemi. Passare a 1.2 non
risolve tutto.
1.5 YAML è davvero un superset di JSON?
La specifica dice che l’obiettivo era proprio quello, e in pratica è quasi vero. Le eccezioni reali:
- Chiavi duplicate. JSON dice che “dovrebbero” essere uniche, YAML dice che
devono.
{"a":1,"a":2}è JSON legale e YAML illegale. - I tab. Un file JSON indentato con tab: js-yaml lo accetta, PyYAML lo rifiuta
con
found character '\t' that cannot start any token. Qui è PyYAML a non essere conforme, ma il risultato pratico non cambia.
Corollario utile: JSON valido è (quasi sempre) YAML valido, quindi in un file YAML puoi sempre ripiegare sulla sintassi JSON quando vuoi essere inequivocabile. È esattamente l’idea dietro KYAML, il sottoinsieme che Kubernetes ha standardizzato nel 2026: flow style, tutte le stringhe fra doppi apici, niente ambiguità.
1.6 Cosa farne, in pratica
Non puoi scegliere il parser: lo sceglie l’applicazione che legge il tuo file. Quindi:
La regola che discende da tutto questo
Scrivi file che si comportano allo stesso modo in 1.1 e in 1.2. Si ottiene virgolettando ogni valore ambiguo. Non è pedanteria: è l’unico modo di avere un file che significa la stessa cosa ovunque.
# fragile: significa cose diverse a seconda di chi legge
paese: NO
versione: 1.10
porta: 0022
inizio: 12:30
attivo: yes
# robusto: identico in 1.1 e 1.2
paese: 'NO'
versione: '1.10'
porta: 22
inizio: '12:30'
attivo: trueEsercizi
- Crea un file con i valori della tabella §1.4 e leggilo con:
python3 -c "import yaml,json;print(json.dumps(yaml.safe_load(open('test.yaml')),indent=2,default=str))". Guarda coi tuoi occhi cosa diventaNO. - Leggi lo stesso file con Node:
node -e "console.log(require('js-yaml').load(require('fs').readFileSync('test.yaml','utf8')))". Confronta. - Cerca nei tuoi file YAML esistenti (frontmatter compresi) tutti i valori che iniziano con zero o che sono sigle di due lettere maiuscole. Sono le tue bombe a orologeria.