Modifying YAML using ruamel.yaml adds extra new lines

2024/11/18 14:36:14

I need to add an extra value to an existing key in a YAML file. Following is the code I'm using.

with open(yaml_in_path, 'r') as f:doc, ind, bsi = load_yaml_guess_indent(f, preserve_quotes=True)
doc['phase1'] += ['c']
with open(yaml_out_path, 'w') as f:ruamel.yaml.round_trip_dump(doc, f,indent=2, block_seq_indent=bsi)

This is the input and output.

Input

phase1:- a# a comment.- bphase2:- d

Output

phase1:- a# a comment.- b- c
phase2:- d

How can I get rid of the new line between b and c? (This problem is not there when phase1 is the only key in the file or when there are no blank lines between phase1 and phase2.)

Answer

The problem here is that the empty line is considered to be sort of a comment and that comments in ruamel.yaml are preserved by associating them with elements in a sequence or with keys in a mapping. That value is stored in a complex attribute named ca, on the list like object doc['phase1'], associated with the second element.

You can of course argue that it should be associated on the top level mapping/dict either associated with key phase1 (as some final empty-line-comment) or with phase2 as some introductory empty-line-comment. Either of the above three is valid and there is currently no control in the library over the strategy, where the empty line (or a comment goes).

If you put in a "real" comment (one starting with #) it will be associated with phase1 as an end comment, for those the strategy is different.

This obviously needs an overhaul, as the original goal of ruamel.yaml was: - load some configuration from YAML - change some value - save the configuration to YAML in which case these kind of append/insert problems don't appear.

So there is no real solution until the library is extended with some control over where to attach (trailing) comments and/or empty lines.

Until such control gets implemented, probably the best thing you can do is the following:

import sys
import ruamel.yamlyaml_str = """\
phase1:- a# a comment.- bphase2:- d
"""def append_move_comment(l, e):i = len(l) - 1l.append(e)x = l.ca.items[i][0]  # the end commentif x is None:returnl.ca.items[i][0] = Nonel.ca.items[i+1] = [x, None, None, None]data = ruamel.yaml.round_trip_load(yaml_str)
append_move_comment(data['phase1'], 'c')
ruamel.yaml.round_trip_dump(data, sys.stdout, indent=4, block_seq_indent=2)

I changed the indent value to 4, which is what your input has (and get because you specify it as to small for the block_seq_indent).

https://en.xdnf.cn/q/71050.html

Related Q&A

How to get the background color of a button or label (QPushButton, QLabel) in PyQt

I am quite new to PyQt. Does anyone tell me how to get the background color of a button or label (QPushButton, QLabel) in PyQt.

Is it possible to make sql join on several fields using peewee python ORM?

Assuming we have these three models.class Item(BaseModel):title = CharField()class User(BaseModel):name = CharField()class UserAnswer(BaseModel):user = ForeignKeyField(User, user_answers)item = Foreign…

Django multiple form factory

What is the best way to deal with multiple forms? I want to combine several forms into one. For example, I want to combine ImangeFormSet and EntryForm into one form:class ImageForm(forms.Form):image =…

How to include the private key in paramiko after fetching from string?

I am working with paramiko, I have generated my private key and tried it which was fine. Now I am working with Django based application where I have already copied the private key in database.I saved m…

SHA 512 crypt output written with Python code is different from mkpasswd

Running mkpasswd -m sha-512 -S salt1234 password results in the following:$6$salt1234$Zr07alHmuONZlfKILiGKKULQZaBG6Qmf5smHCNH35KnciTapZ7dItwaCv5SKZ1xH9ydG59SCgkdtsTqVWGhk81I have this snippet of Python…

Running python scripts in Anaconda environment through Windows cmd

I have the following goal: I have a python script, which should be running in my custom Anaconda environment. And this process needs to be automatizated. The first thing Ive tried was to create an .exe…

How to work out ComplexWarning: Casting complex values to real discards the imaginary part?

I would like to use a matrix with complex entries to construct a new matrix, but it gives me the warning "ComplexWarning: Casting complex values to real discards the imaginary part".As a resu…

Is it possible to use POD(plain old documentation) with Python?

I was wondering if it is possible to use POD(plain old documentation) with Python? And how should I do it?

ctypes error AttributeError symbol not found, OS X 10.7.5

I have a simple test function on C++:#include <stdio.h> #include <string.h> #include <stdlib.h> #include <locale.h> #include <wchar.h>char fun() {printf( "%i", 1…

Filtering negative timedeltas

Consider a series holding timedelta64[ns] that measures at the time difference between two events A and B:> time_deltas499900 -1 days +23:45:13 499916 -1 days +23:50:57 499917 00:03:2…