Skip to content

Commit

Permalink
Merge b4967c4 into 2ba26fe
Browse files Browse the repository at this point in the history
  • Loading branch information
jacebrowning committed Jan 19, 2020
2 parents 2ba26fe + b4967c4 commit afa0148
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 104 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,7 @@

- Added a registration system for custom formatter classes.
- Fixed loading of missing attribute from disk for ORM methods.
- Added support for file patterns relative to the current directory.

# 0.5.1 (2019-11-14)

Expand Down
7 changes: 5 additions & 2 deletions datafiles/mapper.py
Expand Up @@ -57,6 +57,10 @@ def path(self) -> Optional[Path]:
if not self._pattern:
return None

path = Path(self._pattern.format(self=self._instance))
if path.is_absolute() or self._pattern.startswith('./'):
return path.resolve()

cls = self._instance.__class__
try:
root = Path(inspect.getfile(cls)).parent
Expand All @@ -65,8 +69,7 @@ def path(self) -> Optional[Path]:
log.log(level, f'Unable to determine module for {cls}')
root = Path.cwd()

relpath = self._pattern.format(self=self._instance)
return (root / relpath).resolve()
return (root / path).resolve()

@property
def relpath(self) -> Path:
Expand Down
15 changes: 14 additions & 1 deletion datafiles/tests/test_mapper.py
@@ -1,5 +1,6 @@
# pylint: disable=unused-variable

import platform
from dataclasses import dataclass
from pathlib import Path

Expand Down Expand Up @@ -38,11 +39,23 @@ def describe_path():
def is_none_when_no_pattern(expect, mapper):
expect(mapper.path) == None

def is_absolute_based_on_the_file(expect, mapper):
def is_relative_to_file_by_default(expect, mapper):
mapper._pattern = '../../tmp/sample.yml'
root = Path(__file__).parents[2]
expect(mapper.path) == root / 'tmp' / 'sample.yml'

def is_absolute_when_specified(expect, mapper):
mapper._pattern = '/private/tmp/sample.yml'
if platform.system() == 'Windows':
path = Path('C:/private/tmp/sample.yml')
else:
path = Path('/private/tmp/sample.yml')
expect(mapper.path) == path

def is_relative_to_cwd_when_specified(expect, mapper):
mapper._pattern = './foobar/sample.yml'
expect(mapper.path) == Path.cwd() / 'foobar' / 'sample.yml'

def describe_relpath():
def when_cwd_is_parent(expect, mapper):
mapper._pattern = '../../tmp/sample.yml'
Expand Down
22 changes: 13 additions & 9 deletions docs/api/model.md
Expand Up @@ -56,20 +56,24 @@ Item("def") # <=> items/def.yml
```

Attributes included in the filename pattern are automatically excluded from the file contents.
Filename patterns are relative to the file in which models are defined unless `<pattern>` is an absolute path.
Filename patterns are relative to the file in which models are defined unless `<pattern>` is an absolute path or explicitly relative to the current directory:

- Absolute: `/tmp/items/{self.name}.yaml`
- Relative to model: `items/{self.name}.yaml`
- Relative to current directory: `./items/{self.name}.yaml`

<h3>Options</h3>

The following options can be passed to the `@datafile()` decorator:

| Name | Type | Description | Default
| --- | --- | --- | --- |
| `attrs` | `dict` | Attributes to synchronize mapped to `datafile.converters` classes for serialization. | `{}` <sup>1</sup> |
| `manual` | `bool` | Synchronize object and file changes manually. | `False` |
| `defaults` | `bool` | Include default values in files. | `False` |
| `auto_load` | `bool` | Load automatically after saving.<br>If `manual=True` this option is ignored. | `True` |
| `auto_save` | `bool` | Save automatically after loading.<br>If `manual=True` this option is ignored. | `True` |
| `auto_attr` | `bool` | Automatically infer new attributes from the file. | `False` |
| Name | Type | Description | Default |
| ----------- | ------ | ------------------------------------------------------------------------------------ | ----------------- |
| `attrs` | `dict` | Attributes to synchronize mapped to `datafile.converters` classes for serialization. | `{}` <sup>1</sup> |
| `manual` | `bool` | Synchronize object and file changes manually. | `False` |
| `defaults` | `bool` | Include default values in files. | `False` |
| `auto_load` | `bool` | Load automatically after saving.<br>If `manual=True` this option is ignored. | `True` |
| `auto_save` | `bool` | Save automatically after loading.<br>If `manual=True` this option is ignored. | `True` |
| `auto_attr` | `bool` | Automatically infer new attributes from the file. | `False` |

<sup>1</sup> _By default, synchronized attributes are inferred from the type annotations._

Expand Down

0 comments on commit afa0148

Please sign in to comment.