I am loading a yaml True/False item(example below) from a YAML file.
gzip: False
This is correctly interpreted in a Jinja2 template as boolean True.
The same YAML file is being read by another script, passed over as a python CGI form data and eventually written to the YAML file using
with open(myyaml, 'w') as yaml_file:
yaml_file.write(yaml.dump(dict, default_flow_style=False))
The issue is that this then writes the True/False with a single quote
gzip: 'False'
which causes the jinja2 template to not interpret the value as boolean and always sets value as true in
{{ if gzip }}
Is there a way to dump the YAML file with True/False values that are treated as boolean ( I mean without the quotes ).
Boolean values can be represented in YAML using the keywords like true and false or Yes and No .
PyYAML is a YAML parser and emitter for Python. Using the PyYAML module, we can perform various actions such as reading and writing complex configuration YAML files, serializing and persisting YMAL data. Use it to convert the YAML file into a Python dictionary.
It is often used for configuration files, but can also be used for data exchange. The most used python YAML parser is PyYAML, a library that allows you to load, parse, and write YAML, much like Python's JSON library helps you to work with JSON.
dump will write the produced YAML document into the file. Otherwise, yaml. dump returns the produced document.
.dump()
just dumps the data that it gets and it must have gotten a string instead of boolean as value for the key gzip
. Since that string value, if dumped unquoted can be misinterpreted as a boolean it gets quoted.
Since you get your material from a CGI form any value True
or False
will be a string. Before dumping your data, you explicitly have to convert these values you got from CGI to booleans.
You can walk over your dictionary and do something generic processing before you dump
:
import sys
import yaml
# simulating getting string type values from CGI
data = dict(gzip='False', intval="1", strval="abc")
for k in data:
v = data[k]
try:
v = int(v)
data[k] = v
except ValueError:
vl = v.lower()
if vl == 'false':
data[k] = False
elif vl == 'true':
data[k] = True
yaml.safe_dump(data, sys.stdout, default_flow_style=False)
gives:
gzip: false
intval: 1
strval: abc
Please note that abc
is not quoted, because it cannot be interpreted as anything else but a string. The above of course also converts strings 'True' or 'False' that would have to stay strings. If that is not what you want, you have to select conversion based on the key.
There are two other major problems with your two lines of Python:
with open(myyaml, 'w') as yaml_file:
yaml_file.write(yaml.dump(dict, default_flow_style=False))
dict
) as a variable name, that is just asking for trouble later on in your code.yaml.dump()
dumps data to a stream. It has a facility that if you don't specify the stream where things have to go to, the output is written to an internal stream object, from which the final value is returned. You should not abuse this, to then write this returned value to the yaml_file
. Instead do:
with open(myyaml, 'w') as yaml_file:
yaml.dump(dict, yaml_file, default_flow_style=False))
Your way is inefficient (apart from showing lack of understanding).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With