Cary Knoop
Cary Knoop

Reputation: 51

Ignoring objects for PyYAML dump

I use PyYAML dump to print complex data structures but there is one class of objects that cannot, and also I do not want to, be dumped.

Currently I get:

yaml.representer.RepresenterError: cannot represent an object

I would like yaml.dump to completely ignore this particular class or just render the classname and continue as usual.

If this is possible, how can I do that?

Upvotes: 2

Views: 1011

Answers (1)

Anthon
Anthon

Reputation: 76802

You'll have to provide a representer for the object. There are multiple ways to do that, some involving changing the object.

When you explicitly register a representer, the object doesn't have to be changed:

import sys
from ruamel import yaml


class Secret():
    def __init__(self, user, password):
        self.user = user
        self.password = password


def secret_representer(dumper, data):
        return dumper.represent_scalar(u'!secret', u'unknown')

yaml.add_representer(Secret, secret_representer)

data = dict(a=1, b=2, c=[42, Secret(user='cary', password='knoop')])

yaml.dump(data, sys.stdout)

In secret_representer, the data is the instantiated Secret(), since the function doesn't use that, no "secrets" are leaked. You could also e.g. return the user name, but not the password. The represent_scalar function expects a tag (here I used !secret) and a scalar (here the string unknown).

The output of the above:

a: 1
b: 2
c: [42, !secret '[unknown]']

I am using ruamel.yaml in the above which is an upgraded version of PyYAML (disclaimer: I am the author of that package). The above should work with PyYAML as well.

Upvotes: 1

Related Questions