Skip to content

Commit 99975b2

Browse files
aaronj0dpiparo
authored andcommitted
[test] stl vector __iadd__ with array.array
1 parent 4f2a893 commit 99975b2

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

bindings/pyroot/pythonizations/test/stl_vector.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,20 @@
55
import ROOT
66

77

8+
# Helper function to assert that the elements of an array object and a std::vector proxy are equal
9+
def assertVec(vec, arr):
10+
# cppyy automatically casts random integers to unicode characters,
11+
# so do the same in python so the validation doesn't fail
12+
if isinstance(arr, array.array) and arr.typecode in ("b", "B"):
13+
arr = [chr(b) for b in arr]
14+
15+
tc = unittest.TestCase()
16+
# first check lengths match
17+
tc.assertEqual(len(vec), len(arr), f"Length mismatch: std::vector is {len(vec)}, array is {len(arr)}")
18+
19+
tc.assertSequenceEqual(vec, arr, msg="std::vector and array differ, iadd failed")
20+
21+
822
class STL_vector(unittest.TestCase):
923
"""
1024
Tests for the pythonizations of std::vector.
@@ -45,6 +59,78 @@ def test_stl_vector_boolean(self):
4559
self.assertFalse(vector.empty())
4660
self.assertTrue(bool(vector))
4761

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

0 commit comments

Comments
 (0)