From 77b70d39c780fd11de8ea650cb30defd92516b4f Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Fri, 26 Apr 2019 15:41:24 -0400 Subject: [PATCH] bt2: update value.py, make test_value pass This patch updates value.py to match the current API. The only known thing missing (to be done later) is to split classes in their const and non-const variants (e.g. BoolValue and BoolValueConst), where the methods that can modify values are only present on the non-const versions. The test is largely unchanged, except for the removal of things related to frozen values. Change-Id: I6424b0e6208ffe2cbe5e60fdd08579326abff29a Signed-off-by: Simon Marchi Reviewed-on: https://review.lttng.org/c/babeltrace/+/1022 Tested-by: jenkins Reviewed-by: Philippe Proulx --- bindings/python/bt2/bt2/value.py | 125 ++++++++-------------- tests/bindings/python/bt2/test_value.py | 132 +++++------------------- 2 files changed, 69 insertions(+), 188 deletions(-) diff --git a/bindings/python/bt2/bt2/value.py b/bindings/python/bt2/bt2/value.py index 73366fdf..1a5612da 100644 --- a/bindings/python/bt2/bt2/value.py +++ b/bindings/python/bt2/bt2/value.py @@ -32,18 +32,7 @@ import bt2 def _handle_status(status, obj_name): if status >= 0: return - - if status == native_bt.VALUE_STATUS_FROZEN: - raise bt2.Frozen('{} value object is frozen'.format(obj_name)) - elif status == native_bt.VALUE_STATUS_INVAL: - # In practice, this should never happen, because arguments - # should always be validated in this Python module before - # calling the native functions. - raise ValueError('unexpected invalid argument') else: - # In practice, this should never happen, because arguments - # should always be validated in this Python module before - # calling the native functions. raise RuntimeError('unexpected error') @@ -55,6 +44,14 @@ def _create_from_ptr(ptr): return _TYPE_TO_OBJ[typeid]._create_from_ptr(ptr) +def _create_from_ptr_and_get_ref(ptr): + if ptr is None or ptr == native_bt.value_null: + return + + typeid = native_bt.value_get_type(ptr) + return _TYPE_TO_OBJ[typeid]._create_from_ptr_and_get_ref(ptr) + + def create_value(value): if value is None: # null value object @@ -70,7 +67,7 @@ def create_value(value): return IntegerValue(value) if isinstance(value, float): - return FloatValue(value) + return RealValue(value) if isinstance(value, str): return StringValue(value) @@ -89,6 +86,9 @@ def create_value(value): class _Value(object._SharedObject, metaclass=abc.ABCMeta): + _get_ref = native_bt.value_get_ref + _put_ref = native_bt.value_put_ref + def __eq__(self, other): if other is None: # self is never the null value object @@ -119,28 +119,12 @@ class _Value(object._SharedObject, metaclass=abc.ABCMeta): def _check_create_status(self, ptr): if ptr is None: - raise bt2.CreationError('cannot create {} value object'.format(self._NAME.lower())) - - def _is_frozen(self): - return native_bt.value_is_frozen(self._ptr) - - def _freeze(self): - status = native_bt.value_freeze(self._ptr) - self._handle_status(status) - - -class _BasicCopy: - def __copy__(self): - return self.__class__(self._value) - - def __deepcopy__(self, memo): - copy = self.__copy__() - memo[id(self)] = copy - return copy + raise bt2.CreationError( + 'cannot create {} value object'.format(self._NAME.lower())) @functools.total_ordering -class _NumericValue(_Value, _BasicCopy): +class _NumericValue(_Value): @staticmethod def _extract_value(other): if isinstance(other, _NumericValue): @@ -340,7 +324,7 @@ class _RealValue(_NumericValue, numbers.Real): pass -class BoolValue(_Value, _BasicCopy): +class BoolValue(_Value): _NAME = 'Boolean' def __init__(self, value=None): @@ -373,13 +357,11 @@ class BoolValue(_Value, _BasicCopy): @property def _value(self): - status, value = native_bt.value_bool_get(self._ptr) - assert(status == native_bt.VALUE_STATUS_OK) - return value > 0 + value = native_bt.value_bool_get(self._ptr) + return value != 0 def _set_value(self, value): - status = native_bt.value_bool_set(self._ptr, self._value_to_bool(value)) - self._handle_status(status) + native_bt.value_bool_set(self._ptr, self._value_to_bool(value)) value = property(fset=_set_value) @@ -406,26 +388,23 @@ class IntegerValue(_IntegralValue): @property def _value(self): - status, value = native_bt.value_integer_get(self._ptr) - assert(status == native_bt.VALUE_STATUS_OK) - return value + return native_bt.value_integer_get(self._ptr) def _set_value(self, value): - status = native_bt.value_integer_set(self._ptr, self._value_to_int(value)) - self._handle_status(status) + native_bt.value_integer_set(self._ptr, self._value_to_int(value)) value = property(fset=_set_value) -class FloatValue(_RealValue): - _NAME = 'Floating point number' +class RealValue(_RealValue): + _NAME = 'Real number' def __init__(self, value=None): if value is None: - ptr = native_bt.value_float_create() + ptr = native_bt.value_real_create() else: value = self._value_to_float(value) - ptr = native_bt.value_float_create_init(value) + ptr = native_bt.value_real_create_init(value) self._check_create_status(ptr) super().__init__(ptr) @@ -438,20 +417,16 @@ class FloatValue(_RealValue): @property def _value(self): - status, value = native_bt.value_float_get(self._ptr) - assert(status == native_bt.VALUE_STATUS_OK) - return value + return native_bt.value_real_get(self._ptr) def _set_value(self, value): - value = self._value_to_float(value) - status = native_bt.value_float_set(self._ptr, value) - self._handle_status(status) + native_bt.value_real_set(self._ptr, self._value_to_float(value)) value = property(fset=_set_value) @functools.total_ordering -class StringValue(_BasicCopy, collections.abc.Sequence, _Value): +class StringValue(collections.abc.Sequence, _Value): _NAME = 'String' def __init__(self, value=None): @@ -472,9 +447,7 @@ class StringValue(_BasicCopy, collections.abc.Sequence, _Value): @property def _value(self): - status, value = native_bt.value_string_get(self._ptr) - assert(status == native_bt.VALUE_STATUS_OK) - return value + return native_bt.value_string_get(self._ptr) def _set_value(self, value): status = native_bt.value_string_set(self._ptr, self._value_to_str(value)) @@ -498,7 +471,7 @@ class StringValue(_BasicCopy, collections.abc.Sequence, _Value): return bool(self._value) def __repr__(self): - repr(self._value) + return repr(self._value) def __str__(self): return self._value @@ -520,19 +493,6 @@ class _Container: def __bool__(self): return len(self) != 0 - def __copy__(self): - return self.__class__(self) - - def __deepcopy__(self, memo): - ptr = native_bt.value_copy(self._ptr) - - if ptr is None: - raise RuntimeError('unexpected error: cannot deep-copy {} value object'.format(self._NAME)) - - copy = self.__class__._create_from_ptr(ptr) - memo[id(self)] = copy - return copy - def __delitem__(self, index): raise NotImplementedError @@ -566,7 +526,7 @@ class ArrayValue(_Container, collections.abc.MutableSequence, _Value): return def __len__(self): - size = native_bt.value_array_size(self._ptr) + size = native_bt.value_array_get_size(self._ptr) assert(size >= 0) return size @@ -582,9 +542,9 @@ class ArrayValue(_Container, collections.abc.MutableSequence, _Value): def __getitem__(self, index): self._check_index(index) - ptr = native_bt.value_array_get(self._ptr, index) + ptr = native_bt.value_array_borrow_element_by_index(self._ptr, index) assert(ptr) - return _create_from_ptr(ptr) + return _create_from_ptr_and_get_ref(ptr) def __setitem__(self, index, value): self._check_index(index) @@ -595,7 +555,8 @@ class ArrayValue(_Container, collections.abc.MutableSequence, _Value): else: ptr = value._ptr - status = native_bt.value_array_set(self._ptr, index, ptr) + status = native_bt.value_array_set_element_by_index( + self._ptr, index, ptr) self._handle_status(status) def append(self, value): @@ -606,7 +567,7 @@ class ArrayValue(_Container, collections.abc.MutableSequence, _Value): else: ptr = value._ptr - status = native_bt.value_array_append(self._ptr, ptr) + status = native_bt.value_array_append_element(self._ptr, ptr) self._handle_status(status) def __iadd__(self, iterable): @@ -628,7 +589,7 @@ class _MapValueKeyIterator(collections.abc.Iterator): def __init__(self, map_obj): self._map_obj = map_obj self._at = 0 - keys_ptr = native_bt.value_map_get_keys_private(map_obj._ptr) + keys_ptr = native_bt.value_map_get_keys(map_obj._ptr) if keys_ptr is None: raise RuntimeError('unexpected error: cannot get map value object keys') @@ -685,13 +646,13 @@ class MapValue(_Container, collections.abc.MutableMapping, _Value): return def __len__(self): - size = native_bt.value_map_size(self._ptr) + size = native_bt.value_map_get_size(self._ptr) assert(size >= 0) return size def __contains__(self, key): self._check_key_type(key) - return native_bt.value_map_has_key(self._ptr, key) + return native_bt.value_map_has_entry(self._ptr, key) def _check_key_type(self, key): utils._check_str(key) @@ -702,9 +663,9 @@ class MapValue(_Container, collections.abc.MutableMapping, _Value): def __getitem__(self, key): self._check_key(key) - ptr = native_bt.value_map_get(self._ptr, key) + ptr = native_bt.value_map_borrow_entry_value(self._ptr, key) assert(ptr) - return _create_from_ptr(ptr) + return _create_from_ptr_and_get_ref(ptr) def __iter__(self): return _MapValueKeyIterator(self) @@ -718,7 +679,7 @@ class MapValue(_Container, collections.abc.MutableMapping, _Value): else: ptr = value._ptr - status = native_bt.value_map_insert(self._ptr, key, ptr) + status = native_bt.value_map_insert_entry(self._ptr, key, ptr) self._handle_status(status) def __repr__(self): @@ -729,7 +690,7 @@ class MapValue(_Container, collections.abc.MutableMapping, _Value): _TYPE_TO_OBJ = { native_bt.VALUE_TYPE_BOOL: BoolValue, native_bt.VALUE_TYPE_INTEGER: IntegerValue, - native_bt.VALUE_TYPE_REAL: FloatValue, + native_bt.VALUE_TYPE_REAL: RealValue, native_bt.VALUE_TYPE_STRING: StringValue, native_bt.VALUE_TYPE_ARRAY: ArrayValue, native_bt.VALUE_TYPE_MAP: MapValue, diff --git a/tests/bindings/python/bt2/test_value.py b/tests/bindings/python/bt2/test_value.py index 2b15d104..6628e045 100644 --- a/tests/bindings/python/bt2/test_value.py +++ b/tests/bindings/python/bt2/test_value.py @@ -7,45 +7,14 @@ import copy import bt2 -class _TestFrozen: - def test_is_frozen(self): - self._def.freeze() - self.assertTrue(self._def.is_frozen) - - def test_frozen(self): - self._def.freeze() - self.assertTrue(self._def.frozen) - - def test_frozen_exc(self): - self._def.freeze() - - with self.assertRaisesRegex(bt2.Frozen, r'.* value object is frozen$') as cm: - self._modify_def() - - self.assertEqual(self._def, self._def_value) - - def test_get_value_when_frozen(self): - self._def.freeze() - self.assertEqual(self._def, self._def_value) - - -class _TestFrozenSimple(_TestFrozen): - def _modify_def(self): - self._def.value = self._def_new_value - - class _TestCopySimple: def test_copy(self): - cpy = copy.copy(self._def) - self.assertIsNot(cpy, self._def) - self.assertNotEqual(cpy.addr, self._def.addr) - self.assertEqual(cpy, self._def) + with self.assertRaises(NotImplementedError): + copy.copy(self._def) def test_deepcopy(self): - cpy = copy.deepcopy(self._def) - self.assertIsNot(cpy, self._def) - self.assertNotEqual(cpy.addr, self._def.addr) - self.assertEqual(cpy, self._def) + with self.assertRaises(NotImplementedError): + copy.deepcopy(self._def) _COMP_BINOPS = ( @@ -54,7 +23,7 @@ _COMP_BINOPS = ( ) -class _TestNumericValue(_TestFrozenSimple, _TestCopySimple): +class _TestNumericValue(_TestCopySimple): def _binop(self, op, rhs): rexc = None rvexc = None @@ -126,7 +95,7 @@ class _TestNumericValue(_TestFrozenSimple, _TestCopySimple): self.assertEqual(self._def.addr, addr_before) def _test_unaryop_value_same(self, op): - value_before = copy.copy(self._def) + value_before = self._def.__class__(self._def) self._unaryop(op) self.assertEqual(self._def, value_before) @@ -156,7 +125,7 @@ class _TestNumericValue(_TestFrozenSimple, _TestCopySimple): self.assertEqual(self._def.addr, addr_before) def _test_binop_lhs_value_same(self, op, rhs): - value_before = copy.copy(self._def) + value_before = self._def.__class__(self._def) r, rv = self._binop(op, rhs) self.assertEqual(self._def, value_before) @@ -720,7 +689,6 @@ def _inject_numeric_testing_methods(cls): setattr(cls, test_ibinop_name('value_zero_vfloat'), partialmethod(_TestNumericValue._test_ibinop_value_zero_vfloat, op=ibinop)) -@unittest.skip("this is broken") class CreateValueFuncTestCase(unittest.TestCase): def test_create_none(self): v = bt2.create_value(None) @@ -751,13 +719,13 @@ class CreateValueFuncTestCase(unittest.TestCase): def test_create_float_pos(self): raw = 17.5 v = bt2.create_value(raw) - self.assertIsInstance(v, bt2.FloatValue) + self.assertIsInstance(v, bt2.RealValue) self.assertEqual(v, raw) def test_create_float_neg(self): raw = -17.5 v = bt2.create_value(raw) - self.assertIsInstance(v, bt2.FloatValue) + self.assertIsInstance(v, bt2.RealValue) self.assertEqual(v, raw) def test_create_string(self): @@ -823,8 +791,7 @@ class CreateValueFuncTestCase(unittest.TestCase): v = bt2.create_value(a) -@unittest.skip("this is broken") -class BoolValueTestCase(_TestFrozenSimple, _TestCopySimple, unittest.TestCase): +class BoolValueTestCase(_TestCopySimple, unittest.TestCase): def setUp(self): self._f = bt2.BoolValue(False) self._t = bt2.BoolValue(True) @@ -916,7 +883,6 @@ class BoolValueTestCase(_TestFrozenSimple, _TestCopySimple, unittest.TestCase): self.assertNotEqual(self._t, False) -@unittest.skip("this is broken") class IntegerValueTestCase(_TestNumericValue, unittest.TestCase): def setUp(self): self._pv = 23 @@ -1026,13 +992,12 @@ class IntegerValueTestCase(_TestNumericValue, unittest.TestCase): _inject_numeric_testing_methods(IntegerValueTestCase) -@unittest.skip("this is broken") -class FloatValueTestCase(_TestNumericValue, unittest.TestCase): +class RealValueTestCase(_TestNumericValue, unittest.TestCase): def setUp(self): self._pv = 23.4 self._nv = -52.7 - self._fp = bt2.FloatValue(self._pv) - self._fn = bt2.FloatValue(self._nv) + self._fp = bt2.RealValue(self._pv) + self._fn = bt2.RealValue(self._nv) self._def = self._fp self._def_value = self._pv self._def_new_value = -101.88 @@ -1051,7 +1016,7 @@ class FloatValueTestCase(_TestNumericValue, unittest.TestCase): cb() def test_create_default(self): - f = bt2.FloatValue() + f = bt2.RealValue() self.assertEqual(f, 0.0) def test_create_pos(self): @@ -1061,30 +1026,30 @@ class FloatValueTestCase(_TestNumericValue, unittest.TestCase): self.assertEqual(self._fn, self._nv) def test_create_from_vint(self): - f = bt2.FloatValue(self._fp) + f = bt2.RealValue(self._fp) self.assertEqual(f, self._pv) def test_create_from_false(self): - f = bt2.FloatValue(False) + f = bt2.RealValue(False) self.assertFalse(f) def test_create_from_true(self): - f = bt2.FloatValue(True) + f = bt2.RealValue(True) self.assertTrue(f) def test_create_from_int(self): raw = 17 - f = bt2.FloatValue(raw) + f = bt2.RealValue(raw) self.assertEqual(f, float(raw)) def test_create_from_vint(self): raw = 17 - f = bt2.FloatValue(bt2.create_value(raw)) + f = bt2.RealValue(bt2.create_value(raw)) self.assertEqual(f, float(raw)) def test_create_from_vfloat(self): raw = 17.17 - f = bt2.FloatValue(bt2.create_value(raw)) + f = bt2.RealValue(bt2.create_value(raw)) self.assertEqual(f, raw) def test_create_from_unknown(self): @@ -1092,11 +1057,11 @@ class FloatValueTestCase(_TestNumericValue, unittest.TestCase): pass with self._assert_expecting_float(): - f = bt2.FloatValue(A()) + f = bt2.RealValue(A()) def test_create_from_varray(self): with self._assert_expecting_float(): - f = bt2.FloatValue(bt2.ArrayValue()) + f = bt2.RealValue(bt2.ArrayValue()) def test_assign_true(self): self._def.value = True @@ -1150,11 +1115,10 @@ class FloatValueTestCase(_TestNumericValue, unittest.TestCase): self._test_invalid_op(lambda: ~self._def) -_inject_numeric_testing_methods(FloatValueTestCase) +_inject_numeric_testing_methods(RealValueTestCase) -@unittest.skip("this is broken") -class StringValueTestCase(_TestCopySimple, _TestFrozenSimple, unittest.TestCase): +class StringValueTestCase(_TestCopySimple, unittest.TestCase): def setUp(self): self._def_value = 'Hello, World!' self._def = bt2.StringValue(self._def_value) @@ -1272,8 +1236,7 @@ class StringValueTestCase(_TestCopySimple, _TestFrozenSimple, unittest.TestCase) self.assertEqual(self._def, self._def_value) -@unittest.skip("this is broken") -class ArrayValueTestCase(_TestFrozen, unittest.TestCase): +class ArrayValueTestCase(_TestCopySimple, unittest.TestCase): def setUp(self): self._def_value = [None, False, True, -23, 0, 42, -42.4, 23.17, 'yes'] self._def = bt2.ArrayValue(copy.deepcopy(self._def_value)) @@ -1320,22 +1283,6 @@ class ArrayValueTestCase(_TestFrozen, unittest.TestCase): def test_len(self): self.assertEqual(len(self._def), len(self._def_value)) - def test_copy(self): - to_copy = (1, 2, 'hello', (4, 5.2)) - a = bt2.ArrayValue(to_copy) - cpy = copy.copy(a) - self.assertEqual(a, cpy) - self.assertNotEqual(a.addr, cpy.addr) - self.assertEqual(a[3].addr, cpy[3].addr) - - def test_deepcopy(self): - to_copy = (1, 2, 'hello', (4, 5.2)) - a = bt2.ArrayValue(to_copy) - cpy = copy.deepcopy(a) - self.assertEqual(a, cpy) - self.assertNotEqual(a.addr, cpy.addr) - self.assertNotEqual(a[3].addr, cpy[3].addr) - def test_eq_int(self): self.assertNotEqual(self._def, 23) @@ -1428,8 +1375,7 @@ class ArrayValueTestCase(_TestFrozen, unittest.TestCase): self.assertEqual(velem, elem) -@unittest.skip("this is broken") -class MapValueTestCase(_TestFrozen, unittest.TestCase): +class MapValueTestCase(_TestCopySimple, unittest.TestCase): def setUp(self): self._def_value = { 'none': None, @@ -1478,32 +1424,6 @@ class MapValueTestCase(_TestFrozen, unittest.TestCase): def test_len(self): self.assertEqual(len(self._def), len(self._def_value)) - def test_copy(self): - to_copy = { - 'yes': 1, - 'no': 2, - 's': 'hello', - 'inner': (4, 5.2) - } - m = bt2.MapValue(to_copy) - cpy = copy.copy(m) - self.assertEqual(m, cpy) - self.assertNotEqual(m.addr, cpy.addr) - self.assertEqual(m['inner'].addr, cpy['inner'].addr) - - def test_deepcopy(self): - to_copy = { - 'yes': 1, - 'no': 2, - 's': 'hello', - 'inner': (4, 5.2) - } - m = bt2.MapValue(to_copy) - cpy = copy.deepcopy(m) - self.assertEqual(m, cpy) - self.assertNotEqual(m.addr, cpy.addr) - self.assertNotEqual(m['inner'].addr, cpy['inner'].addr) - def test_eq_int(self): self.assertNotEqual(self._def, 23) -- 2.34.1