Skip to content

Commit

Permalink
[JAC-CLOUD]: Improved Deserialization
Browse files Browse the repository at this point in the history
CHANGES:
 - Manually assign fields from datasource based on dataclass fields
 - Value error will be raised
   - if field is required but not existing from db
   - if field has different type from db
 - default will get populated if field has default/factory and not existing from db
 - excess fields will be included but no type checking

OLD:
 - Uses __init__ generated by dataclass
  • Loading branch information
amadolid committed Oct 11, 2024
1 parent e93ba97 commit d3117dc
Showing 1 changed file with 33 additions and 2 deletions.
35 changes: 33 additions & 2 deletions jac-cloud/jac_cloud/core/architype.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
"""Core constructs for Jac Language."""

from dataclasses import asdict as _asdict, dataclass, field, fields, is_dataclass
from dataclasses import (
MISSING,
asdict as _asdict,
dataclass,
field,
fields,
is_dataclass,
)
from enum import Enum
from os import getenv
from pickle import dumps as pdumps
Expand Down Expand Up @@ -76,7 +83,31 @@ def architype_to_dataclass(cls: type[T], data: dict[str, Any], **kwargs: object)
"""Parse dict to architype."""
_to_dataclass(cls, data)
architype = object.__new__(cls)
architype.__init__(**data, **kwargs) # type: ignore[misc]
hintings = get_type_hints(cls)
if is_dataclass(cls):
for attr in fields(cls):
if (val := data.pop(attr.name, MISSING)) is MISSING:
if attr.default is not MISSING:
setattr(architype, attr.name, attr.default)
elif attr.default_factory is not MISSING and callable(
attr.default_factory
):
setattr(architype, attr.name, attr.default_factory())
else:
raise ValueError(
f"{cls.__name__} requires {attr.name} field with type {hintings[attr.name]}"
)
else:
hinter = hintings[attr.name]
if isinstance(val, hinter):
setattr(architype, attr.name, val)
else:
raise ValueError(
f"Data from datasource has type {val.__class__.__name__}"
f" but {cls.__name__}.{attr.name} requires {hinter}."
)
architype.__dict__.update(data)
architype.__dict__.update(kwargs)
return architype


Expand Down

0 comments on commit d3117dc

Please sign in to comment.