pythonyamlruamel.yaml

How to keep !!timestamps and other tags when using ruamel.yaml


I currently work on a small automation script in Python to add specific lines to a YAML file. The script is working for now, but the created modified file is ignoring a couple of tags that are necessary in the file:

I have this small part that keeps changing. The original:

example:
  - x: ~
    y: !!timestamp 2025-05-04

The edited:

example:
  - x:
    y: 2025-05-04

I don't know how to adjust this. I know it's Python interpreting the ~ as None and the timestamp as a date format. Is there a workaround? Since the stuff I need to edit is in an entirely different group I thought about finding a solution that involves only loading the group I need to edit.


Solution

  • ruamel.yaml normalizes the output on roundtrip. This is includes emitting None as an empty scalar (when possible), and removing superfluous tags like !!timestamp.

    The representation of null can be changed (for all occurences) by creating your own representer. Preserving the superfluous tag is IMO best done by pre-and postprocessing the input.

    import sys
    import ruamel.yaml
    
    yaml_str = """\
    example:
      - x: ~
        y: !!timestamp 2025-05-04
    """
    
    class MyRepresenter(ruamel.yaml.representer.RoundTripRepresenter):
        def represent_none(self, data):
            if len(self.represented_objects) == 0 and not self.serializer.use_explicit_start:
                return self.represent_scalar('tag:yaml.org,2002:null', 'null')
            return self.represent_scalar('tag:yaml.org,2002:null', "~")
    
    MyRepresenter.add_representer(type(None), MyRepresenter.represent_none)
    
    def TSX113(s):
        return s.replace('TSX113', '!!timestamp')
    
    yaml = ruamel.yaml.YAML()
    yaml.Representer = MyRepresenter
    yaml.indent(sequence=4, offset=2)
    data = yaml.load(yaml_str.replace('!!timestamp', '!TSX113'))
    yaml.dump(data, sys.stdout, transform=TSX113)
    

    which gives:

    example:
      - x: ~
        y: !!!timestamp 2025-05-04
    

    Non-superfluous tags (like !TSX113) are preserved on round-trip without further action.