-1

I have the following Python code:

import ruamel.yaml

source = open("source.yaml", "r")
target = open("target.yaml", "r")

sourceValues = ruamel.yaml.load(source, ruamel.yaml.RoundTripLoader, preserve_quotes=True)
targetValues = ruamel.yaml.load(target, ruamel.yaml.RoundTripLoader, preserve_quotes=True)

source.close()
target.close()

# some changes on target properties
targetValues['test']['something'] = sourceValues['test']['something']

with open('target.yaml', 'w') as conf:
  ruamel.yaml.dump(targetValues, conf, ruamel.yaml.RoundTripDumper)

One example of YAML with comments:

test:
  # some comment
  something: "something" # another comment
  else: 123

The above code outputs:

test:
  something: "something-updated"
  else: 123456

Everything works fine, fields are updated as expected, quotes are being kept, code indentation looks OK... But the comments are being lost.

Ventrue
  • 372
  • 3
  • 17
  • Possible dupe: [ruamel.yam is not preserving all comments](https://stackoverflow.com/q/40872028) – SuperStormer Aug 09 '22 at 23:41
  • I don’t think it’s a duplicate. I’m losing all comments, not just some comments. – Ventrue Aug 09 '22 at 23:50
  • 1
    You are using the deprecated `load` function instead of instantiating a `YAML()` instance and usng its `load` method. Is that because you are using an old version of `ruamel.yaml`? You use two input files, but only one YAML input, which one is that and what is the other? The vast majority of YAML files are UTF-8 encoded, so you better open them `"rb"` resp. `"wb"'. – Anthon Aug 10 '22 at 05:17

1 Answers1

1

You are using functions from the ruamel.yaml library that were deprecated quite a long time ago.

Your input round-trips without a problem:

import sys
from pathlib import Path
import ruamel.yaml

file_in = Path('target.yaml')
file_in.write_text("""\
test:
  # some comment
  something: "something" # another comment
  else: 123
""")
    
yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
data = yaml.load(file_in)
yaml.dump(data, sys.stdout)

as this gives:

test:
  # some comment
  something: "something" # another comment
  else: 123

And this works even if you update data:

data['test']['something'] = 'something-updated'
yaml.dump(data, file_in)
print(file_in.read_text(), end='')

which gives:

test:
  # some comment
  something: "something-updated" # another comment
  else: 123
Anthon
  • 69,918
  • 32
  • 186
  • 246
  • That's true, I am a new in Python and did not realize that. Thanks, your solution works. – Ventrue Aug 10 '22 at 11:16
  • Do you know by any chance why the output file has some new break lines? They appear just below lines with comments. – Ventrue Aug 10 '22 at 11:30
  • 1
    Are you on windows? – Anthon Aug 10 '22 at 15:13
  • Yes, I'm using Windows for development. – Ventrue Aug 10 '22 at 15:17
  • 1
    I haven't worked with ruamel.yaml on Windows for a while. What I suspect is that the newline that is stored in the comment causes this duplication. with file_in.open('w') as fp: yaml.dump(data, fp)` instead of handing in the `Path` instance to dump. – Anthon Aug 10 '22 at 15:29