Skip to content

Commit 904d058

Browse files
committed
[test] stl vector __iadd__ with array.array
1 parent faa5689 commit 904d058

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

bindings/pyroot/pythonizations/test/stl_vector.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,24 @@
44

55
import ROOT
66

7+
# Helper function to assert that the elements of an array object and a std::vector proxy are equal
8+
def assertVec(vec, arr):
9+
# cppyy automatically casts random integers to unicode characters,
10+
# so do the same in python so the validation doesn't fail
11+
if isinstance(arr, array.array) and arr.typecode in ('b', 'B'):
12+
arr = [chr(b) for b in arr]
13+
14+
tc = unittest.TestCase()
15+
# first check lengths match
16+
tc.assertEqual(
17+
len(vec), len(arr),
18+
f"Length mismatch: std::vector is {len(vec)}, array is {len(arr)}"
19+
)
20+
21+
tc.assertSequenceEqual(
22+
vec, arr,
23+
msg="std::vector and array differ, iadd failed"
24+
)
725

826
class STL_vector(unittest.TestCase):
927
"""
@@ -45,6 +63,69 @@ def test_stl_vector_boolean(self):
4563
self.assertFalse(vector.empty())
4664
self.assertTrue(bool(vector))
4765

66+
def test_stl_vector_iadd(self):
67+
import array
68+
import random
69+
"""
70+
Test that the __iadd__ pythonization of std::vector works as expected.
71+
This call dispatches to std::insert
72+
https://github.com/root-project/root/issues/
73+
"""
74+
75+
# we go over all possible numeric PODs
76+
# https://docs.python.org/3/library/array.html
77+
entry_type = ['char', 'unsigned char','short', 'unsigned short', 'int',
78+
'unsigned int', 'long', 'unsigned long', 'long long', 'float',
79+
'double']
80+
array_type = [ 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd']
81+
82+
typemap = zip(entry_type, array_type)
83+
n = 5
84+
for dtype in typemap:
85+
vec = ROOT.std.vector[dtype[0]]()
86+
self.assertTrue(vec.empty())
87+
li = [random.randint(1, 100) for _ in range(n)]
88+
arr = array.array(dtype[1], li)
89+
vec += arr
90+
self.assertFalse(vec.empty())
91+
assertVec(vec, arr)
92+
vec.pop_back()
93+
arr = arr[:-1]
94+
assertVec(vec, arr)
95+
96+
def test_stl_vector_iadd_2D(self):
97+
"""
98+
Test that the __iadd__ pythonization of std::vector works as expected in 2D
99+
"""
100+
initial = [
101+
[1, 2, 3],
102+
[4, 5, 6],
103+
[7, 8, 9],
104+
]
105+
106+
vec2d = ROOT.std.vector[ROOT.std.vector[int]](initial)
107+
self.assertEqual(
108+
len(vec2d), len(initial),
109+
f"Initial 2D vector row count wrong ({len(vec2d)} vs {len(initial)})"
110+
)
111+
112+
# verify rows before iadd
113+
for idx, (subvec, sublist) in enumerate(zip(vec2d, initial)):
114+
with self.subTest(row=idx, phase="before"):
115+
assertVec(subvec, sublist)
116+
117+
vec2d += initial
118+
expected = initial + initial
119+
120+
self.assertEqual(
121+
len(vec2d), len(expected),
122+
f"2D vector row count after iadd wrong ({len(vec2d)} vs {len(expected)})"
123+
)
124+
125+
for idx, (subvec, sublist) in enumerate(zip(vec2d, expected)):
126+
with self.subTest(row=idx, phase="after"):
127+
assertVec(subvec, sublist)
128+
48129
def test_tree_with_containers(self):
49130
"""
50131
Test that the boolean conversion of a std::vector works as expected inside a TTree.

0 commit comments

Comments
 (0)