Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ install:
- set PATH=C:\Python%PYTHON_MAJOR%%PYTHON_MINOR%\Scripts;%PATH%
# Install system dependencies
- choco install make
- set POETRY_VERSION=1.8.5
- curl -sSL https://install.python-poetry.org | python -
- set PATH=%USERPROFILE%\AppData\Roaming\Python\Scripts;%PATH%
- make doctor
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
python-version: ${{ matrix.python-version }}

- name: Install Poetry
run: curl -sSL https://install.python-poetry.org | python3 -
run: curl -sSL https://install.python-poetry.org | POETRY_VERSION=1.8.5 python3 -

- name: Check dependencies
run: make doctor
Expand Down
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
python 3.11.5
poetry 1.8.2
poetry 1.8.5
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Release Notes

## 2.3.1 (2025-02-11)

- Removed unnecessary `eval()` call to map annotations to types.

## 2.3 (2024-10-30)

- Added support for the [JSON5](https://json5.org) file format.
Expand Down
17 changes: 1 addition & 16 deletions datafiles/converters/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import dataclasses
import inspect
import types
from enum import Enum
from inspect import isclass
Expand Down Expand Up @@ -38,18 +37,6 @@ def register(cls: Union[type, str], converter: type):
register(dict, Dictionary)


def resolve(annotation, obj=None):
if isinstance(annotation, str):
log.debug(f"Attempting to eval {annotation!r} using {obj}")
annotation = annotation.replace("List", "list").replace("Dict", "list")
namespace = inspect.getmodule(obj).__dict__ if obj else None
try:
return eval(annotation, namespace) # pylint: disable=eval-used
except NameError as e:
log.warn(f"Unable to eval: {e}")
return annotation


@cached
def map_type(cls, *, name: str = "", item_cls: Optional[type] = None):
"""Infer the converter type from a dataclass, type, or annotation."""
Expand All @@ -66,7 +53,7 @@ def map_type(cls, *, name: str = "", item_cls: Optional[type] = None):
if dataclasses.is_dataclass(cls):
converters = {}
for field in dataclasses.fields(cls):
converters[field.name] = map_type(resolve(field.type), name=field.name) # type: ignore
converters[field.name] = map_type(field.type, name=field.name) # type: ignore
converter = Dataclass.of_mappings(cls, converters)
log.debug(f"Mapped {cls!r} to new converter: {converter}")
return converter
Expand All @@ -79,8 +66,6 @@ def map_type(cls, *, name: str = "", item_cls: Optional[type] = None):
converter = converter.as_optional()
return converter

cls = resolve(cls)

if hasattr(cls, "__origin__"):
converter = None

Expand Down
4 changes: 2 additions & 2 deletions datafiles/mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from cached_property import cached_property

from . import config, formats, hooks
from .converters import Converter, List, map_type, resolve
from .converters import Converter, List, map_type
from .types import Missing, Trilean
from .utils import display, get_default_field_value, recursive_update, write

Expand Down Expand Up @@ -301,7 +301,7 @@ def create_mapper(obj, root=None) -> Mapper:
for field in [field for field in dataclasses.fields(obj) if field.init]:
self_name = f"self.{field.name}"
if pattern is None or self_name not in pattern:
attrs[field.name] = map_type(resolve(field.type, obj), name=field.name) # type: ignore
attrs[field.name] = map_type(field.type, name=field.name) # type: ignore

return Mapper(
obj,
Expand Down
11 changes: 0 additions & 11 deletions datafiles/tests/test_manager.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# pylint: disable=unused-variable,unused-argument

import os
import shutil
from dataclasses import dataclass
from pathlib import Path
Expand Down Expand Up @@ -42,11 +41,6 @@ def manager(files: Path):
model = create_model(MyClass, pattern="files/{self.foo}.yml")
return Manager(model)

@pytest.fixture
def manager_at_home():
model = create_model(Nested, pattern="~/.{self.name}.json")
return Manager(model)

@pytest.fixture
def manager_with_files(files: Path):
files.mkdir(exist_ok=True)
Expand Down Expand Up @@ -145,11 +139,6 @@ def when_no_files_exist(expect, manager: Manager):
items = list(manager.all())
expect(items) == []

def with_home_directory(expect, manager_at_home: Manager):
items = list(manager_at_home.all())
if "CI" not in os.environ:
expect(len(items)) > 0

def describe_filter():
@patch("datafiles.mapper.Mapper.exists", False)
def when_no_files_exist(expect, manager: Manager):
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 = "2.3"
version = "2.3.1"
description = "File-based ORM for dataclasses."

license = "MIT"
Expand Down
1 change: 1 addition & 0 deletions tests/test_custom_converters_future.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from datafiles import datafile


@pytest.mark.xfail(reason="https://github.com/jacebrowning/datafiles/issues/131")
def test_optional_type(expect):
@datafile("../tmp/sample.yml")
class MyObject:
Expand Down
Loading