Search code examples
pythoninheritanceyamlpyyaml

Pyyaml: Default dump behavior for inherited classes


I have a class that inherits from one of the built-ins:

from yaml import YAMLObject, dump
class D(dict, YAMLObject):
   yaml_tag = u'!!map'
   ...

Is there a way to tell pyyaml that the dump of any instance of D should be treated like the parent (in this case dict)? I.e., I would like the following output:

d = {'a':1}
print( dump(d) )
>>> a: 1

Instead of

print( dump(D(d)) )
>>> !%21map {}

As you can see I already tried assigning the class a default tag, but that did not quite work out. Defining a custom dumper is unfortunately not an option.


Solution

  • You can provide a custom to_yaml method in your D class:

    import yaml
    
    
    class D(dict, yaml.YAMLObject):
        yaml_tag = "!map"
    
        @classmethod
        def to_yaml(cls, dumper, data):
            return dumper.represent_dict(dict(data))
    
    
    d = D({"foo": "bar"})
    print(yaml.dump(d))
    

    The output of the above is:

    foo: bar
    

    Note that this only works with yaml.dump and not with yaml.safe_dump. The value of yaml_tag seems to be irrelevant, but it must be set; without setting it, the output of the above would be:

    !!python/object/new:__main__.D
    dictitems:
      foo: bar