Skip to content

Commit

Permalink
Improved typechecking on MultiTypeSerializer init
Browse files Browse the repository at this point in the history
  • Loading branch information
timbernat committed Apr 12, 2024
1 parent dbb1a58 commit e319163
Showing 1 changed file with 23 additions and 3 deletions.
26 changes: 23 additions & 3 deletions polymerist/genutils/fileutils/jsonio/serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from typing import Any, ClassVar, Optional, Type, TypeVar, Union
from abc import ABC, abstractstaticmethod
from inspect import isclass
T = TypeVar('T') # generic type

from pathlib import Path
Expand Down Expand Up @@ -29,7 +30,7 @@ def decode(json_obj : JSONSerializable) -> T:
pass

@classmethod
def encoder_default(cls, python_obj : Any) -> JSONSerializable: # NOTE : this is only called on objects which cannot be JSON serialized by default (i.e. don;t need base case)
def encoder_default(cls, python_obj : Any) -> JSONSerializable: # NOTE : this is only called on objects which cannot be JSON serialized by default (i.e. don't need base case)
'''Augmented Encoder for encoding registered objects along with type info for decoding'''
if isinstance(python_obj, cls.python_type):
return {
Expand All @@ -54,8 +55,27 @@ def decoder_hook(cls, json_dict : dict[JSONSerializable, JSONSerializable]) -> U

class MultiTypeSerializer:
'''For dynamically merging multiple TypeSerializer encoders and decoders'''
def __init__(self, *type_sers) -> None:
self.type_sers = type_sers
def __init__(self, *type_sers : tuple[Type[TypeSerializer]]) -> None:
self._type_sers = []
for ts in type_sers:
self.add_type_serializer(ts)

@property
def type_sers(self) -> list[Type[TypeSerializer]]:
'''Read-only wrapper for the internal registry of TypeSerializers'''
return self._type_sers

def add_type_serializer(self, obj : Union[TypeSerializer, 'MultiTypeSerializer']) -> None: # TODO: add uniqueness check
'''For type, instance, and uniqueness checking of Type '''
if isinstance(obj, TypeSerializer):
self._type_sers.append(obj)
elif isclass(obj) and issubclass(obj, TypeSerializer):
self._type_sers.append(obj()) # instantiate, then add to registered serializers
elif isinstance(obj, MultiTypeSerializer):
for ts in obj.type_sers:
self.add_type_serializer(ts)
else:
raise TypeError(f'Object of type "{obj.__name__ if isclass(obj) else type(obj).__name__}" is not a valid TypeSerializer')

def encoder_default(self, python_obj : Any) -> JSONSerializable:
for type_ser in self.type_sers:
Expand Down

0 comments on commit e319163

Please sign in to comment.