bt2: update value.py, make test_value pass
authorSimon Marchi <simon.marchi@efficios.com>
Fri, 26 Apr 2019 19:41:24 +0000 (15:41 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 3 May 2019 22:19:40 +0000 (18:19 -0400)
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 <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1022
Tested-by: jenkins
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
bindings/python/bt2/bt2/value.py
tests/bindings/python/bt2/test_value.py

index 73366fdf24766cc798fc61ef92913d64ef276b89..1a5612da49ae0bb5baf1011067513b7b40163746 100644 (file)
@@ -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,
index 2b15d104ac0057464e00487c86ddfaa7e1d491dd..6628e0450f11d8c15be8d37c0d5034afcdab343e 100644 (file)
@@ -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)
 
This page took 0.032896 seconds and 4 git commands to generate.