Saving config files with !new tags
Hello,
I have the following code (a MWE - minimum working example), where I want to dump a config with a !new instatiation.
yaml_string = """
foo: !new:collections.Counter
a: 4
bar: !ref <foo>
baz: !copy <foo>
"""
loaded_yaml = load_hyperpyyaml(yaml_string)
from hyperpyyaml import dump_hyperpyyaml
# Importing the StringIO module.
from io import StringIO
dump_hyperpyyaml(loaded_yaml, StringIO())
This fails with the following
RepresenterError Traceback (most recent call last)
[<ipython-input-6-c8804319bfb8>](https://localhost:8080/#) in <cell line: 14>()
12 from io import StringIO
13
---> 14 dump_hyperpyyaml(loaded_yaml, StringIO())
9 frames
[/usr/local/lib/python3.10/dist-packages/ruamel/yaml/representer.py](https://localhost:8080/#) in represent_undefined(self, data)
343
344 def represent_undefined(self, data: Any) -> None:
--> 345 raise RepresenterError(f'cannot represent an object: {data!s}')
346
347
RepresenterError: cannot represent an object: Counter({'a': 4})
Neither the docs, nor the given Colab notebook contains an example of dumping with the !new tag. How could this be done?
tl;dr this is not possible with the current way this is structured.
Longer answer:
There's no general way to extract the arguments used to construct an object. On the other hand, if you wanted to use it for specific cases, this would have to be done with something like the add_representer in the current dump_hyperpyyaml where the to_yaml function tells the representer how to convert the class to a string:
def dump_hyperpyyaml(yaml_tree, output_stream, *args, **kwargs):
ruamel_yaml = ruamel.yaml.YAML()
ruamel_yaml.representer.add_representer(RefTag, RefTag.to_yaml)
ruamel_yaml.representer.add_representer(Placeholder, Placeholder.to_yaml)
ruamel_yaml.dump(yaml_tree, output_stream, *args, **kwargs)
I suppose one simple change that might allow a user to do this is to do something like:
def dump_hyperpyyaml(yaml_tree, output_stream, represented_classes=[RefTag, Placeholder], *args, **kwargs):
ruamel_yaml = ruamel.yaml.YAML()
for represented_class in represented_classes:
ruamel_yaml.representer.add_representer(represented_class, represented_class.to_yaml)
ruamel_yaml.dump(yaml_tree, output_stream, *args, **kwargs)
Is this something that would likely work for your use case?
I understand. Ideally, as a user I would appreciate something more towards how hydra manages to do this - not requiring extra effort from the users. I did not study how that works though - could be requiring some changes to how hyperpyyaml functions. For the time being, I just want to dump the configuration for certain speech processing pipeline segments - so I can get away with making a base class dumpable (according to your first snippet) and everything else can inherit. Thank you for the reply :+1: