summaryrefslogtreecommitdiff
path: root/tests/test_everything.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_everything.py')
-rw-r--r--tests/test_everything.py405
1 files changed, 383 insertions, 22 deletions
diff --git a/tests/test_everything.py b/tests/test_everything.py
index 4c4535f..f1f14b7 100644
--- a/tests/test_everything.py
+++ b/tests/test_everything.py
@@ -4,14 +4,10 @@
import unittest
import traceback
+import ctypes
import warnings
-import gc
-gc
-
import sys
-from sys import getrefcount
-import copy
try:
import cairo
has_cairo = True
@@ -37,6 +33,17 @@ else:
UNICHAR = "♥"
+class RawGList(ctypes.Structure):
+ _fields_ = [('data', ctypes.c_void_p),
+ ('next', ctypes.c_void_p),
+ ('prev', ctypes.c_void_p)]
+
+ @classmethod
+ def from_wrapped(cls, obj):
+ offset = sys.getsizeof(object()) # size of PyObject_HEAD
+ return ctypes.POINTER(cls).from_address(id(obj) + offset)
+
+
@unittest.skipUnless(has_cairo, 'built without cairo support')
class TestEverything(unittest.TestCase):
@@ -73,6 +80,123 @@ class TestEverything(unittest.TestCase):
self.assertEqual(surface.get_width(), 10)
self.assertEqual(surface.get_height(), 10)
+ def test_bool(self):
+ self.assertEqual(Everything.test_boolean(False), False)
+ self.assertEqual(Everything.test_boolean(True), True)
+ self.assertEqual(Everything.test_boolean('hello'), True)
+ self.assertEqual(Everything.test_boolean(''), False)
+
+ self.assertEqual(Everything.test_boolean_true(True), True)
+ self.assertEqual(Everything.test_boolean_false(False), False)
+
+ def test_int8(self):
+ self.assertEqual(Everything.test_int8(GObject.G_MAXINT8),
+ GObject.G_MAXINT8)
+ self.assertEqual(Everything.test_int8(GObject.G_MININT8),
+ GObject.G_MININT8)
+ self.assertRaises(ValueError, Everything.test_int8, GObject.G_MAXINT8 + 1)
+
+ self.assertEqual(Everything.test_uint8(GObject.G_MAXUINT8),
+ GObject.G_MAXUINT8)
+ self.assertEqual(Everything.test_uint8(0), 0)
+ self.assertRaises(ValueError, Everything.test_uint8, -1)
+ self.assertRaises(ValueError, Everything.test_uint8, GObject.G_MAXUINT8 + 1)
+
+ def test_int16(self):
+ self.assertEqual(Everything.test_int16(GObject.G_MAXINT16),
+ GObject.G_MAXINT16)
+ self.assertEqual(Everything.test_int16(GObject.G_MININT16),
+ GObject.G_MININT16)
+ self.assertRaises(ValueError, Everything.test_int16, GObject.G_MAXINT16 + 1)
+
+ self.assertEqual(Everything.test_uint16(GObject.G_MAXUINT16),
+ GObject.G_MAXUINT16)
+ self.assertEqual(Everything.test_uint16(0), 0)
+ self.assertRaises(ValueError, Everything.test_uint16, -1)
+ self.assertRaises(ValueError, Everything.test_uint16, GObject.G_MAXUINT16 + 1)
+
+ def test_int32(self):
+ self.assertEqual(Everything.test_int32(GObject.G_MAXINT32),
+ GObject.G_MAXINT32)
+ self.assertEqual(Everything.test_int32(GObject.G_MININT32),
+ GObject.G_MININT32)
+ self.assertRaises(ValueError, Everything.test_int32, GObject.G_MAXINT32 + 1)
+
+ self.assertEqual(Everything.test_uint32(GObject.G_MAXUINT32),
+ GObject.G_MAXUINT32)
+ self.assertEqual(Everything.test_uint32(0), 0)
+ self.assertRaises(ValueError, Everything.test_uint32, -1)
+ self.assertRaises(ValueError, Everything.test_uint32, GObject.G_MAXUINT32 + 1)
+
+ def test_int64(self):
+ self.assertEqual(Everything.test_int64(GObject.G_MAXINT64),
+ GObject.G_MAXINT64)
+ self.assertEqual(Everything.test_int64(GObject.G_MININT64),
+ GObject.G_MININT64)
+ self.assertRaises(ValueError, Everything.test_int64, GObject.G_MAXINT64 + 1)
+
+ self.assertEqual(Everything.test_uint64(GObject.G_MAXUINT64),
+ GObject.G_MAXUINT64)
+ self.assertEqual(Everything.test_uint64(0), 0)
+ self.assertRaises(ValueError, Everything.test_uint64, -1)
+ self.assertRaises(ValueError, Everything.test_uint64, GObject.G_MAXUINT64 + 1)
+
+ def test_int(self):
+ self.assertEqual(Everything.test_int(GObject.G_MAXINT),
+ GObject.G_MAXINT)
+ self.assertEqual(Everything.test_int(GObject.G_MININT),
+ GObject.G_MININT)
+ self.assertRaises(ValueError, Everything.test_int, GObject.G_MAXINT + 1)
+
+ self.assertEqual(Everything.test_uint(GObject.G_MAXUINT),
+ GObject.G_MAXUINT)
+ self.assertEqual(Everything.test_uint(0), 0)
+ self.assertRaises(ValueError, Everything.test_uint, -1)
+ self.assertRaises(ValueError, Everything.test_uint, GObject.G_MAXUINT + 1)
+
+ def test_short(self):
+ self.assertEqual(Everything.test_short(GObject.G_MAXSHORT),
+ GObject.G_MAXSHORT)
+ self.assertEqual(Everything.test_short(GObject.G_MINSHORT),
+ GObject.G_MINSHORT)
+ self.assertRaises(ValueError, Everything.test_short, GObject.G_MAXSHORT + 1)
+
+ self.assertEqual(Everything.test_ushort(GObject.G_MAXUSHORT),
+ GObject.G_MAXUSHORT)
+ self.assertEqual(Everything.test_ushort(0), 0)
+ self.assertRaises(ValueError, Everything.test_ushort, -1)
+ self.assertRaises(ValueError, Everything.test_ushort, GObject.G_MAXUSHORT + 1)
+
+ def test_long(self):
+ self.assertEqual(Everything.test_long(GObject.G_MAXLONG),
+ GObject.G_MAXLONG)
+ self.assertEqual(Everything.test_long(GObject.G_MINLONG),
+ GObject.G_MINLONG)
+ self.assertRaises(ValueError, Everything.test_long, GObject.G_MAXLONG + 1)
+
+ self.assertEqual(Everything.test_ulong(GObject.G_MAXULONG),
+ GObject.G_MAXULONG)
+ self.assertEqual(Everything.test_ulong(0), 0)
+ self.assertRaises(ValueError, Everything.test_ulong, -1)
+ self.assertRaises(ValueError, Everything.test_ulong, GObject.G_MAXULONG + 1)
+
+ def test_size(self):
+ self.assertEqual(Everything.test_ssize(GObject.G_MAXSSIZE),
+ GObject.G_MAXSSIZE)
+ self.assertEqual(Everything.test_ssize(GObject.G_MINSSIZE),
+ GObject.G_MINSSIZE)
+ self.assertRaises(ValueError, Everything.test_ssize, GObject.G_MAXSSIZE + 1)
+
+ self.assertEqual(Everything.test_size(GObject.G_MAXSIZE),
+ GObject.G_MAXSIZE)
+ self.assertEqual(Everything.test_size(0), 0)
+ self.assertRaises(ValueError, Everything.test_size, -1)
+ self.assertRaises(ValueError, Everything.test_size, GObject.G_MAXSIZE + 1)
+
+ def test_timet(self):
+ self.assertEqual(Everything.test_timet(42), 42)
+ self.assertRaises(ValueError, Everything.test_timet, GObject.G_MAXUINT64 + 1)
+
def test_unichar(self):
self.assertEqual("c", Everything.test_unichar("c"))
@@ -82,6 +206,96 @@ class TestEverything(unittest.TestCase):
self.assertRaises(TypeError, Everything.test_unichar, "")
self.assertRaises(TypeError, Everything.test_unichar, "morethanonechar")
+ def test_float(self):
+ self.assertEqual(Everything.test_float(GObject.G_MAXFLOAT),
+ GObject.G_MAXFLOAT)
+ self.assertEqual(Everything.test_float(GObject.G_MINFLOAT),
+ GObject.G_MINFLOAT)
+ self.assertRaises(ValueError, Everything.test_float, GObject.G_MAXFLOAT * 2)
+
+ def test_double(self):
+ self.assertEqual(Everything.test_double(GObject.G_MAXDOUBLE),
+ GObject.G_MAXDOUBLE)
+ self.assertEqual(Everything.test_double(GObject.G_MINDOUBLE),
+ GObject.G_MINDOUBLE)
+ self.assertRaises(ValueError, Everything.test_double, GObject.G_MAXDOUBLE * 2)
+
+ (two, three) = Everything.test_multi_double_args(2.5)
+ self.assertAlmostEqual(two, 5.0)
+ self.assertAlmostEqual(three, 7.5)
+
+ def test_value(self):
+ self.assertEqual(Everything.test_int_value_arg(GObject.G_MAXINT), GObject.G_MAXINT)
+ self.assertEqual(Everything.test_value_return(GObject.G_MAXINT), GObject.G_MAXINT)
+
+ def test_variant(self):
+ v = Everything.test_gvariant_i()
+ self.assertEqual(v.get_type_string(), 'i')
+ self.assertEqual(v.get_int32(), 1)
+
+ v = Everything.test_gvariant_s()
+ self.assertEqual(v.get_type_string(), 's')
+ self.assertEqual(v.get_string(), 'one')
+
+ v = Everything.test_gvariant_v()
+ self.assertEqual(v.get_type_string(), 'v')
+ vi = v.get_variant()
+ self.assertEqual(vi.get_type_string(), 's')
+ self.assertEqual(vi.get_string(), 'contents')
+
+ v = Everything.test_gvariant_as()
+ self.assertEqual(v.get_type_string(), 'as')
+ self.assertEqual(v.get_strv(), ['one', 'two', 'three'])
+
+ v = Everything.test_gvariant_asv()
+ self.assertEqual(v.get_type_string(), 'a{sv}')
+ self.assertEqual(v.lookup_value('nosuchkey', None), None)
+ name = v.lookup_value('name', None)
+ self.assertEqual(name.get_string(), 'foo')
+ timeout = v.lookup_value('timeout', None)
+ self.assertEqual(timeout.get_int32(), 10)
+
+ def test_string(self):
+ const_str = b'const \xe2\x99\xa5 utf8'
+ if sys.version_info >= (3, 0):
+ const_str = const_str.decode('UTF-8')
+ noconst_str = 'non' + const_str
+
+ self.assertEqual(Everything.test_utf8_const_return(), const_str)
+ self.assertEqual(Everything.test_utf8_nonconst_return(), noconst_str)
+ self.assertEqual(Everything.test_utf8_out(), noconst_str)
+
+ Everything.test_utf8_const_in(const_str)
+ self.assertEqual(Everything.test_utf8_inout(const_str), noconst_str)
+
+ self.assertEqual(Everything.test_filename_return(), ['åäö', '/etc/fstab'])
+
+ # returns g_utf8_strlen() in out argument
+ self.assertEqual(Everything.test_int_out_utf8(''), 0)
+ self.assertEqual(Everything.test_int_out_utf8('hello world'), 11)
+ self.assertEqual(Everything.test_int_out_utf8('åäö'), 3)
+
+ self.assertEqual(Everything.test_utf8_out_out(), ('first', 'second'))
+ self.assertEqual(Everything.test_utf8_out_nonconst_return(), ('first', 'second'))
+
+ def test_enum(self):
+ self.assertEqual(Everything.test_enum_param(Everything.TestEnum.VALUE1), 'value1')
+ self.assertEqual(Everything.test_enum_param(Everything.TestEnum.VALUE3), 'value3')
+ self.assertRaises(TypeError, Everything.test_enum_param, 'hello')
+
+ # FIXME: ValueError: invalid enum value: 2147483648
+ @unittest.expectedFailure
+ def test_enum_unsigned(self):
+ self.assertEqual(Everything.test_unsigned_enum_param(Everything.TestEnumUnsigned.VALUE1), 'value1')
+ self.assertEqual(Everything.test_unsigned_enum_param(Everything.TestEnumUnsigned.VALUE3), 'value3')
+ self.assertRaises(TypeError, Everything.test_unsigned_enum_param, 'hello')
+
+ def test_flags(self):
+ result = Everything.global_get_flags_out()
+ # assert that it's not an int
+ self.assertEqual(type(result), Everything.TestFlags)
+ self.assertEqual(result, Everything.TestFlags.FLAG1 | Everything.TestFlags.FLAG3)
+
def test_floating(self):
e = Everything.TestFloating()
self.assertEqual(e.__grefcount__, 1)
@@ -121,6 +335,9 @@ class TestEverything(unittest.TestCase):
self.assertEqual(struct_b.nested_a.some_double, struct_b_clone.nested_a.some_double)
self.assertEqual(struct_b.nested_a.some_enum, struct_b_clone.nested_a.some_enum)
+ struct_a = Everything.test_struct_a_parse('ignored')
+ self.assertEqual(struct_a.some_int, 23)
+
def test_wrong_type_of_arguments(self):
try:
Everything.test_int8()
@@ -173,6 +390,34 @@ class TestEverything(unittest.TestCase):
# test that there are no duplicates returned
self.assertEqual(len(attr_list), len(set(attr_list)))
+ def test_array(self):
+ self.assertEqual(Everything.test_array_int_in([]), 0)
+ self.assertEqual(Everything.test_array_int_in([1, 5, -2]), 4)
+ self.assertEqual(Everything.test_array_int_out(), [0, 1, 2, 3, 4])
+ self.assertEqual(Everything.test_array_int_full_out(), [0, 1, 2, 3, 4])
+ self.assertEqual(Everything.test_array_int_none_out(), [1, 2, 3, 4, 5])
+ self.assertEqual(Everything.test_array_int_inout([1, 5, 42, -8]), [6, 43, -7])
+
+ if sys.version_info >= (3, 0):
+ self.assertEqual(Everything.test_array_gint8_in(b'\x01\x03\x05'), 9)
+ self.assertEqual(Everything.test_array_gint8_in([1, 3, 5, -50]), -41)
+ self.assertEqual(Everything.test_array_gint16_in([256, 257, -1000, 10000]), 9513)
+ self.assertEqual(Everything.test_array_gint32_in([30000, 1, -2]), 29999)
+ self.assertEqual(Everything.test_array_gint64_in([2 ** 33, 2 ** 34]), 2 ** 33 + 2 ** 34)
+
+ self.assertEqual(Everything.test_array_gtype_in(
+ [GObject.TYPE_STRING, GObject.TYPE_UINT64, GObject.TYPE_VARIANT]),
+ '[gchararray,guint64,GVariant,]')
+
+ def test_array_fixed_size(self):
+ # fixed length of 5
+ self.assertEqual(Everything.test_array_fixed_size_int_in([1, 2, -10, 5, 3]), 1)
+ self.assertRaises(ValueError, Everything.test_array_fixed_size_int_in, [1, 2, 3, 4])
+ self.assertRaises(ValueError, Everything.test_array_fixed_size_int_in, [1, 2, 3, 4, 5, 6])
+
+ self.assertEqual(Everything.test_array_fixed_size_int_out(), [0, 1, 2, 3, 4])
+ self.assertEqual(Everything.test_array_fixed_size_int_return(), [0, 1, 2, 3, 4])
+
def test_ptrarray(self):
# transfer container
result = Everything.test_garray_container_return()
@@ -184,7 +429,43 @@ class TestEverything(unittest.TestCase):
self.assertEqual(result, ['regress'])
result = None
+ def test_strv(self):
+ self.assertEqual(Everything.test_strv_out(), ['thanks', 'for', 'all', 'the', 'fish'])
+ self.assertEqual(Everything.test_strv_out_c(), ['thanks', 'for', 'all', 'the', 'fish'])
+ self.assertEqual(Everything.test_strv_out_container(), ['1', '2', '3'])
+ self.assertEqual(Everything.test_strv_outarg(), ['1', '2', '3'])
+
+ self.assertEqual(Everything.test_strv_in_gvalue(), ['one', 'two', 'three'])
+
+ Everything.test_strv_in(['1', '2', '3'])
+
+ def test_glist(self):
+ self.assertEqual(Everything.test_glist_nothing_return(), ['1', '2', '3'])
+ self.assertEqual(Everything.test_glist_nothing_return2(), ['1', '2', '3'])
+ self.assertEqual(Everything.test_glist_container_return(), ['1', '2', '3'])
+ self.assertEqual(Everything.test_glist_everything_return(), ['1', '2', '3'])
+
+ Everything.test_glist_nothing_in(['1', '2', '3'])
+ Everything.test_glist_nothing_in2(['1', '2', '3'])
+
+ def test_gslist(self):
+ self.assertEqual(Everything.test_gslist_nothing_return(), ['1', '2', '3'])
+ self.assertEqual(Everything.test_gslist_nothing_return2(), ['1', '2', '3'])
+ self.assertEqual(Everything.test_gslist_container_return(), ['1', '2', '3'])
+ self.assertEqual(Everything.test_gslist_everything_return(), ['1', '2', '3'])
+
+ Everything.test_gslist_nothing_in(['1', '2', '3'])
+ Everything.test_gslist_nothing_in2(['1', '2', '3'])
+
def test_hash_return(self):
+ expected = {'foo': 'bar', 'baz': 'bat', 'qux': 'quux'}
+
+ self.assertEqual(Everything.test_ghash_null_return(), None)
+ self.assertEqual(Everything.test_ghash_nothing_return(), expected)
+ self.assertEqual(Everything.test_ghash_nothing_return(), expected)
+ self.assertEqual(Everything.test_ghash_container_return(), expected)
+ self.assertEqual(Everything.test_ghash_everything_return(), expected)
+
result = Everything.test_ghash_gvalue_return()
self.assertEqual(result['integer'], 12)
self.assertEqual(result['boolean'], True)
@@ -194,6 +475,11 @@ class TestEverything(unittest.TestCase):
self.assertEqual(result['enum'], Everything.TestEnum.VALUE2)
result = None
+ # FIXME: CRITICAL **: Unsupported type ghash
+ def disabled_test_hash_return_nested(self):
+ self.assertEqual(Everything.test_ghash_nested_everything_return(), {})
+ self.assertEqual(Everything.test_ghash_nested_everything_return2(), {})
+
def test_hash_in(self):
# specifying a simple string array for "strings" does not work due to
# https://bugzilla.gnome.org/show_bug.cgi?id=666636
@@ -201,6 +487,11 @@ class TestEverything(unittest.TestCase):
class GStrv(list):
__gtype__ = GObject.TYPE_STRV
+ expected = {'foo': 'bar', 'baz': 'bat', 'qux': 'quux'}
+
+ Everything.test_ghash_nothing_in(expected)
+ Everything.test_ghash_nothing_in2(expected)
+
data = {'integer': 12,
'boolean': True,
'string': 'some text',
@@ -212,24 +503,24 @@ class TestEverything(unittest.TestCase):
data = None
def test_struct_gpointer(self):
- l1 = GLib.List()
- self.assertEqual(l1.data, None)
- init_refcount = getrefcount(l1)
+ glist = GLib.List()
+ raw = RawGList.from_wrapped(glist)
+
+ self.assertEqual(glist.data, None)
+ self.assertEqual(raw.contents.data, None)
- l1.data = 'foo'
- self.assertEqual(l1.data, 'foo')
+ glist.data = 123
+ self.assertEqual(glist.data, 123)
+ self.assertEqual(raw.contents.data, 123)
- l2 = l1
- self.assertEqual(l1.data, l2.data)
- self.assertEqual(getrefcount(l1), init_refcount + 1)
+ glist.data = None
+ self.assertEqual(glist.data, None)
+ self.assertEqual(raw.contents.data, None)
- l3 = copy.copy(l1)
- l3.data = 'bar'
- self.assertEqual(l1.data, 'foo')
- self.assertEqual(l2.data, 'foo')
- self.assertEqual(l3.data, 'bar')
- self.assertEqual(getrefcount(l1), init_refcount + 1)
- self.assertEqual(getrefcount(l3), init_refcount)
+ # Setting to anything other than an int should raise
+ self.assertRaises(TypeError, setattr, glist.data, 'nan')
+ self.assertRaises(TypeError, setattr, glist.data, object())
+ self.assertRaises(TypeError, setattr, glist.data, 123.321)
def test_struct_opaque(self):
# we should get a sensible error message
@@ -375,13 +666,37 @@ class TestCallbacks(unittest.TestCase):
def callback():
TestCallbacks.called += 1
- return 0
+ return TestCallbacks.called
refcount = sys.getrefcount(callback)
- Everything.test_multi_callback(callback)
+ result = Everything.test_multi_callback(callback)
+ # first callback should give 1, second 2, and the function sums them up
+ self.assertEqual(result, 3)
self.assertEqual(TestCallbacks.called, 2)
self.assertEqual(sys.getrefcount(callback), refcount)
+ # FIXME: TypeError: callback() takes 2 positional arguments but 4 were given
+ # does not remove the array length arguments
+ @unittest.expectedFailure
+ def test_callback_scope_call_array(self):
+ # This tests a callback that gets called multiple times from a
+ # single scope call in python with array arguments
+ TestCallbacks.callargs = []
+
+ # works with:
+ #def callback(one, one_length, two, two_length):
+ def callback(one, two):
+ TestCallbacks.callargs.append((one, two))
+ return len(TestCallbacks.callargs)
+
+ refcount = sys.getrefcount(callback)
+ result = Everything.test_array_callback(callback)
+ # first callback should give 1, second 2, and the function sums them up
+ self.assertEqual(result, 3)
+ self.assertEqual(TestCallbacks.callargs,
+ [([-1, 0, 1, 2], ['one', 'two', 'three'])] * 2)
+ self.assertEqual(sys.getrefcount(callback), refcount)
+
def test_callback_userdata(self):
TestCallbacks.called = 0
@@ -556,6 +871,16 @@ class TestCallbacks(unittest.TestCase):
@unittest.skipUnless(has_cairo, 'built without cairo support')
class TestClosures(unittest.TestCase):
+ def test_no_arg(self):
+ def callback():
+ self.called = True
+ return 42
+
+ self.called = False
+ result = Everything.test_closure(callback)
+ self.assertTrue(self.called)
+ self.assertEqual(result, 42)
+
def test_int_arg(self):
def callback(num):
self.called = True
@@ -589,6 +914,22 @@ class TestClosures(unittest.TestCase):
self.assertRaises(TypeError, Everything.test_closure_variant, callback, 'foo')
self.assertFalse(self.called)
+ def test_variant_wrong_return_type(self):
+ def callback(variant):
+ return 'no_variant'
+
+ # reset last error
+ sys.last_type = None
+
+ # this does not directly raise an exception (see
+ # https://bugzilla.gnome.org/show_bug.cgi?id=616279)
+ result = Everything.test_closure_variant(callback, GLib.Variant('i', 42))
+ # ... but the result shouldn't be a string
+ self.assertEqual(result, None)
+ # and the error should be shown
+ self.assertEqual(sys.last_type, TypeError)
+ self.assertTrue('return value' in str(sys.last_value), sys.last_value)
+
@unittest.skipUnless(has_cairo, 'built without cairo support')
class TestProperties(unittest.TestCase):
@@ -647,7 +988,27 @@ class TestProperties(unittest.TestCase):
self.assertTrue(isinstance(object_.props.boxed, Everything.TestBoxed))
self.assertEqual(object_.props.boxed.some_int8, 42)
+ def test_boxed_alternative_constructor(self):
+ boxed = Everything.TestBoxed.new_alternative_constructor1(5)
+ self.assertEqual(boxed.some_int8, 5)
+
+ boxed = Everything.TestBoxed.new_alternative_constructor2(5, 3)
+ self.assertEqual(boxed.some_int8, 8)
+
+ boxed = Everything.TestBoxed.new_alternative_constructor3("-3")
+ self.assertEqual(boxed.some_int8, -3)
+
def test_boxed_equality(self):
+ boxed42 = Everything.TestBoxed.new_alternative_constructor1(42)
+ boxed5 = Everything.TestBoxed.new_alternative_constructor1(5)
+ boxed42_2 = Everything.TestBoxed.new_alternative_constructor2(41, 1)
+
+ self.assertFalse(boxed42.equals(boxed5))
+ self.assertTrue(boxed42.equals(boxed42_2))
+ self.assertTrue(boxed42_2.equals(boxed42))
+ self.assertTrue(boxed42.equals(boxed42))
+
+ def test_boxed_c_equality(self):
boxed = Everything.TestBoxedC()
# TestBoxedC uses refcounting, so we know that
# the pointer is the same when copied