import abc
import inspect
from typing import Dict
from large_scale_deploy.tools.errors import ParseError
class StringRepr:
def __repr__(self):
return str(self)
class KeyValue(StringRepr, metaclass=abc.ABCMeta):
def __init__(self, key: str, value: str):
self.key = key
self.value = value
@classmethod
@abc.abstractmethod
def get_delimiter(cls) -> str:
pass
def __str__(self):
return str(self.key) + self.get_delimiter() + str(self.value)
@classmethod
def parse(cls, src_str: str):
parts = src_str.split(cls.get_delimiter())
if len(parts) != 2:
raise ParseError(f"String: {src_str} can't parse to key value by {cls.get_delimiter()}")
return cls(parts[0], parts[1])
class Var(KeyValue):
def __init__(self, option: str, value: str):
super().__init__(option, value)
self.option = option
self.value = value
@classmethod
def get_delimiter(cls):
return "="
class JsonDict(metaclass=abc.ABCMeta):
@staticmethod
def _is_json_dict_in_typing_list(instance, sign_class):
return isinstance(instance, list) and \
isinstance(getattr(sign_class, "__args__"), tuple) and \
len(sign_class.__args__) == 1 and \
issubclass(sign_class.__args__[0], JsonDict)
@classmethod
def from_json(cls, json_dict: Dict):
sigs = inspect.signature(cls.__init__)
args = []
for arg_name, parameter in sigs.parameters.items():
if arg_name == "self":
continue
value = json_dict.get(arg_name)
if value is None:
args.append(None)
continue
sign_class = parameter.annotation
if isinstance(sign_class, type) and issubclass(sign_class, JsonDict):
value = sign_class.from_json(value)
elif cls._is_json_dict_in_typing_list(value, sign_class):
value = [sign_class.__args__[0].from_json(item) for item in value]
args.append(value)
return cls(*args)
def to_json(self):
members = {}
for key, value in vars(self).items():
if key.startswith('__'):
continue
if isinstance(value, JsonDict):
value = value.to_json()
elif isinstance(value, list):
new_value = []
for item in value:
if isinstance(item, JsonDict):
new_value.append(item.to_json())
else:
new_value.append(item)
value = new_value
members[key] = value
return members