From bbd331bcacd1dba52460978a76819d932677a485 Mon Sep 17 00:00:00 2001 From: Jesper Friis Date: Tue, 29 Oct 2024 16:09:16 +0100 Subject: [PATCH] Avoid overwrite existing YAML files if no change has been made (#987) Do not overwrite existing yaml files by default. --- bindings/python/scripts/CMakeLists.txt | 10 ++++++++++ bindings/python/tests/entities/InvalidYaml1.yaml | 14 ++++++++++++++ bindings/python/tests/entities/ValidYaml1.yaml | 14 ++++++++++++++ bindings/python/tests/test_storage.py | 6 +++--- storages/python/python-storage-plugins/yaml.py | 14 +++++++------- 5 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 bindings/python/tests/entities/InvalidYaml1.yaml create mode 100644 bindings/python/tests/entities/ValidYaml1.yaml diff --git a/bindings/python/scripts/CMakeLists.txt b/bindings/python/scripts/CMakeLists.txt index bb560f977..95dc9d7ea 100644 --- a/bindings/python/scripts/CMakeLists.txt +++ b/bindings/python/scripts/CMakeLists.txt @@ -79,3 +79,13 @@ test_success( dlite-validate-empty dlite-validate Empty.json ) +# Test valid yaml +test_success( + dlite-validate-valid1-yaml + dlite-validate ../tests/entities/ValidYaml1.yaml +) +# Test invalid yaml +test_failure( + dlite-validate-invalid1-yaml + dlite-validate ../tests/entities/InvalidYaml1.yaml +) diff --git a/bindings/python/tests/entities/InvalidYaml1.yaml b/bindings/python/tests/entities/InvalidYaml1.yaml new file mode 100644 index 000000000..875a15bf2 --- /dev/null +++ b/bindings/python/tests/entities/InvalidYaml1.yaml @@ -0,0 +1,14 @@ +# An invalid version of datamodel Valid1.yaml +uri: http://onto-ns.com/meta/0.1/InvalidYaml1 +description: An datamodel for an item with float type and invalid shape name. +dimensions: + nf: Number of eigen-frequencies. +properties: + name: + type: str + description: Name of the item. + f: + type: float64 + shape: [nf_MISPELLED] + unit: Hz + description: The magic eigen-frequencies of the item. diff --git a/bindings/python/tests/entities/ValidYaml1.yaml b/bindings/python/tests/entities/ValidYaml1.yaml new file mode 100644 index 000000000..382cd6efa --- /dev/null +++ b/bindings/python/tests/entities/ValidYaml1.yaml @@ -0,0 +1,14 @@ +# An valid version of datamodel Invalid1.yaml +uri: http://onto-ns.com/meta/0.1/ValidYaml1 +description: An datamodel for an item with float type and invalid shape name. +dimensions: + nf: Number of eigen-frequencies. +properties: + name: + type: str + description: Name of the item. + f: + type: float64 + shape: [nf] + unit: Hz + description: The magic eigen-frequencies of the item. diff --git a/bindings/python/tests/test_storage.py b/bindings/python/tests/test_storage.py index 0999353ba..681bb02fd 100755 --- a/bindings/python/tests/test_storage.py +++ b/bindings/python/tests/test_storage.py @@ -127,9 +127,9 @@ location: Path to YAML file. options: Supported options: - `mode`: Mode for opening. Valid values are: - - `a`: Append to existing file or create new file (default). - - `r`: Open existing file for read-only. - - `w`: Truncate existing file or create new file. + - `a`: Open for writing, add to existing `location` (default). + - `r`: Open existing `location` for reading. + - `w`: Open for writing. If `location` exists, it is truncated. - `soft7`: Whether to save using SOFT7 format. - `single`: Whether the input is assumed to be in single-entity form. If "auto" (default) the form will be inferred automatically. diff --git a/storages/python/python-storage-plugins/yaml.py b/storages/python/python-storage-plugins/yaml.py index f8cd7fa7a..22e8cb6b6 100644 --- a/storages/python/python-storage-plugins/yaml.py +++ b/storages/python/python-storage-plugins/yaml.py @@ -24,9 +24,9 @@ def open(self, location: str, options=None): location: Path to YAML file. options: Supported options: - `mode`: Mode for opening. Valid values are: - - `a`: Append to existing file or create new file (default). - - `r`: Open existing file for read-only. - - `w`: Truncate existing file or create new file. + - `a`: Open for writing, add to existing `location` (default). + - `r`: Open existing `location` for reading. + - `w`: Open for writing. If `location` exists, it is truncated. - `soft7`: Whether to save using SOFT7 format. - `single`: Whether the input is assumed to be in single-entity form. If "auto" (default) the form will be inferred automatically. @@ -35,13 +35,13 @@ def open(self, location: str, options=None): self.options = Options( options, defaults="mode=a;soft7=true;single=auto;with_uuid=false" ) - self.readable = "r" in self.options.mode - self.writable = "r" != self.options.mode + mode = self.options.mode + self.writable = "w" in mode or "a" in mode self.generic = True self.location = location - self.flushed = False # whether buffered data has been written to file + self.flushed = True # whether buffered data has been written to file self._data = {} # data buffer - if self.options.mode in ("r", "a", "append"): + if "r" in mode or "a" in mode: with open(location, "r") as f: data = pyyaml.safe_load(f) if data: