From 0cbe576af535987bb0e20a73b2461b8e5e326686 Mon Sep 17 00:00:00 2001 From: Jace Browning Date: Sat, 22 Feb 2025 17:18:53 -0500 Subject: [PATCH 1/2] Fixed initialization of list attributes --- datafiles/manager.py | 6 ++++-- datafiles/mapper.py | 8 ++++---- datafiles/model.py | 3 +-- tests/test_instantiation.py | 3 --- tests/test_loading.py | 10 +++++----- 5 files changed, 14 insertions(+), 16 deletions(-) diff --git a/datafiles/manager.py b/datafiles/manager.py index 1ce0d4c2..f2fc7981 100644 --- a/datafiles/manager.py +++ b/datafiles/manager.py @@ -108,8 +108,11 @@ def get_or_create(self, *args, **kwargs) -> Model: def all(self, *, _exclude: str = "") -> Iterator[Model]: path = Path(self.model.Meta.datafile_pattern).expanduser() if path.is_absolute() or self.model.Meta.datafile_pattern[:2] == "./": - log.debug(f"Detected static pattern: {path}") + log.debug(f"Detected static path pattern: {path}") else: + log.debug( + f"Detected relative path pattern: {self.model.Meta.datafile_pattern}" + ) try: root = Path(inspect.getfile(self.model)).parent except (TypeError, OSError): @@ -117,7 +120,6 @@ def all(self, *, _exclude: str = "") -> Iterator[Model]: log.log(level, f"Unable to determine module for {self.model}") root = Path.cwd() path = root / self.model.Meta.datafile_pattern - log.debug(f"Detected dynamic pattern: {path}") pattern = alt_pattern = str(path.resolve()) for field in dataclasses.fields(self.model): diff --git a/datafiles/mapper.py b/datafiles/mapper.py index 9d55ee9d..305cb574 100644 --- a/datafiles/mapper.py +++ b/datafiles/mapper.py @@ -13,7 +13,7 @@ from cached_property import cached_property from . import config, formats, hooks -from .converters import Converter, List, map_type +from .converters import Converter, map_type from .types import Missing, Trilean from .utils import display, get_default_field_value, recursive_update, write @@ -57,7 +57,7 @@ def path(self) -> Optional[Path]: path = Path(self._pattern.format(self=self._instance)).expanduser() if path.is_absolute() or self._pattern.startswith("./"): - log.debug(f"Detected static pattern: {path}") + log.debug(f"Detected static path pattern: {path}") return path.resolve() cls = self._instance.__class__ @@ -68,8 +68,8 @@ def path(self) -> Optional[Path]: log.log(level, f"Unable to determine module for {cls}") root = Path.cwd() + log.debug(f"Detected relative path pattern: {path}") path = (root / path).resolve() - log.debug(f"Detected dynamic pattern: {path}") return path @property @@ -244,7 +244,7 @@ def _set_value(instance, name, converter, data, first_load): default_value, ) - if init_value != default_value and not issubclass(converter, List): + if init_value != default_value: log.debug(f"Keeping non-default '{name}' init value: {init_value!r}") return diff --git a/datafiles/model.py b/datafiles/model.py index 5ebd465c..4d179641 100644 --- a/datafiles/model.py +++ b/datafiles/model.py @@ -27,8 +27,7 @@ def __post_init__(self): create = not self.datafile.manual if path: - log.debug(f"Datafile path: {path}") - log.debug(f"Datafile exists: {exists}") + log.debug(f"Resolved datafile path: {path} ({exists=})") if exists: self.datafile.load(_first_load=True) diff --git a/tests/test_instantiation.py b/tests/test_instantiation.py index e9f8e1f8..95c4690d 100644 --- a/tests/test_instantiation.py +++ b/tests/test_instantiation.py @@ -5,8 +5,6 @@ from dataclasses import dataclass, field from typing import Dict -import pytest - from datafiles import Missing, datafile from datafiles.utils import logbreak, write @@ -67,7 +65,6 @@ def it_wins_when_no_init_values(expect): expect(sample.foo) == 2 expect(sample.bar) == "b" - @pytest.mark.xfail(reason="https://github.com/jacebrowning/datafiles/issues/344") def it_loses_against_init_values(expect): write( "tmp/sample.yml", diff --git a/tests/test_loading.py b/tests/test_loading.py index a07e9187..9e945461 100644 --- a/tests/test_loading.py +++ b/tests/test_loading.py @@ -6,7 +6,7 @@ import pytest -from datafiles import datafile +from datafiles import Missing, datafile from datafiles.utils import dedent, logbreak, read, write from . import xfail_with_pep_563 @@ -384,7 +384,7 @@ def with_matching_types(expect): """, ) - sample = SampleWithList(None) + sample = SampleWithList(Missing) expect(sample.items) == [1.2, 3.4] @@ -396,7 +396,7 @@ def with_conversion(expect): """, ) - sample = SampleWithList(None) + sample = SampleWithList(Missing) expect(sample.items) == [1.0, 2.3] @@ -452,7 +452,7 @@ def with_matching_types(expect): """, ) - sample = SampleWithSet(None) + sample = SampleWithSet(Missing) expect(sample.items) == {1.2, 3.4} @@ -464,7 +464,7 @@ def with_conversion(expect): """, ) - sample = SampleWithSet(None) + sample = SampleWithSet(Missing) expect(sample.items) == {1.0, 2.3} From 81fa5e9f2a5dbf6ab6c1b0b7d5102688ea3edc73 Mon Sep 17 00:00:00 2001 From: Jace Browning Date: Sat, 22 Feb 2025 17:27:33 -0500 Subject: [PATCH 2/2] Bump version to 2.3.3 --- CHANGELOG.md | 4 ++++ pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78ca3175..2f48f331 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Release Notes +## 2.3.3 (2025-02-23) + +- Fixed list attributes being ignored during initialization with existing files. + ## 2.3.2 (2025-02-23) - Dropped support for Python 3.8 (past end of life). diff --git a/pyproject.toml b/pyproject.toml index c6e4468a..3b23de63 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [tool.poetry] name = "datafiles" -version = "2.3.2" +version = "2.3.3" description = "File-based ORM for dataclasses." license = "MIT"