diff --git a/mongoengine/fields.py b/mongoengine/fields.py index b681ac39..6f69465c 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -8,6 +8,8 @@ import uuid import warnings from operator import itemgetter +import six + try: import dateutil except ImportError: @@ -260,10 +262,14 @@ class FloatField(BaseField): return value def validate(self, value): - if isinstance(value, int): - value = float(value) + if isinstance(value, six.integer_types): + try: + value = float(value) + except OverflowError: + self.error('The value is too large to be converted to float') + if not isinstance(value, float): - self.error('FloatField only accepts float values') + self.error('FloatField only accepts float and integer values') if self.min_value is not None and value < self.min_value: self.error('Float value is too small') diff --git a/requirements.txt b/requirements.txt index 03935868..b6a5b06c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ -pymongo>=2.7.1 nose +pymongo>=2.7.1 +six==1.10.0 diff --git a/setup.py b/setup.py index 6aa924c8..e34d834a 100644 --- a/setup.py +++ b/setup.py @@ -78,7 +78,7 @@ setup(name='mongoengine', long_description=LONG_DESCRIPTION, platforms=['any'], classifiers=CLASSIFIERS, - install_requires=['pymongo>=2.7.1'], + install_requires=['pymongo>=2.7.1', 'six'], test_suite='nose.collector', **extra_opts ) diff --git a/tests/fields/fields.py b/tests/fields/fields.py index 757f66a8..1c1f49ad 100644 --- a/tests/fields/fields.py +++ b/tests/fields/fields.py @@ -1,5 +1,7 @@ # -*- coding: utf-8 -*- import sys + +import six from nose.plugins.skip import SkipTest sys.path[0:0] = [""] @@ -399,20 +401,37 @@ class FieldTest(unittest.TestCase): class Person(Document): height = FloatField(min_value=0.1, max_value=3.5) + class BigPerson(Document): + height = FloatField() + person = Person() person.height = 1.89 person.validate() person.height = '2.0' self.assertRaises(ValidationError, person.validate) + person.height = 0.01 self.assertRaises(ValidationError, person.validate) + person.height = 4.0 self.assertRaises(ValidationError, person.validate) person_2 = Person(height='something invalid') self.assertRaises(ValidationError, person_2.validate) + big_person = BigPerson() + + for value, value_type in enumerate(six.integer_types): + big_person.height = value_type(value) + big_person.validate() + + big_person.height = 2 ** 500 + big_person.validate() + + big_person.height = 2 ** 100000 # Too big for a float value + self.assertRaises(ValidationError, big_person.validate) + def test_decimal_validation(self): """Ensure that invalid values cannot be assigned to decimal fields. """