web-dev-qa-db-fra.com

Enregistrer / vider un fichier YAML avec des commentaires dans PyYAML

J'ai un fichier yaml qui ressemble à ceci:

# The following key opens a door
key: value

Existe-t-il un moyen de load et dump ces données tout en conservant le commentaire?

50
Harley Holcombe

PyYAML jette les commentaires à un niveau très bas (dans Scanner.scan_to_next_token).

Bien que vous puissiez l'adapter ou l'étendre pour gérer les commentaires dans toute sa pile, ce serait une modification majeure. Dumping (= émission) les commentaires semblent être plus faciles et ont été discutés dans ticket 114 sur l'ancien tracker de bogue PyYAML.

14
phihag

Si vous utilisez YAML structuré par blocs, vous pouvez utiliser le python package¹ ruamel.yaml qui est un dérivé de PyYAML et prend en charge conservation aller-retour des commentaires :

import sys
import ruamel.yaml

yaml_str = """\
# example
name:
  # details
  family: Smith   # very common
  given: Alice    # one of the siblings
"""

yaml = ruamel.yaml.YAML()  # defaults to round-trip if no parameters given
code = yaml.load(yaml_str)
code['name']['given'] = 'Bob'

yaml.dump(code, sys.stdout)

avec résultat:

# example
name:
  # details
  family: Smith   # very common
  given: Bob      # one of the siblings

Notez que les commentaires de fin de ligne sont toujours alignés.

Au lieu des objets normaux list et dict, le code se compose de versions wrappées² sur lesquelles les commentaires sont joints.

¹ Installer avec pip install ruamel.yaml. Fonctionne sur Python 2.6/2.7/3.3 +
² ordereddict est utilisé en cas de mappage, pour préserver l'ordre

73
Anthon

J'ai une branche de pyyaml ​​qui fait exactement cela. https://github.com/pflarr/pyyaml

Pour créer un fichier yaml avec des commentaires, vous devez créer un flux d'événements qui inclut des événements de commentaires. Les commentaires ne sont actuellement autorisés qu'avant les éléments de séquence et les clés de mappage.

Cela ne fonctionne actuellement que pour python3, je ne l'ai pas porté sur la version python2 de la bibliothèque, mais je pourrais facilement le faire sur demande. De plus, cela devrait également être assez facile à porter sur le libyaml C, car le code python est un port simple de cela de toute façon.

1
Paul Ferrell