Search code examples
pythonpython-3.xyamlpyyaml

How to get consistent quotes during PyYAML dump()?


I want to dump a dictionary to a yaml file with PyYAML (using yaml.dump()). Dict looks like this:

{'releases':
 {'release1': {'name': 'release1, 'version': '1.0.0', 'sha1': 'sha1'},
 {'release2': {'name': 'release2', 'version': '20', 'sha1': 'sha1'},
 {'release3': {'name': 'release3', 'version': '3.0', 'sha1': 'sha1'},
 ...

Those version numbers can have any format. E.g. 1.0, 2.0.1, 30, v4, ...
During dumping PyYAML adds single quotes to values which could be interpreted as float or int. This makes sense and seems to be intended. However this makes the final yaml file look very inconsistent (it's valid anyways):

releases:
  release1:
    name: release1
    sha1: sha1
    version: 1.0.0
  release2:
    name: release2
    sha1: sha1
    version: '20'
  release3:
    name: release3
    sha1: sha1
    version: '3.0'
...

Is there a way to enforce quotes for all version numbers?
I tried using default_flow_style but it does not work or adds quotes to keys and values which I don't want.


Solution

  • If you want control over how PyYAML serializes values, you need a custom serializer, e.g.

    class SingleQuoted(str):
      pass
    
    def represent_single_quoted(dumper, data):
      return dumper.represent_scalar(BaseResolver.DEFAULT_SCALAR_TAG,
          data, style="'")
    
    yaml.add_representer(SingleQuoted, represent_single_quoted)
    

    If you have that, you can force any value to be serialized single-quoted by wrapping it with SingleQuoted, e.g.

    SingleQuoted('1.0.0')