I have classes that are setup to be loaded/dumped using ruamel.yaml 0.17.21 yaml_object
decorator.
For some reason, I don't want changes in my class to be saved to yaml, unless specifically requested by the user. To do that, I use the __getstate__
and __setstate__
methods to cache the initial_state and the user is directed to modify this object if they want a permanent change.
Everything works as excepted, except that the name of the anchors are lost when dumping.
I was not able to pinpoint how ruamel.yaml preserves those normally when the __{set|get}state__
methods are not defined.
Those easy-to-read anchor names are very important to me as a user-friendly feature.
Here's an example:
import sys
from copy import deepcopy
from ruamel.yaml import YAML, yaml_object
yaml = YAML()
@yaml_object(yaml)
class ExampleClass():
def __init__(self):
self._permanent_state = {}
def __setstate__(self, state):
self.__dict__.update(deepcopy(state))
self._permanent_state = state
def __getstate__(self):
return self._permanent_state
source = """
simple: &simple !ExampleClass
potato: 10
turnip: 20
nested: !ExampleClass
sunflower: 30
others: *simple
"""
a = yaml.load(source)
a['simple'].potato = 10**6 # Should not be reflected in dump
a['nested']._permanent_state['sunflower'] = 100 # Should be reflected in dump
yaml.dump(a, sys.stdout)
Output has simple
anchor renamed to id001
:
simple: &id001 !ExampleClass
potato: 10
turnip: 20
nested: !ExampleClass
sunflower: 100
others: *id001
If I remove the __getstate__
and __setstate__
methods
import sys
from copy import deepcopy
from ruamel.yaml import YAML, yaml_object
yaml = YAML()
@yaml_object(yaml)
class ExampleClass():
pass
source = """
simple: &simple !ExampleClass
potato: 10
turnip: 20
nested: !ExampleClass
sunflower: 30
others: *simple
"""
a = yaml.load(source)
a['simple'].potato = 10**6 # Should not be reflected in dump
a['nested']._permanent_state = deepcopy(a['nested'].__dict__)
a['nested']._permanent_state['sunflower'] = 100 # Should not be reflected in dump
yaml.dump(a, sys.stdout)
Output now preserves the simple
anchor (but the desired behaviour is lost):
simple: &simple !ExampleClass
potato: 1000000
turnip: 20
nested: !ExampleClass
sunflower: 30
others: *simple
_permanent_state:
sunflower: 100
others: !ExampleClass
potato: 1000000
turnip: 20
Ideally I would like the behaviour of the first example, while preserving the anchor name.