Commits

Matt Chaput committed 2c5c77e

Added slightly better error messages for numeric field values out of range.
Added min_value and max_value attributes to NUMERIC field type.
See issue #342.

Comments (0)

Files changed (2)

src/whoosh/fields.py

             either ``int``, ``float``. If you use ``Decimal``,
             use the ``decimal_places`` argument to control how many decimal
             places the field will store.
+        :param bits: When ``numtype`` is ``int``, the number of bits to use to
+            store the number: 8, 16, 32, or 64.
         :param stored: Whether the value of this field is stored with the
             document.
         :param unique: Whether the value of this field is unique per-document.
             raise Exception("A float type and decimal_places argument %r are "
                             "incompatible" % decimal_places)
 
+        intsizes = [8, 16, 32, 64]
+        intcodes = ["B", "H", "I", "Q"]
         # Set up field configuration based on type and size
         if numtype is float:
             bits = 64  # Floats are converted to 64 bit ints
-        intsizes = [8, 16, 32, 64]
-        intcodes = ["B", "H", "I", "Q"]
-        if bits not in intsizes:
-            raise Exception("Invalid bits %r, use 8, 16, 32, or 64"
-                            % bits)
+        else:
+            if bits not in intsizes:
+                raise Exception("Invalid bits %r, use 8, 16, 32, or 64"
+                                % bits)
         # Type code for the *sortable* representation
         self.sortable_typecode = intcodes[intsizes.index(bits)]
         self._struct = struct.Struct(">" + self.sortable_typecode)
         self.analyzer = analysis.IDAnalyzer()
         self.format = formats.Existence(field_boost=field_boost)
 
+        # Calculate the minimum and maximum possible values for error checking
+        self.min_value = from_sortable(numtype, bits, signed, 0)
+        self.max_value = from_sortable(numtype, bits, signed, 2 ** bits - 1)
+
         # Column configuration
         if default is None:
             if numtype is int:
         if dc and isinstance(x, (string_type, Decimal)):
             x = Decimal(x) * (10 ** dc)
         x = self.numtype(x)
+
+        if x < self.min_value or x > self.max_value:
+            raise ValueError("Numeric field value %s out of range [%s, %s]"
+                             % (x, self.min_value, self.max_value))
         return x
 
     def unprepare_number(self, x):

tests/test_fields.py

         check("{10.2 to 80.8}", "10.4", "80.6")
 
 
+def test_numeric_errors():
+    f = fields.NUMERIC(int, bits=16, signed=True)
+    schema = fields.Schema(f=f)
+
+    with pytest.raises(ValueError):
+        list(f.index(-32769))
+    with pytest.raises(ValueError):
+        list(f.index(32768))
+
+
 def test_nontext_document():
     schema = fields.Schema(id=fields.STORED, num=fields.NUMERIC,
                            date=fields.DATETIME, even=fields.BOOLEAN)