Construct new YAML serializer object on every load/save operation

Not sure if this is a good idea worth keeping.
It may or may not fix a bug I've seen months ago.
In return, it introduces complexity and brittleness into my code,
and could stop working in a future ruamel.yaml update.
Also `pip install` doesn't pin the exact ruamel.yaml version
(accepting higher versions that could break my code),
only `poetry install` pins an exact version.
remove-global-yaml
nyanpasu64 2021-06-13 19:53:54 -07:00
rodzic e3e414e28c
commit c62e5d7351
2 zmienionych plików z 35 dodań i 7 usunięć

Wyświetl plik

@ -3,6 +3,7 @@
### Changelog
- Update NumPy so `poetry install` on Python 3.8+ won't build NumPy from source (#371)
- Fix possible bug where loading a corrupted file would cause future loading operations to fail (#???)
- Fix longstanding crash when prefs.yaml is corrupted, reset settings instead (#377)
- Atomically save prefs.yaml to prevent file corruption (#377)

Wyświetl plik

@ -119,15 +119,42 @@ class NoAliasRepresenter(RoundTripRepresenter):
return super().ignore_aliases(data)
yaml = MyYAML()
yaml.width = float("inf")
class yaml:
"""
Using a MyYAML object to load corrupted YAML files used to corrupt the object,
causing it to crash when trying to load future files.
I don't remember what kinds of YAML files reproduce the issue,
nor whether the bug still works.
However, making yaml.load()/yaml.dump() construct a new MyYAML object each time
means that even if the MyYAML object gets corrupted,
it's discarded and doesn't affect future yaml.load()/yaml.dump() operations.
"""
# Default typ='roundtrip' creates 'ruamel.yaml.comments.CommentedMap' instead of dict.
# Is isinstance(CommentedMap, dict)? IDK
assert yaml.Representer == RoundTripRepresenter
yaml.Representer = NoAliasRepresenter
@staticmethod
def _get_yaml():
yaml = MyYAML()
yaml.width = float("inf")
_yaml_loadable = yaml_object(yaml)
# Default typ='roundtrip' creates 'ruamel.yaml.comments.CommentedMap' instead of dict.
# Is isinstance(CommentedMap, dict)? IDK
assert yaml.Representer == RoundTripRepresenter
yaml.Representer = NoAliasRepresenter
return yaml
@staticmethod
def load(*args, **kwargs):
return yaml._get_yaml().load(*args, **kwargs)
@staticmethod
def dump(*args, **kwargs):
return yaml._get_yaml().dump(*args, **kwargs)
# This code is *very* hacky:
# calling _yaml_loadable(FooConfig) mutates the MyYAML.Representer and
# MyYAML.Constructor classes, to register FooConfig as serializable as YAML.
_yaml_loadable = yaml_object(MyYAML())
"""