Skip to content

Commit

Permalink
Merge pull request #207 from jacebrowning/load-after-create
Browse files Browse the repository at this point in the history
Automatically load objects after creation via manager
  • Loading branch information
jacebrowning committed Apr 10, 2021
2 parents de13464 + aa6efe8 commit 9a07290
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 6 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
- Added support for generic types.
- Added support for sets.
- Updated default `attrs` to exclude computed properties, i.e. `field(init=False)`.
- Fixed automatic save when modifying nested dictionary values.
- Fixed initialization for non-compliant `None` default values.


# 0.12 (2021-03-05)

Expand Down
4 changes: 3 additions & 1 deletion datafiles/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ def get_or_create(self, *args, **kwargs) -> HasDatafile:
return self.get(*args, **kwargs)
except FileNotFoundError:
log.info(f"File not found, creating '{self.model.__name__}' object")
return self.model(*args, **kwargs)
instance = self.model(*args, **kwargs)
instance.datafile.load()
return instance

def all(self, *, _exclude: str = '') -> Iterator[HasDatafile]:
path = Path(self.model.Meta.datafile_pattern)
Expand Down
10 changes: 6 additions & 4 deletions datafiles/tests/test_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,22 @@ def when_file_missing(expect, manager):
expect(manager.get_or_none(foo=3, bar=4)).is_(None)

def describe_get_or_create():
@patch('datafiles.mapper.Mapper.load')
@patch('datafiles.mapper.Mapper.save')
@patch('datafiles.mapper.Mapper.load')
@patch('datafiles.mapper.Mapper.exists', True)
@patch('datafiles.mapper.Mapper.modified', False)
def when_file_exists(mock_load, mock_save, expect, manager):
def when_file_exists(mock_save, mock_load, expect, manager):
expect(manager.get_or_create(foo=1, bar=2)) == MyClass(foo=1, bar=2)
expect(mock_load.called).is_(False)
expect(mock_save.called).is_(True)
expect(mock_load.called).is_(False)

@patch('datafiles.mapper.Mapper.save')
@patch('datafiles.mapper.Mapper.load')
@patch('datafiles.mapper.Mapper.exists', False)
def when_file_missing(mock_save, expect, manager):
def when_file_missing(mock_save, mock_load, expect, manager):
expect(manager.get_or_create(foo=1, bar=2)) == MyClass(foo=1, bar=2)
expect(mock_save.called).is_(True)
expect(mock_load.called).is_(True)

def describe_all():
@patch('datafiles.mapper.Mapper.exists', False)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[tool.poetry]

name = "datafiles"
version = "0.13b4"
version = "0.13b5"
description = "File-based ORM for dataclasses."

license = "MIT"
Expand Down
11 changes: 11 additions & 0 deletions tests/test_instantiation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# pylint: disable=unused-variable

from dataclasses import dataclass, field
from typing import Dict

from datafiles import Missing, datafile
from datafiles.utils import logbreak, write
Expand Down Expand Up @@ -169,3 +170,13 @@ class Sample:
sample2 = Sample(42, Missing) # type: ignore

expect(sample2.name.value) == "Widget"

def with_none_defaults(expect):
@datafile("../tmp/sample.yml")
class Config:
name: str = None # type: ignore
channels: Dict[str, str] = None # type: ignore

config = Config.objects.get_or_create()
expect(config.name) == ""
expect(config.channels) == {}

0 comments on commit 9a07290

Please sign in to comment.