YAML en JSON
Flux multi-documents, et un interrupteur pour le piège des booléens de YAML 1.1.
Rien de ce que vous collez ne quitte votre navigateur. La liste d’autorisation connect-src en fait une garantie du navigateur plutôt qu’une promesse. Vérifiez-le vous-même
Convertissez du YAML en JSON, avec prise en charge multi-documents et un interrupteur pour les règles de typage qui causent le plus de confusion.
C’est dans ce sens que les choses tournent mal, et presque tout se ramène à la version de YAML qu’implémentent vos autres outils.
Le problème norvégien, démontré
En YAML 1.1, les mots nus no, yes, on, off, y et n sont des booléens. Une liste de pays contenant NO pour la Norvège s’analyse donc en false. En YAML 1.2, ce sont des chaînes ordinaires.
Cela compte parce que la fracture traverse tout l’écosystème. PyYAML, Psych en Ruby et plusieurs outils anciens implémentent 1.1. js-yaml, yaml.v3 en Go et la plupart des analyseurs modernes implémentent 1.2. Le même fichier veut dire des choses différentes selon qui le lit.
Vous pouvez changer les règles de typage ici et voir une valeur changer sous vos yeux. Mesuré avec js-yaml 5.4.1 : `a: no` donne la chaîne "no" en YAML 1.2 et le booléen false en YAML 1.1. Même en mode 1.2, cet outil vous prévient lorsqu’il voit un no ou un yes sans guillemets, car l’outil suivant de votre chaîne pourrait ne pas être d’accord avec lui.
Les autres choses que YAML a et que JSON n’a pas
- Commentaires
- Perdus, définitivement. JSON n’a pas de syntaxe de commentaire. Si vous maintenez le YAML à la main, cette conversion est à sens unique.
- Ancres et alias
- Développés sur place. Un document utilisant une ancre cinq fois devient cinq copies dans le JSON, qui peut être nettement plus volumineux.
- Horodatages
- YAML résout les scalaires en forme de date en véritables dates. JSON n’a pas de type date : elles sont donc écrites en chaînes ISO 8601. Choisissez les règles de typage JSON pour qu’elles restent de simples chaînes dès le départ.
- Clés non textuelles
- YAML autorise un nombre, voire une séquence, comme clé de mapping. JSON non : elles sont converties en chaînes.
- .inf et .nan
- Aucun équivalent JSON, ils deviennent donc null.
- Documents multiples
- Un flux séparé par --- contient plusieurs documents. Par défaut le premier est converti et on vous signale qu’il y en avait d’autres ; activez « tous les documents » pour obtenir un tableau.
Tabulations
YAML interdit les tabulations pour l’indentation, absolument et sans exception. C’est l’erreur YAML la plus fréquente qui soit, et elle arrive parce qu’un éditeur est configuré pour insérer des tabulations. Cet outil vous avertit des tabulations avant même d’essayer d’analyser, car le message que produit alors n’importe quel analyseur n’aide en rien.
How to do this in code
Convertir en code, et l’argument de sécurité qui va avec.
py Python
PyYAML implémente YAML 1.1 : c’est donc là que "no" devient False.
import yaml, json
# safe_load, never load. yaml.load can construct arbitrary Python
# objects and has been a real remote-code-execution vector.
data = yaml.safe_load(text)
print(json.dumps(data, indent=2, default=str))
# default=str handles the datetime objects PyYAML produces for
# date-shaped scalars, which json.dumps otherwise refuses. sh Shell
yq -o=json eval . input.yaml > output.json
# Every document of a multi-document stream
yq -o=json eval-all '[.]' input.yaml js JavaScript
js-yaml implémente YAML 1.2, donc ici "no" reste une chaîne.
import { load, loadAll } from 'js-yaml';
const data = load(text); // YAML 1.2 core schema
const docs = loadAll(text); // multi-document stream go Go
import "gopkg.in/yaml.v3"
var v any
if err := yaml.Unmarshal(data, &v); err != nil { return err }
out, _ := json.MarshalIndent(v, "", " ") Questions fréquentes
- Pourquoi ma valeur est-elle devenue true ou false ?
- Vous la lisez avec un analyseur YAML 1.1, où no, yes, on, off, y et n sont des booléens. Mettez la valeur entre guillemets, ou utilisez un analyseur YAML 1.2. Changez les règles de typage ci-dessus pour voir la différence sur votre propre document.
- Où sont passés mes commentaires ?
- JSON n’a pas de commentaires, ils sont donc supprimés. Il n’y a pas de contournement. Si le YAML est un fichier que vous maintenez, gardez-le comme source de vérité et générez le JSON à partir de lui.
- Pourquoi yaml.load est-il dangereux en Python ?
- Parce qu’il peut instancier des objets Python arbitraires à partir de balises du document, ce qui rend l’analyse d’un YAML non fiable équivalente à son exécution. Utilisez toujours safe_load.