class SampleEntity(Entity): id = fields.IntField() name = fields.StringField() slug = fields.StringField() url = fields.UrlField() bool = fields.BooleanField() entity = fields.EntityField('self') collection = fields.CollectionField(fields.StringField) entity_collection = fields.CollectionField(fields.EntityField('self')) date = fields.DateTimeField()
class SelfNonDottedNameEntity(Entity): # 'self' is a special case and is the only non-dotted, # dotted-name class reference that we support. foo = fields.EntityField('self') name = fields.StringField()
class NonDottedNameEntity(Entity): # `Property` is a real class, but this string is not a full # reference, so it can't be resolved and is therefore considered # invalid. foo = fields.EntityField('Property')
class ExistingNonDottedNameEntity(Entity): # `FlexEntity` is a real class and it's likely in the local # import scope, but it's still not considered a supported # dotted-name class reference. foo = fields.EntityField('FlexEntity')
class TestEntity(Entity): foo = fields.EntityField('tests.dottedname.foo.bar.baz.NotCallable')
class RandomStringTestEntity(Entity): foo = fields.EntityField('a.string.with.dots')
class TestEntity(Entity): foo = fields.EntityField('tests.dottedname.foo.bar.baz.Zap')
class PropertyList(Entity): properties = fields.CollectionField(fields.EntityField(Property))
class Property(Entity): name = fields.StringField() nested = fields.EntityField('tests.dottedname.foo.bar.bop.PropertyList')
def __new__(mcs, name, bases, attrs): _fields = {} aliases = {} for base in bases: if hasattr(base, '__fields__'): _fields.update(base.__fields__) if hasattr(base, '__aliases__'): _fields.update(base.__aliases__) for key, val in list(attrs.items()): is_cls = inspect.isclass(val) if isinstance(val, Field): _fields[key] = val attrs.pop(key) elif isinstance(val, Alias): aliases[key] = val attrs.pop(key) elif is_cls and issubclass(val, Field): _fields[key] = val() attrs.pop(key) elif isinstance(val, EntityBase) or (is_cls and issubclass(val, EntityBase)): # Wrap fields assigned to `Entity`s with an `EntityField` _fields[key] = fields.EntityField(val) attrs.pop(key) elif isinstance(val, list) and len(val) == 1: attr = val[0] is_cls = inspect.isclass(attr) if isinstance(attr, EntityBase) or (is_cls and issubclass( attr, EntityBase)): # Lists that contain just an Entity class are treated as # a collection of that Entity _fields[key] = fields.CollectionField( fields.EntityField(attr)) elif isinstance(attr, Field) or (is_cls and issubclass(attr, Field)): # Lists that contain just a Field class are treated as # a collection of that Field _fields[key] = fields.CollectionField(attr) for key, field in _fields.items(): attrs[key] = field.make_descriptor(key) for key, field in aliases.items(): attrs[key] = field.make_descriptor(key) attrs['__fields__'] = _fields attrs['__aliases__'] = aliases new_class = super(EntityMetaClass, mcs).__new__(mcs, name, bases, attrs) for key, field in _fields.items(): field.init(new_class) for key, field in aliases.items(): field.init(new_class) return new_class
class TestEntity(Entity): sub = fields.EntityField(SubEntity)