Is it possible to specify a default PyYAML representer for non-standard Python objects?
import yaml
class Foo(int): pass
class Bar(float): pass
data = dict(foo=Foo(42), bar=Bar(3.14), baz=[1,2])
print(yaml.safe_dump(data))
# Raises error:
# RepresenterError: ('cannot represent an object', ...)
print(yaml.dump(data))
# Prints:
# bar: !!python/object/new:__main__.Bar
# - 3.14
# baz:
# - 1
# - 2
# foo: !!python/object/new:__main__.Foo
# - 42
How to instruct PyYAML to use a default representer for all non-standard objects? For instance, I would like to invoke an object's __str__()
or __repr__()
method iff it cannot be represented safely.
I was lucky with the following "naive" approach:
import yaml
class Foo(int): pass
class Bar(float): pass
data = dict(foo=Foo(42), bar=Bar(3.14), baz=[1,2])
# Set default representer
def default_representer(dumper, data):
# Alternatively, use repr() instead str():
return dumper.represent_scalar('tag:yaml.org,2002:str', str(data))
yaml.representer.SafeRepresenter.add_representer(None, default_representer)
# Now this works as expected: unknown objects
# are printed as strings.
print(yaml.safe_dump(data))
# Prints:
# bar: '3.14'
# baz:
# - 1
# - 2
# foo: '42'
To make this work via yaml.dump()
as well, I set the Dumper
argument:
print(yaml.dump(data, Dumper=yaml.SafeDumper))
However, this makes it essentially the same as yaml.safe_dump()
. I could not find a better way to disable the type tags.