Added create_type. Support for Meta as dict

This commit is contained in:
Syrus Akbary 2017-07-24 21:33:08 -07:00
parent 33a30db5f1
commit 7ca5c2225f
3 changed files with 74 additions and 1 deletions

View File

@ -26,6 +26,10 @@ class BaseOptions(object):
class BaseType(SubclassWithMeta): class BaseType(SubclassWithMeta):
@classmethod
def create_type(cls, class_name, **options):
return type(class_name, (cls, ), {'Meta': options})
@classmethod @classmethod
def __init_subclass_with_meta__(cls, name=None, description=None, _meta=None): def __init_subclass_with_meta__(cls, name=None, description=None, _meta=None):
assert "_meta" not in cls.__dict__, "Can't assign directly meta" assert "_meta" not in cls.__dict__, "Can't assign directly meta"

View File

@ -0,0 +1,63 @@
import pytest
from ..base import BaseType, BaseOptions
class CustomOptions(BaseOptions):
pass
class CustomType(BaseType):
@classmethod
def __init_subclass_with_meta__(cls, **options):
_meta = CustomOptions(cls)
super(CustomType, cls).__init_subclass_with_meta__(_meta=_meta, **options)
def test_basetype():
class MyBaseType(CustomType):
pass
assert isinstance(MyBaseType._meta, CustomOptions)
assert MyBaseType._meta.name == "MyBaseType"
assert MyBaseType._meta.description is None
def test_basetype_nones():
class MyBaseType(CustomType):
'''Documentation'''
class Meta:
name = None
description = None
assert isinstance(MyBaseType._meta, CustomOptions)
assert MyBaseType._meta.name == "MyBaseType"
assert MyBaseType._meta.description == "Documentation"
def test_basetype_custom():
class MyBaseType(CustomType):
'''Documentation'''
class Meta:
name = 'Base'
description = 'Desc'
assert isinstance(MyBaseType._meta, CustomOptions)
assert MyBaseType._meta.name == "Base"
assert MyBaseType._meta.description == "Desc"
def test_basetype_create():
MyBaseType = CustomType.create_type('MyBaseType')
assert isinstance(MyBaseType._meta, CustomOptions)
assert MyBaseType._meta.name == "MyBaseType"
assert MyBaseType._meta.description is None
def test_basetype_create_extra():
MyBaseType = CustomType.create_type('MyBaseType', name='Base', description='Desc')
assert isinstance(MyBaseType._meta, CustomOptions)
assert MyBaseType._meta.name == "Base"
assert MyBaseType._meta.description == "Desc"

View File

@ -1,4 +1,5 @@
import six import six
from inspect import isclass
from ..pyutils.init_subclass import InitSubclassMeta from ..pyutils.init_subclass import InitSubclassMeta
from .props import props from .props import props
@ -18,7 +19,12 @@ class SubclassWithMeta(six.with_metaclass(SubclassWithMeta_Meta)):
_Meta = getattr(cls, "Meta", None) _Meta = getattr(cls, "Meta", None)
_meta_props = {} _meta_props = {}
if _Meta: if _Meta:
_meta_props = props(_Meta) if isinstance(_Meta, dict):
_meta_props = _Meta
elif isclass(_Meta):
_meta_props = props(_Meta)
else:
raise Exception("Meta have to be either a class or a dict. Received {}".format(_Meta))
delattr(cls, "Meta") delattr(cls, "Meta")
options = dict(meta_options, **_meta_props) options = dict(meta_options, **_meta_props)
super_class = super(cls, cls) super_class = super(cls, cls)