bt2: field.py: raise ValueError when setting out of range value to Integer
[babeltrace.git] / src / bindings / python / bt2 / bt2 / field.py
index 4f89d1e43a10ccedcf36c9eff846f9a1f6f09f0e..fbe609eedb473377a3a16ff55ac4091540626bc0 100644 (file)
@@ -180,6 +180,9 @@ class _NumericFieldConst(_FieldConst):
         except Exception:
             return False
 
+    def __hash__(self):
+        return hash(self._value)
+
     def __rmod__(self, other):
         return self._extract_value(other) % self._value
 
@@ -242,7 +245,10 @@ class _NumericFieldConst(_FieldConst):
 
 
 class _NumericField(_NumericFieldConst, _Field):
-    pass
+    def __hash__(self):
+        # Non const field are not hashable as their value may be modified
+        # without changing the underlying Python object.
+        raise TypeError('unhashable type: \'{}\''.format(self._NAME))
 
 
 class _IntegralFieldConst(_NumericFieldConst, numbers.Integral):
@@ -324,7 +330,13 @@ class _IntegerFieldConst(_IntegralFieldConst, _FieldConst):
 
 
 class _IntegerField(_IntegerFieldConst, _IntegralField, _Field):
-    pass
+    def _check_range(self, value):
+        if not (value >= self._lower_bound and value <= self._upper_bound):
+            raise ValueError(
+                "Value {} is outside valid range [{}, {}]".format(
+                    value, self._lower_bound, self._upper_bound
+                )
+            )
 
 
 class _UnsignedIntegerFieldConst(_IntegerFieldConst, _FieldConst):
@@ -335,10 +347,7 @@ class _UnsignedIntegerFieldConst(_IntegerFieldConst, _FieldConst):
         if not isinstance(value, numbers.Integral):
             raise TypeError('expecting an integral number object')
 
-        value = int(value)
-        utils._check_uint64(value)
-
-        return value
+        return int(value)
 
     @property
     def _value(self):
@@ -350,10 +359,21 @@ class _UnsignedIntegerField(_UnsignedIntegerFieldConst, _IntegerField, _Field):
 
     def _set_value(self, value):
         value = self._value_to_int(value)
+
+        self._check_range(value)
+
         native_bt.field_integer_unsigned_set_value(self._ptr, value)
 
     value = property(fset=_set_value)
 
+    @property
+    def _lower_bound(self):
+        return 0
+
+    @property
+    def _upper_bound(self):
+        return (2 ** self.cls.field_value_range) - 1
+
 
 class _SignedIntegerFieldConst(_IntegerFieldConst, _FieldConst):
     _NAME = 'Const signed integer'
@@ -363,10 +383,7 @@ class _SignedIntegerFieldConst(_IntegerFieldConst, _FieldConst):
         if not isinstance(value, numbers.Integral):
             raise TypeError('expecting an integral number object')
 
-        value = int(value)
-        utils._check_int64(value)
-
-        return value
+        return int(value)
 
     @property
     def _value(self):
@@ -378,10 +395,21 @@ class _SignedIntegerField(_SignedIntegerFieldConst, _IntegerField, _Field):
 
     def _set_value(self, value):
         value = self._value_to_int(value)
+
+        self._check_range(value)
+
         native_bt.field_integer_signed_set_value(self._ptr, value)
 
     value = property(fset=_set_value)
 
+    @property
+    def _lower_bound(self):
+        return -1 * (2 ** (self.cls.field_value_range - 1))
+
+    @property
+    def _upper_bound(self):
+        return (2 ** (self.cls.field_value_range - 1)) - 1
+
 
 class _RealFieldConst(_NumericFieldConst, numbers.Real):
     _NAME = 'Const real'
@@ -483,6 +511,9 @@ class _StringFieldConst(_FieldConst):
     def __bool__(self):
         return bool(self._value)
 
+    def __hash__(self):
+        return hash(self._value)
+
     def _repr(self):
         return repr(self._value)
 
@@ -513,6 +544,11 @@ class _StringField(_StringFieldConst, _Field):
         )
         return self
 
+    def __hash__(self):
+        # Non const field are not hashable as their value may be modified
+        # without changing the underlying Python object.
+        raise TypeError('unhashable type: \'{}\''.format(self._NAME))
+
 
 class _ContainerFieldConst(_FieldConst):
     def __bool__(self):
This page took 0.02422 seconds and 4 git commands to generate.