Pyyaml And Using Quotes For Strings Only
Solution 1:
I suggest you update to using YAML 1.2 (released in 2009) with the backwards compatible ruamel.yaml
package instead of using PyYAML which implements most of YAML 1.1 (2005). (Disclaimer: I am the author of that package).
Then you just specify preserve_quotes=True
when loading for round-tripping the YAML file:
import sys
import ruamel.yaml
yaml_str = """\
---
my_vars:
my_env: "dev" # keep "dev" quoted
my_count: 3
"""
data = ruamel.yaml.round_trip_load(yaml_str, preserve_quotes=True)
ruamel.yaml.round_trip_dump(data, sys.stdout, explicit_start=True)
which outputs (including the preserved comment):
---my_vars:my_env:"dev"# keep "dev" quotedmy_count:3
After loading the string scalars will be a subclass of string, to be able to accommodate the quoting info, but will work like a normal string for all other purposes. If you want to replace such a string though (dev
to fgw
)
you have to cast the string to this subclass ( DoubleQuotedScalarString
from ruamel.yaml.scalarstring
).
When round-tripping ruamel.yaml
by default preserves the order (by insertion) of the keys.
Solution 2:
Right, so borrowing heavily from this answer, you can do something like this:
import yaml
# define a custom representer for stringsdefquoted_presenter(dumper, data):
return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='"')
yaml.add_representer(str, quoted_presenter)
env_file = 'input.txt'withopen(env_file) as f:
env_dict = yaml.load(f)
print yaml.dump(env_dict, default_flow_style=False)
However, this just overloads it on all strings types in the dictionary so it'll quote the keys as well, not just the values.
It prints:
"my_vars":"my_count":3"my_env":"dev"
Is this what you want? Not sure what you mean by variable names, do you mean the keys?
Solution 3:
you can use the following method to retain your double quoted scalar
object in yaml
:
Taking your yaml example:
---my_vars:my_env:"dev"my_count:3
Loading it into an env_dict (dictionary):
myyaml = '''
---
my_vars:
my_env: "dev"
my_count: 3
'''
env_dict = yaml.load(myyaml, yaml.FullLoader) # loading yamlprint(env_dict)
{'my_vars': {'my_env': 'dev', 'my_count': 3}}
# Define a quoted class, which uses style = '"' and add representer to yamlclassquoted(str):
passdefquoted_presenter(dumper, data):
return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='"')
yaml.add_representer(quoted, quoted_presenter)
# Now, we update the dictionary env_dict as follows for the "dev" # value which needs to be a double quoted scalar
env_dict['my_vars'].update(my_env = quoted("dev")) # this makes "dev"# a double quoted scalar# Now, we dump the yaml as before
yaml.dump(env_dict, sys.stdout, indent=4, default_flow_style=False, explicit_start=True)
# which outputs
---
my_vars:
my_count: 3
my_env: "dev"
These links helped me to arrive at this answer : Any yaml libraries in Python that support dumping of long strings as block literals or folded blocks?
How can I control what scalar form PyYAML uses for my data?
Also, this one is a great article to read on To Quote or not to Quote?
Hope, this helps!
Post a Comment for "Pyyaml And Using Quotes For Strings Only"