1from ..utils.subclass_with_meta import SubclassWithMeta 2from ..utils.trim_docstring import trim_docstring 3import six 4 5if six.PY3: 6 from typing import Type 7 8 9class BaseOptions(object): 10 name = None # type: str 11 description = None # type: str 12 13 _frozen = False # type: bool 14 15 def __init__(self, class_type): 16 self.class_type = class_type # type: Type 17 18 def freeze(self): 19 self._frozen = True 20 21 def __setattr__(self, name, value): 22 if not self._frozen: 23 super(BaseOptions, self).__setattr__(name, value) 24 else: 25 raise Exception("Can't modify frozen Options {}".format(self)) 26 27 def __repr__(self): 28 return "<{} name={}>".format(self.__class__.__name__, repr(self.name)) 29 30 31class BaseType(SubclassWithMeta): 32 @classmethod 33 def create_type(cls, class_name, **options): 34 return type(class_name, (cls,), {"Meta": options}) 35 36 @classmethod 37 def __init_subclass_with_meta__( 38 cls, name=None, description=None, _meta=None, **_kwargs 39 ): 40 assert "_meta" not in cls.__dict__, "Can't assign directly meta" 41 if not _meta: 42 return 43 _meta.name = name or cls.__name__ 44 _meta.description = description or trim_docstring(cls.__doc__) 45 _meta.freeze() 46 cls._meta = _meta 47 super(BaseType, cls).__init_subclass_with_meta__() 48