Skip to content

Commit

Permalink
working proof
Browse files Browse the repository at this point in the history
  • Loading branch information
tlambert03 committed Sep 17, 2023
1 parent a398352 commit 45a019b
Show file tree
Hide file tree
Showing 13 changed files with 713 additions and 209 deletions.
8 changes: 5 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ repos:
hooks:
- id: mypy
files: "^src/"
# # you have to add the things you want to type check against here
# additional_dependencies:
# - numpy
additional_dependencies:
- pydantic
- attrs
- dataclassy
- msgspec
20 changes: 17 additions & 3 deletions src/dataclass_compat/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
"""Utilities for providing compatibility with many dataclass-like libraries"""
"""Utilities for providing compatibility with many dataclass-like libraries."""

from importlib.metadata import PackageNotFoundError, version

try:
__version__ = version("dataclass-compat")
except PackageNotFoundError:
__version__ = "uninstalled"
__author__ = "Talley Lambert"
__email__ = "talley.lambert@gmail.com"

__all__ = [
"Field",
"DataclassParams",
"fields",
"asdict",
"astuple",
"replace",
"params",
"Adapter",
"get_adapter",
]

from ._functions import asdict, astuple, fields, get_adapter, params, replace
from ._types import DataclassParams, Field
from .adapters import Adapter
201 changes: 0 additions & 201 deletions src/dataclass_compat/_compat.py

This file was deleted.

37 changes: 37 additions & 0 deletions src/dataclass_compat/_functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from typing import Any

from ._types import DataclassParams, Field
from .adapters import ADAPTER_MODULES, Adapter


def asdict(obj: Any) -> dict[str, Any]:
"""Return a dict representation of obj."""
return get_adapter(obj).asdict(obj)


def astuple(obj: Any) -> tuple[Any, ...]:
"""Return a tuple representation of obj."""
return get_adapter(obj).astuple(obj)


def replace(obj: Any, /, **changes: Any) -> Any:
"""Return a copy of obj with the specified changes."""
return get_adapter(obj).replace(obj, **changes)


def fields(obj: Any | type[Any]) -> tuple[Field, ...]:
"""Return a tuple of fields for the class or instance."""
return get_adapter(obj).fields(obj)


def params(obj: Any) -> DataclassParams:
"""Return parameters used to define the dataclass."""
return get_adapter(obj).params(obj)


def get_adapter(obj: Any) -> Adapter:
"""Return the module of the given object."""
for mod in ADAPTER_MODULES:
if mod.is_instance(obj):
return mod
raise TypeError(f"Unsupported dataclass type: {type(obj)}")
37 changes: 37 additions & 0 deletions src/dataclass_compat/_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from __future__ import annotations

import dataclasses
from types import MappingProxyType
from typing import Any, Callable, Generic, TypeVar

_T = TypeVar("_T")


@dataclasses.dataclass
class Field(Generic[_T]):
name: str
type: type[_T] | None = None
default: _T | dataclasses._MISSING_TYPE = dataclasses.field(
default_factory=lambda: dataclasses.MISSING
)
default_factory: Callable[[], _T] | dataclasses._MISSING_TYPE = dataclasses.field(
default_factory=lambda: dataclasses.MISSING
)
repr: bool = True
hash: bool | None = None
init: bool = True
compare: bool = True
metadata: MappingProxyType[Any, Any] = dataclasses.field(
default_factory=lambda: MappingProxyType({})
)
kw_only: bool = False


@dataclasses.dataclass
class DataclassParams:
init: bool = True
repr: bool = True
eq: bool = True
order: bool = False
unsafe_hash: bool = False
frozen: bool = False
17 changes: 17 additions & 0 deletions src/dataclass_compat/adapters/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""Adapter modules for dataclass_compat."""

from typing import Tuple

from . import _attrs, _dataclasses, _dataclassy, _msgspec, _pydantic
from .protocol import Adapter

# Order matters here. The first adapter to return True for is_instance will be used.
ADAPTER_MODULES: Tuple[Adapter, ...] = (
_attrs,
_dataclassy,
_pydantic,
_msgspec,
_dataclasses,
)

__all__ = ["ADAPTER_MODULES", "Adapter"]
Loading

0 comments on commit 45a019b

Please sign in to comment.