Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
from datetime import datetime
import pytest
from jsonmodels import models, fields, errors
class _DateField(fields.BaseField):
_types = (datetime,)
def test_to_struct_basic():
class Person(models.Base):
name = fields.StringField(required=True)
surname = fields.StringField(required=True)
age = fields.IntField()
cash = fields.FloatField()
alan = Person()
with pytest.raises(errors.ValidationError):
alan.to_struct()
def test_base_field_should_not_be_usable():
class Person(models.Base):
name = fields.BaseField()
alan = Person()
with pytest.raises(errors.ValidationError):
alan.name = 'some name'
with pytest.raises(errors.ValidationError):
alan.name = 2345
def parse_value(self, value):
"""Cast value to `int`, e.g. from string or long"""
parsed = super(IntField, self).parse_value(value)
if parsed is None:
return parsed
return int(parsed)
class FloatField(BaseField):
"""Float field."""
types = (float, int)
class BoolField(BaseField):
"""Bool field."""
types = (bool,)
def parse_value(self, value):
"""Cast value to `bool`."""
parsed = super(BoolField, self).parse_value(value)
return bool(parsed) if parsed is not None else None
class ListField(BaseField):
"""List field."""
types = (list,)
def __str__(self):
data = {}
for name in dir(self):
if name.startswith('_'):
continue
cls_definition = getattr(self.__class__, name, None)
if isinstance(cls_definition, fields.BaseField):
if name in self._set_fields:
data[name] = getattr(self, name)
elif not cls_definition: # Display only instnaces, not classes
data[name] = getattr(self, name)
return str(data)
elif isinstance(field, field_types.EnumField):
field_type = ENUM_TYPE
restrictions = list(field._valid_values)
return field_type, restrictions
elif isinstance(field, field_types.ReferenceField):
model = field._model
return model.__name__, None
elif isinstance(field, fields.StringField):
return STRING_TYPE, None
elif isinstance(field, fields.IntField):
return NUMBER_TYPE, None
elif isinstance(field, fields.FloatField):
return FLOAT_TYPE, None
elif isinstance(field, fields.BoolField):
return BOOL_TYPE, None
elif isinstance(field, fields.BaseField):
return STRING_TYPE, None
else:
return field.__name__, None
Each field can specify its default.
"""
return self._default
def _validate_name(self):
if self.name is None:
return
if not re.match('^[A-Za-z_](([\w\-]*)?\w+)?$', self.name):
raise ValueError('Wrong name', self.name)
def structue_name(self, default):
return self.name if self.name is not None else default
class StringField(BaseField):
"""String field."""
types = six.string_types
class IntField(BaseField):
"""Integer field."""
types = (int,)
def parse_value(self, value):
"""Cast value to `int`, e.g. from string or long"""
parsed = super(IntField, self).parse_value(value)
if parsed is None:
In serialized form it is stored as IP address string:
"ip": "10.0.0.12",
'''
types = (netaddr.IPAddress,)
def parse_value(self, value):
if value is not None:
return netaddr.IPAddress(value)
def to_struct(self, obj):
if obj is not None:
return str(obj)
class IpNetworkField(fields.BaseField):
'''A field that holds netaddr.IPNetwork
In serialized form it is stored as CIDR:
"network": "10.0.0.0/24",
'''
types = (netaddr.IPNetwork,)
def parse_value(self, value):
if value is not None:
return netaddr.IPNetwork(value)
def to_struct(self, obj):
if obj is not None:
return str(obj)
types.append(type.evaluate(owner))
else:
types.append(type)
self.items_types = tuple(types)
def _elem_to_struct(self, value):
try:
return value.to_struct()
except AttributeError:
return value
def to_struct(self, values):
return [self._elem_to_struct(v) for v in values]
class EmbeddedField(BaseField):
"""Field for embedded models."""
def __init__(self, model_types, *args, **kwargs):
self._assign_model_types(model_types)
super(EmbeddedField, self).__init__(*args, **kwargs)
def _assign_model_types(self, model_types):
if not isinstance(model_types, (list, tuple)):
model_types = (model_types,)
types = []
for type_ in model_types:
if isinstance(type_, six.string_types):
types.append(_LazyType(type_))
else:
class IntField(BaseField):
"""Integer field."""
types = (int,)
def parse_value(self, value):
"""Cast value to `int`, e.g. from string or long"""
parsed = super(IntField, self).parse_value(value)
if parsed is None:
return parsed
return int(parsed)
class FloatField(BaseField):
"""Float field."""
types = (float, int)
class BoolField(BaseField):
"""Bool field."""
types = (bool,)
def parse_value(self, value):
"""Cast value to `bool`."""
parsed = super(BoolField, self).parse_value(value)
return bool(parsed) if parsed is not None else None
def get_default_value(self):
return {}
class PortRange(object):
def __init__(self, port_min, port_max):
self.min = port_min
self.max = port_max
@classmethod
def from_min_max(cls, port_min, port_max):
if port_min is not None and port_max is not None:
return cls(port_min, port_max)
class PortRangeField(fields.BaseField):
types = (PortRange,)
def to_struct(self, value):
if value is None or value == [None, None]:
return
return [value.min, value.max]
def parse_value(self, value):
if value is not None:
if isinstance(value, PortRange):
return value
else:
# Raise an error if list in not of 2 values
port_min, port_max = value
return PortRange(port_min, port_max)