From 1198c63595288e43f354d8cce6db1e69a38d3a20 Mon Sep 17 00:00:00 2001 From: Francis Deslauriers Date: Mon, 23 Sep 2019 15:25:36 -0400 Subject: [PATCH] bt2: field.py: raise ValueError when setting out of range value to Integer This commit removes the use of `utils._check_int64()` and `utils._check_uint64()` methods as the validity of the value is now checked using the _check_range() method and the existing field class' `_field_value_range` setter property. Signed-off-by: Francis Deslauriers Change-Id: Ib5b33ae5becc9f71b20b17ae0244b6e676b89f75 Reviewed-on: https://review.lttng.org/c/babeltrace/+/2081 Tested-by: jenkins --- src/bindings/python/bt2/bt2/field.py | 40 +++++++++++++++++++------ tests/bindings/python/bt2/test_field.py | 31 ++++++++++++++++--- 2 files changed, 58 insertions(+), 13 deletions(-) diff --git a/src/bindings/python/bt2/bt2/field.py b/src/bindings/python/bt2/bt2/field.py index 1e2ceac3..fbe609ee 100644 --- a/src/bindings/python/bt2/bt2/field.py +++ b/src/bindings/python/bt2/bt2/field.py @@ -330,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): @@ -341,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): @@ -356,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' @@ -369,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): @@ -384,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' diff --git a/tests/bindings/python/bt2/test_field.py b/tests/bindings/python/bt2/test_field.py index 7c00b306..ecf0194c 100644 --- a/tests/bindings/python/bt2/test_field.py +++ b/tests/bindings/python/bt2/test_field.py @@ -1284,12 +1284,35 @@ class _TestIntegerFieldCommon(_TestNumericField): field.value = (2 ** 53) + 1 self.assertEqual(field, raw) - def test_assign_uint_invalid_neg(self): - uint_fc = self._tc.create_unsigned_integer_field_class(32) + def test_assign_uint_out_of_range(self): + uint_fc = self._tc.create_unsigned_integer_field_class(8) field = _create_field(self._tc, uint_fc) - with self.assertRaises(ValueError): - field.value = -23 + with self.assertRaises(ValueError) as ctx: + field.value = 256 + self.assertEqual( + str(ctx.exception), 'Value 256 is outside valid range [0, 255]' + ) + + with self.assertRaises(ValueError) as ctx: + field.value = -1 + self.assertEqual(str(ctx.exception), 'Value -1 is outside valid range [0, 255]') + + def test_assign_int_out_of_range(self): + int_fc = self._tc.create_signed_integer_field_class(8) + field = _create_field(self._tc, int_fc) + + with self.assertRaises(ValueError) as ctx: + field.value = 128 + self.assertEqual( + str(ctx.exception), 'Value 128 is outside valid range [-128, 127]' + ) + + with self.assertRaises(ValueError) as ctx: + field.value = -129 + self.assertEqual( + str(ctx.exception), 'Value -129 is outside valid range [-128, 127]' + ) def test_str_op(self): self.assertEqual(str(self._def), str(self._def_value)) -- 2.34.1