2016-07-05 1 views
2

J'ai un fichier YAML et je voudrais contraindre un certain champ à ne contenir aucun espace.Pourquoi PyYAML et ruamel.yaml échappent-ils à des caractères spéciaux quand on les compare?

Voici un script qui démontre ma tentative:

test.py

#!/usr/bin/env python3 

import os 
from ruamel import yaml 

def read_conf(path_to_config): 
    if os.path.exists(path_to_config): 
     conf = open(path_to_config).read() 
     return yaml.load(conf) 
    return None 

if __name__ == "__main__": 
    settings = read_conf("hello.yaml") 
    print("type of name: {0}, repr of name: {1}".format(type(
      settings['foo']['name']), repr(settings['foo']['name']))) 
    if any(c.isspace() for c in settings['foo']['name']): 
     raise Exception("No whitespace allowed in name!") 

Voici ma première coupe du fichier YAML:

hello.yaml

foo: 
    name: "hello\t" 

Dans le fichier YAML ci-dessus, une exception est correctement soulevé:

type of name: <class 'str'>, repr of name: 'hello\t' 
Traceback (most recent call last): 
    File "./test.py", line 16, in <module> 
    raise Exception("No whitespace allowed in name!") 
Exception: No whitespace allowed in name! 

Cependant, si je change les guillemets doubles guillemets simples, pas d'exception est levée:

08:23 $ ./test.py 
type of name: <class 'str'>, repr of name: 'hello\\t' 

Ce comportement se produit lorsque vous utilisez ruamel.yaml==0.11.11 et PyYAML=3.11. Pourquoi y a-t-il une différence entre les guillemets simples et doubles dans ces analyseurs syntaxiques YAML Python alors que, si je comprends bien, il n'y a pas de différence fonctionnelle entre eux dans les spécifications YAML? Comment puis-je empêcher les caractères spéciaux d'être échappés?

+1

Quel module 'yaml' serait natif de Python3? Ni «ruamel.yaml» ni «PyYAML» ne font partie de la bibliothèque python standard. – Anthon

+0

@Anthon Oups. J'ai installé PyYAML globalement et je ne m'en suis pas rendu compte. :) Éditera. – erip

Répondre

3

Il existe une grande différence dans la spécification YAML entre les chaînes simples et doubles. Dans single quoted scalars vous pouvez seulement échapper la citation unique:

Le style de guillemets simples est spécifié par les indicateurs «'» environnants. Par conséquent, dans un scalaire à guillemets simples, de tels caractères doivent être répétés. C'est la seule forme d'échappement effectuée dans les scalaires à guillemets simples.

Par conséquent \ dans 'hello\t' n'a aucune fonction particulière et que scalaire se compose des lettres h, e, l (2x), o. \ et t

L'échappement de barre oblique inverse est uniquement pris en charge dans les scalaires YAML à double guillemets.

+1

Ah, ma compréhension était boguée. :) Je suppose que je vais devoir élargir ma contrainte pour empêcher tous les caractères spéciaux. – erip

+1

Vous pouvez utiliser des tabulations dans des guillemets simples (et dans des scalaires de blocs littéraux et pliés), mais vous devez utiliser le caractère de tabulation lui-même, pas la séquence d'échappement habituelle ('\ t'). Ces caractères sont, dans de nombreuses circonstances, difficiles à distinguer de l'espace (s), mais c'est correct YAML – Anthon