Exemplo n.º 1
0
class Profile(fields.WithFields):
    name = fields.field()
    thumbnail = fields.field(type=Image)  # Of type image

    def __init__(self, name, thumbnail):
        self.name = name
        self.thumbnail = thumbnail
Exemplo n.º 2
0
def test_field_basics():
    # pylint: disable=unnecessary-dunder-call

    # Can't use full stop in field name
    with pytest.raises(ValueError):
        fields.FieldProperties(store_as='my.field')

    # Try getting an invalid attribute
    field = fields.field(type=Image)
    with pytest.raises(AttributeError):
        field.area

    # However, this is fine with dynamic fields
    field = fields.field(dynamic=True)
    assert isinstance(field.area, fields.Field)
    # The dynamic property should be propagated
    assert isinstance(field.area.height, fields.Field)

    # By default a field is read/write/deletable depending on the object
    field = fields.field(attr='value')
    ns = argparse.Namespace()
    field.__set__(ns, 5)
    assert field.__get__(ns) == 5
    field.__delete__(ns)
    assert 'value' not in ns.__dict__

    # however, if it is converted to a property it becomes read-only until a setter is given
    ns = argparse.Namespace()
    ns.value = 5
    field = fields.field(attr='value')(lambda obj: getattr(obj, 'value'))
    assert field.__get__(ns) == 5
    with pytest.raises(AttributeError):
        field.__set__(ns, 10)
    # But if we add the setter...
    field.setter(lambda obj, value: setattr(obj, 'value', value))
    field.__set__(ns, 10)
    assert field.__get__(ns) == 10

    # Now check deleting
    with pytest.raises(AttributeError):
        field.__delete__(ns)
    field.deleter(lambda obj: delattr(obj, 'value'))
    field.__delete__(ns)
    with pytest.raises(AttributeError):
        field.__get__(ns)

    # Test unreadable attribute
    field = fields.field(attr='unexistent')

    class Test:
        pass

    with pytest.raises(AttributeError):
        field.__get__(Test())
Exemplo n.º 3
0
class Image(fields.WithFields):
    width = fields.field()
    height = fields.field()
    _fmt = mincepy.field(store_as='format')

    def __init__(self, width: int, height: int, fmt: str, creator=None):
        super().__init__()
        self.width = width
        self.height = height
        self._fmt = fmt
        self._creator = creator

    def area(self):
        return self.width * self.height

    @mincepy.field(store_as='_creator')
    def creator(self):
        return self._creator

    @creator.setter
    def creator(self, value):
        self._creator = value
Exemplo n.º 4
0
class Animal(fields.WithFields):
    def __init__(self):
        self._specie = None

    def set_specie(self, specie):
        self._specie = specie

    def get_specie(self):
        return self._specie

    def del_specie(self):
        del self._specie

    specie = fields.field()(get_specie, set_specie, del_specie)
Exemplo n.º 5
0
def test_nested_fields():
    assert expr.query_expr(Profile.thumbnail.width == 64) == {
        'thumbnail.width': 64
    }

    assert expr.query_expr(Profile.thumbnail == {'width': 64, 'height': 128}) == \
           {'thumbnail': {'width': 64, 'height': 128}}

    # Add a query context
    tag_eq_holiday = fields.field('tag') == 'holiday'
    Profile.thumbnail.set_query_context(tag_eq_holiday)
    # check the query context is being used
    assert expr.query_expr(Profile.thumbnail == {'width': 64, 'height': 128}) == \
           {'$and': [{'tag': 'holiday'}, {'thumbnail': {'width': 64, 'height': 128}}]}

    # now check that it is carried over to 'width'
    assert expr.query_expr(Profile.thumbnail.width == 64) == \
           {'$and': [{'tag': 'holiday'}, {'thumbnail.width': 64}]}
Exemplo n.º 6
0
 class Car(fields.WithFields):
     make = fields.field('_make')
     colour = fields.field(default='red')