Skip to content

Instantly share code, notes, and snippets.

@cwells
Last active July 3, 2023 19:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cwells/5ace2c66d8f6ddfdbc9407293dec7813 to your computer and use it in GitHub Desktop.
Save cwells/5ace2c66d8f6ddfdbc9407293dec7813 to your computer and use it in GitHub Desktop.
import json
from typing import Any, TypedDict, Union, Callable, Optional
from typeguard import CollectionCheckStrategy, check_type
Serializer = Optional[Callable]
def typed_object_factory(object_type: Any, serializer: Serializer=None):
class TypedObject:
def __init__(self, obj: Any) -> None:
self.object_type: Any = object_type
self._serializer: Serializer = serializer
self._object: Any = self.validate(obj)
def validate(self, value: Any) -> Any:
check_type(
value,
self.object_type,
collection_check_strategy=CollectionCheckStrategy.ALL_ITEMS,
)
return value
def serialize(self):
if self._serializer:
return self._serializer(self._object)
raise NotImplementedError("No serializer defined.")
return TypedObject
class TagType(TypedDict):
name: str
value: Union[str, int]
class ThingType(TypedDict):
name: str
id: int
tags: list[TagType]
Thing: object = typed_object_factory(ThingType, serializer=lambda v: json.dumps(v, indent=2))
thing: Thing = Thing( # succeeds
{
"name": "Foobar 2000",
"id": 100,
"tags": [
{"name": "industry", "value": "Foo"},
{"name": "utility", "value": "Foo preparation"},
]
}
)
print(thing.serialize())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment