kopia lustrzana https://github.com/corrscope/corrscope
Save config files atomically
Fixes #506. In PR #377 (save GlobalPrefs atomically), I created a new codepath by passing a file into yaml.dump. Unfortunately I forgot to mark it as UTF-8 (regressing #311). This breaks saving settings after opening a config in a Unicode folder. To prevent this from recurring, I restructured the code to always pass a Path into yaml.dump(), and write the file atomically.pull/507/head
rodzic
6a504c51db
commit
4fa08c4f25
|
@ -14,6 +14,8 @@
|
||||||
### Changelog
|
### Changelog
|
||||||
|
|
||||||
- When opening missing file via CLI, show dialog rather than crashing (#499)
|
- When opening missing file via CLI, show dialog rather than crashing (#499)
|
||||||
|
- Fix saving global settings after opening config in Unicode folder (#507)
|
||||||
|
- Save config files atomically (#507)
|
||||||
|
|
||||||
## 0.10.1
|
## 0.10.1
|
||||||
|
|
||||||
|
|
|
@ -19,10 +19,10 @@ from typing import (
|
||||||
Any,
|
Any,
|
||||||
TextIO,
|
TextIO,
|
||||||
Union,
|
Union,
|
||||||
IO,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
import attr
|
import attr
|
||||||
|
from atomicwrites import atomic_write
|
||||||
from ruamel.yaml import (
|
from ruamel.yaml import (
|
||||||
yaml_object,
|
yaml_object,
|
||||||
YAML,
|
YAML,
|
||||||
|
@ -61,9 +61,14 @@ class MyYAML(YAML):
|
||||||
# https://bitbucket.org/ruamel/yaml/issues/316/unicode-encoding-decoding-errors-on
|
# https://bitbucket.org/ruamel/yaml/issues/316/unicode-encoding-decoding-errors-on
|
||||||
# Both are bad, so use UTF-8.
|
# Both are bad, so use UTF-8.
|
||||||
if isinstance(stream, Path):
|
if isinstance(stream, Path):
|
||||||
with stream.open("w", encoding="utf-8") as f:
|
path = stream
|
||||||
|
with atomic_write(path, overwrite=True, encoding="utf-8") as f:
|
||||||
self.dump_without_corrupting(data, f, **kwargs)
|
self.dump_without_corrupting(data, f, **kwargs)
|
||||||
|
|
||||||
|
elif isinstance(stream, TextIO):
|
||||||
|
# Nobody actually calls dump(..., open()). This branch is never taken.
|
||||||
|
self.dump_without_corrupting(data, stream, **kwargs)
|
||||||
|
|
||||||
elif stream is None:
|
elif stream is None:
|
||||||
# Possibly only called in unit tests, not in production.
|
# Possibly only called in unit tests, not in production.
|
||||||
stream = StringIO()
|
stream = StringIO()
|
||||||
|
@ -71,8 +76,9 @@ class MyYAML(YAML):
|
||||||
return stream.getvalue()
|
return stream.getvalue()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# with atomic_write(...) as f: dump(..., f)
|
raise TypeError(
|
||||||
self.dump_without_corrupting(data, stream, **kwargs)
|
f"stream must be {{Path, TextIO=open(), None}}, but is {type(stream)}"
|
||||||
|
)
|
||||||
|
|
||||||
def dump_without_corrupting(self, *args, **kwargs):
|
def dump_without_corrupting(self, *args, **kwargs):
|
||||||
YAML.dump(self, *args, **kwargs)
|
YAML.dump(self, *args, **kwargs)
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
from typing import *
|
from typing import *
|
||||||
|
|
||||||
import attr
|
import attr
|
||||||
from atomicwrites import atomic_write
|
|
||||||
|
|
||||||
from corrscope.config import DumpableAttrs, yaml
|
from corrscope.config import DumpableAttrs, yaml
|
||||||
from corrscope.settings import paths
|
from corrscope.settings import paths
|
||||||
|
|
||||||
|
@ -75,5 +73,4 @@ def load_prefs() -> GlobalPrefs:
|
||||||
|
|
||||||
|
|
||||||
def dump_prefs(pref: GlobalPrefs) -> None:
|
def dump_prefs(pref: GlobalPrefs) -> None:
|
||||||
with atomic_write(_PREF_PATH, overwrite=True, encoding="utf-8") as f:
|
yaml.dump(pref, _PREF_PATH)
|
||||||
yaml.dump(pref, f)
|
|
||||||
|
|
Ładowanie…
Reference in New Issue