pythonfileyamlruamel.yaml

End of line comments and before after key comments made using ruamel.yaml are not dumped


Comments made using .yaml_set_comment_before_after_key() and .yaml_add_eol_comment() on a newly created ruamel.yaml.comments.CommentedMap are not shown in the dumped string. See the expected vs actual output below.

Note that, ruamel.yaml==0.17.4 is the latest version that produces the expected output. Any versions later than this otherwise does not (see below).

# Minimal reproducible example
import ruamel.yaml

data = ruamel.yaml.comments.CommentedMap()
data['key'] = 'value'
data.yaml_set_start_comment('Start comment', indent=0)
data.yaml_set_comment_before_after_key('key', before='Before comment', indent=0)
data.yaml_add_eol_comment('End-of-line comment', 'key', column=0)

yaml_str = ruamel.yaml.dump(data, Dumper=ruamel.yaml.RoundTripDumper)
print(yaml_str)

Using:
Python 3.10.8
ruamel.yaml==0.17.32
ruamel.yaml.clib==0.2.7

By going through ruamel.yaml's version history, I have found that the latest ruamel version that produces the expected output to be 0.17.4 (Can be installed using pip install ruamel.yaml==0.17.4)
I don't understand why versions higher than this do not produce the expected output anymore. Is this perhaps a bug since April 2021?

Expected output:

# Start comment
# Before comment
key: value # End-of-line comment

Actual output (using ruamel.yaml==0.17.32):

# Start comment
key: value


Solution

  • First of all your code is not minimal, in that it creates a StringIO buffer and then prints the contents of that buffer. Don't do this:

    yaml_str = ruamel.yaml.dump(data, Dumper=ruamel.yaml.RoundTripDumper)
    print(yaml_str)
    

    just directly stream to sys.stdout ( with dump(data, sys.stdout) ), that is more concise, is faster and uses far less memory.

    What I don't understand is why you expect to be able to continue to use deprecated functions when you upgrade to a newer version, and then expect them to continue to work as usual. You should be using a YAML() instance:

    import sys
    import ruamel.yaml
    
        
    yaml = ruamel.yaml.YAML()
     
    data = ruamel.yaml.comments.CommentedMap()
    data['key'] = 'value'
    data.yaml_set_start_comment('Start comment', indent=0)
    data.yaml_set_comment_before_after_key('key', before='Before comment', indent=0)
    data.yaml_add_eol_comment('End-of-line comment', 'key', column=0)
    yaml.dump(data, sys.stdout)
    

    which gives:

    # Start comment
    # Before comment
    key: value # End-of-line comment
    

    And pin the version of ruamel.yaml that you are using, because those internal routines for handling comments will change in the future.