Guardar / volcar un archivo YAML con comentarios en PyYAML

Tengo un archivo yaml que se ve así:

# The following key opens a door key: value 

¿Hay alguna forma en que pueda load y dump estos datos mientras mantengo el comentario?

PyYAML tira los comentarios a un nivel muy bajo (en Scanner.scan_to_next_token ).

Si bien podría adaptarlo o ampliarlo para manejar los comentarios en toda su stack, esta sería una modificación importante. Dump ing (= emitir) los comentarios parece ser más fácil y se discutió en el ticket 114 en el antiguo rastreador de errores PyYAML.

Si está utilizando YAML de bloques estructurados, puede usar el paquete python¹ ruamel.yaml, que es un derivado de PyYAML y es compatible con la conservación de comentarios de ida y vuelta :

 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) 

con resultado

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

Tenga en cuenta que los comentarios de fin de línea aún están alineados.

En lugar de la list normal y los objetos dict , el code consiste en versiones envueltas² en las que se adjuntan los comentarios.

¹ Instalar con pip install ruamel.yaml . Funciona en Python 2.6 / 2.7 / 3.3 +
² El ordereddict se usa en el caso de un mapeo, para preservar el orden

Tengo una twig de pyyaml ​​que hace exactamente esto. https://github.com/pflarr/pyyaml

Para crear un archivo yaml con comentarios, debe crear una secuencia de eventos que incluya eventos de comentarios. Actualmente solo se permiten comentarios antes de elementos de secuencia y claves de mapeo.

Esto solo funciona actualmente para python3, no lo he transferido a la versión python2 de la biblioteca, pero podría hacerlo fácilmente a petición. Además, esto también debería ser bastante fácil de portar al C libyaml, ya que el código de Python es un puerto simple de todos modos.