xobjects 0.6.10__tar.gz → 0.7.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {xobjects-0.6.10/xobjects.egg-info → xobjects-0.7.1}/PKG-INFO +1 -1
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_capi.py +39 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_general.py +94 -84
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_hybrid_class.py +22 -0
- xobjects-0.7.1/tests/test_raw_union.py +78 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/__init__.py +1 -0
- xobjects-0.7.1/xobjects/_version.py +1 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/array.py +2 -2
- xobjects-0.7.1/xobjects/capi.py +1010 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/context.py +3 -3
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/context_cpu.py +98 -15
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/context_cupy.py +5 -3
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/general.py +1 -1
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/headers/atomicadd.h +14 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/hybrid_class.py +7 -1
- xobjects-0.7.1/xobjects/raw_union.py +111 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/ref.py +4 -4
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/scalar.py +2 -2
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/settings.py +80 -68
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/string.py +2 -2
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/struct.py +12 -6
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/union.py +2 -2
- {xobjects-0.6.10 → xobjects-0.7.1/xobjects.egg-info}/PKG-INFO +1 -1
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects.egg-info/SOURCES.txt +2 -0
- xobjects-0.6.10/xobjects/_version.py +0 -1
- xobjects-0.6.10/xobjects/capi.py +0 -654
- {xobjects-0.6.10 → xobjects-0.7.1}/Architecture.md +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/LICENSE +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/MANIFEST.in +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/README.md +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/pyproject.toml +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/setup.cfg +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/setup.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_align.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_array.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_buffer.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_chunk.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_common.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_context_opencl.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_kernel.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_linked_array.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_nplike_arrays.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_ref.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_scalars.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_shared_memory.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_strides.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_string.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_struct.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_to_dict.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_typeutils.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/tests/test_unionref.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/_patch_pyopencl_array.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/context_pyopencl.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/headers/common.h +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/linkedarray.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/specialize_source.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/test_helpers.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects/typeutils.py +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects.egg-info/dependency_links.txt +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects.egg-info/entry_points.txt +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects.egg-info/requires.txt +0 -0
- {xobjects-0.6.10 → xobjects-0.7.1}/xobjects.egg-info/top_level.txt +0 -0
|
@@ -21,6 +21,15 @@ class Struct1(xo.Struct):
|
|
|
21
21
|
field2 = xo.Float64
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
class RawValue(xo.RawUnion):
|
|
25
|
+
scalar = xo.Float64
|
|
26
|
+
bits = xo.UInt64
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class StructRawUnion(xo.Struct):
|
|
30
|
+
value = RawValue
|
|
31
|
+
|
|
32
|
+
|
|
24
33
|
class Struct2(xo.Struct):
|
|
25
34
|
field1 = xo.Int32
|
|
26
35
|
field2 = xo.Float64[:]
|
|
@@ -243,6 +252,36 @@ def test_struct1():
|
|
|
243
252
|
assert p2[0] == s1.field2
|
|
244
253
|
|
|
245
254
|
|
|
255
|
+
def test_raw_union_member_getters():
|
|
256
|
+
kernels = StructRawUnion._gen_kernels()
|
|
257
|
+
ctx = xo.ContextCpu()
|
|
258
|
+
ctx.add_kernels(kernels=kernels)
|
|
259
|
+
|
|
260
|
+
source = StructRawUnion._gen_c_api().source
|
|
261
|
+
assert "StructRawUnion_get_value_scalar" in source
|
|
262
|
+
assert "StructRawUnion_get_value_bits" in source
|
|
263
|
+
assert "StructRawUnion_get_value(" not in source
|
|
264
|
+
|
|
265
|
+
value = 3.5
|
|
266
|
+
value_bits = np.array([value], dtype=np.float64).view(np.uint64)[0]
|
|
267
|
+
s1 = StructRawUnion(value=value)
|
|
268
|
+
s2 = StructRawUnion(value=("bits", value_bits))
|
|
269
|
+
raw_value = RawValue(value)
|
|
270
|
+
|
|
271
|
+
assert isinstance(s1.value, RawValue)
|
|
272
|
+
assert s1.value.scalar == value
|
|
273
|
+
assert s1.value.bits == value_bits
|
|
274
|
+
assert s2.value.scalar == value
|
|
275
|
+
assert s2.value.bits == value_bits
|
|
276
|
+
assert raw_value.scalar == value
|
|
277
|
+
assert raw_value.bits == value_bits
|
|
278
|
+
|
|
279
|
+
assert ctx.kernels.StructRawUnion_get_value_scalar(obj=s1) == value
|
|
280
|
+
assert ctx.kernels.StructRawUnion_get_value_bits(obj=s1) == value_bits
|
|
281
|
+
assert ctx.kernels.StructRawUnion_get_value_scalar(obj=s2) == value
|
|
282
|
+
assert ctx.kernels.StructRawUnion_get_value_bits(obj=s2) == value_bits
|
|
283
|
+
|
|
284
|
+
|
|
246
285
|
def test_struct2():
|
|
247
286
|
s2 = Struct2(field1=2, field2=5)
|
|
248
287
|
|
|
@@ -12,44 +12,44 @@ from xobjects.test_helpers import allow_kernel_compilation
|
|
|
12
12
|
def test_print_mode_default(capsys):
|
|
13
13
|
printer = Print()
|
|
14
14
|
|
|
15
|
-
printer(
|
|
15
|
+
printer("visible")
|
|
16
16
|
|
|
17
|
-
assert capsys.readouterr().out ==
|
|
17
|
+
assert capsys.readouterr().out == "visible\n"
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
def test_print_mode_suppressed(capsys):
|
|
21
21
|
printer = Print()
|
|
22
|
-
with xo.settings.override(print_mode=
|
|
23
|
-
printer(
|
|
22
|
+
with xo.settings.override(print_mode="suppress"):
|
|
23
|
+
printer("hidden")
|
|
24
24
|
|
|
25
|
-
assert capsys.readouterr().out ==
|
|
25
|
+
assert capsys.readouterr().out == ""
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
def test_settings_control_xsuite_printer(capsys):
|
|
29
|
-
with xo.settings.override(print_mode=
|
|
30
|
-
xo._print(
|
|
29
|
+
with xo.settings.override(print_mode="suppress"):
|
|
30
|
+
xo._print("hidden")
|
|
31
31
|
|
|
32
|
-
assert capsys.readouterr().out ==
|
|
32
|
+
assert capsys.readouterr().out == ""
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
def test_python_setting_overrides_environment_default(capsys):
|
|
36
|
-
with xo.settings.override(print_mode=
|
|
37
|
-
xo._print(
|
|
36
|
+
with xo.settings.override(print_mode="print"):
|
|
37
|
+
xo._print("visible")
|
|
38
38
|
|
|
39
|
-
assert capsys.readouterr().out ==
|
|
39
|
+
assert capsys.readouterr().out == "visible\n"
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
def test_invalid_print_mode_setting():
|
|
43
|
-
with pytest.raises(ValueError, match=
|
|
44
|
-
xo.settings.print_mode =
|
|
43
|
+
with pytest.raises(ValueError, match="XSUITE_PRINT_MODE.*print.*suppress"):
|
|
44
|
+
xo.settings.print_mode = "invalid"
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
def test_settings_override_restores_value_after_error():
|
|
48
48
|
original = xo.settings.print_mode
|
|
49
49
|
|
|
50
50
|
with pytest.raises(RuntimeError):
|
|
51
|
-
with xo.settings.override(print_mode=
|
|
52
|
-
assert xo.settings.print_mode ==
|
|
51
|
+
with xo.settings.override(print_mode="suppress"):
|
|
52
|
+
assert xo.settings.print_mode == "suppress"
|
|
53
53
|
raise RuntimeError
|
|
54
54
|
|
|
55
55
|
assert xo.settings.print_mode == original
|
|
@@ -57,84 +57,88 @@ def test_settings_override_restores_value_after_error():
|
|
|
57
57
|
|
|
58
58
|
def test_settings_are_discoverable():
|
|
59
59
|
expected_settings = {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
60
|
+
"print_mode",
|
|
61
|
+
"progress_indicator",
|
|
62
|
+
"allow_kernel_compilation",
|
|
63
|
+
"force_kernel_compilation",
|
|
64
|
+
"show_kernel_diagnostics",
|
|
65
|
+
"cffi_forbid_compile",
|
|
66
|
+
"cffi_keep_build_files",
|
|
67
|
+
"cuda_backend",
|
|
68
|
+
"cuda_fast_compile",
|
|
69
|
+
"cuda_compiler",
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
assert expected_settings <= set(dir(xo.settings))
|
|
73
73
|
for name in expected_settings:
|
|
74
|
-
assert f
|
|
74
|
+
assert f"{name}=" in repr(xo.settings)
|
|
75
75
|
assert name in type(xo.settings).__doc__
|
|
76
76
|
|
|
77
77
|
|
|
78
78
|
def test_print_mode_environment_variable_is_startup_default():
|
|
79
79
|
environment = os.environ.copy()
|
|
80
|
-
environment[
|
|
80
|
+
environment["XSUITE_PRINT_MODE"] = "suppress"
|
|
81
81
|
code = (
|
|
82
|
-
|
|
82
|
+
"import xobjects as xo; "
|
|
83
83
|
'assert xo.settings.print_mode == "suppress"; '
|
|
84
|
-
'xo._print("hidden")'
|
|
84
|
+
'xo._print("hidden")'
|
|
85
|
+
)
|
|
85
86
|
|
|
86
87
|
completed = subprocess.run(
|
|
87
|
-
[sys.executable,
|
|
88
|
+
[sys.executable, "-c", code],
|
|
88
89
|
env=environment,
|
|
89
90
|
capture_output=True,
|
|
90
91
|
text=True,
|
|
91
92
|
check=True,
|
|
92
93
|
)
|
|
93
94
|
|
|
94
|
-
assert completed.stdout ==
|
|
95
|
+
assert completed.stdout == ""
|
|
95
96
|
|
|
96
97
|
|
|
97
98
|
def test_print_mode_environment_variable_can_be_overridden_in_python():
|
|
98
99
|
environment = os.environ.copy()
|
|
99
|
-
environment[
|
|
100
|
+
environment["XSUITE_PRINT_MODE"] = "suppress"
|
|
100
101
|
code = (
|
|
101
|
-
|
|
102
|
+
"import xobjects as xo; "
|
|
102
103
|
'xo.settings.print_mode = "print"; '
|
|
103
104
|
'assert xo.settings.print_mode == "print"; '
|
|
104
|
-
'xo._print("visible")'
|
|
105
|
+
'xo._print("visible")'
|
|
106
|
+
)
|
|
105
107
|
|
|
106
108
|
completed = subprocess.run(
|
|
107
|
-
[sys.executable,
|
|
109
|
+
[sys.executable, "-c", code],
|
|
108
110
|
env=environment,
|
|
109
111
|
capture_output=True,
|
|
110
112
|
text=True,
|
|
111
113
|
check=True,
|
|
112
114
|
)
|
|
113
115
|
|
|
114
|
-
assert completed.stdout ==
|
|
116
|
+
assert completed.stdout == "visible\n"
|
|
115
117
|
|
|
116
118
|
|
|
117
119
|
def test_environment_change_after_import_does_not_override_python_setting(
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
capsys, monkeypatch
|
|
121
|
+
):
|
|
122
|
+
with xo.settings.override(print_mode="print"):
|
|
123
|
+
monkeypatch.setenv("XSUITE_PRINT_MODE", "suppress")
|
|
124
|
+
xo._print("visible")
|
|
122
125
|
|
|
123
|
-
assert capsys.readouterr().out ==
|
|
126
|
+
assert capsys.readouterr().out == "visible\n"
|
|
124
127
|
|
|
125
128
|
|
|
126
|
-
@pytest.mark.parametrize(
|
|
129
|
+
@pytest.mark.parametrize("value", ["1", "true", "YES", "on"])
|
|
127
130
|
def test_boolean_environment_true_values(value):
|
|
128
131
|
environment = os.environ.copy()
|
|
129
|
-
environment[
|
|
132
|
+
environment["XSUITE_ALLOW_KERNEL_COMPILATION"] = value
|
|
130
133
|
code = (
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
134
|
+
"import xobjects as xo; "
|
|
135
|
+
"assert xo.settings.allow_kernel_compilation is True; "
|
|
136
|
+
"xo.settings.allow_kernel_compilation = False; "
|
|
137
|
+
"assert xo.settings.allow_kernel_compilation is False"
|
|
138
|
+
)
|
|
135
139
|
|
|
136
140
|
subprocess.run(
|
|
137
|
-
[sys.executable,
|
|
141
|
+
[sys.executable, "-c", code],
|
|
138
142
|
env=environment,
|
|
139
143
|
capture_output=True,
|
|
140
144
|
text=True,
|
|
@@ -142,16 +146,17 @@ def test_boolean_environment_true_values(value):
|
|
|
142
146
|
)
|
|
143
147
|
|
|
144
148
|
|
|
145
|
-
@pytest.mark.parametrize(
|
|
149
|
+
@pytest.mark.parametrize("value", ["0", "false", "NO", "off"])
|
|
146
150
|
def test_boolean_environment_false_values(value):
|
|
147
151
|
environment = os.environ.copy()
|
|
148
|
-
environment[
|
|
152
|
+
environment["XSUITE_FORCE_KERNEL_COMPILATION"] = value
|
|
149
153
|
code = (
|
|
150
|
-
|
|
151
|
-
|
|
154
|
+
"import xobjects as xo; "
|
|
155
|
+
"assert xo.settings.force_kernel_compilation is False"
|
|
156
|
+
)
|
|
152
157
|
|
|
153
158
|
subprocess.run(
|
|
154
|
-
[sys.executable,
|
|
159
|
+
[sys.executable, "-c", code],
|
|
155
160
|
env=environment,
|
|
156
161
|
capture_output=True,
|
|
157
162
|
text=True,
|
|
@@ -161,46 +166,49 @@ def test_boolean_environment_false_values(value):
|
|
|
161
166
|
|
|
162
167
|
def test_invalid_boolean_environment_value():
|
|
163
168
|
environment = os.environ.copy()
|
|
164
|
-
environment[
|
|
169
|
+
environment["XSUITE_CFFI_FORBID_COMPILE"] = "sometimes"
|
|
165
170
|
|
|
166
171
|
completed = subprocess.run(
|
|
167
|
-
[sys.executable,
|
|
172
|
+
[sys.executable, "-c", "import xobjects"],
|
|
168
173
|
env=environment,
|
|
169
174
|
capture_output=True,
|
|
170
175
|
text=True,
|
|
171
176
|
)
|
|
172
177
|
|
|
173
178
|
assert completed.returncode != 0
|
|
174
|
-
assert
|
|
175
|
-
assert
|
|
176
|
-
assert
|
|
179
|
+
assert "Invalid boolean value" in completed.stderr
|
|
180
|
+
assert "xobjects.settings.cffi_forbid_compile" in completed.stderr
|
|
181
|
+
assert "XSUITE_CFFI_FORBID_COMPILE" in completed.stderr
|
|
177
182
|
|
|
178
183
|
|
|
179
184
|
def test_runtime_settings_environment_defaults():
|
|
180
185
|
environment = os.environ.copy()
|
|
181
|
-
environment.update(
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
186
|
+
environment.update(
|
|
187
|
+
{
|
|
188
|
+
"XSUITE_PROGRESS_INDICATOR": "text",
|
|
189
|
+
"XSUITE_FORCE_KERNEL_COMPILATION": "yes",
|
|
190
|
+
"XSUITE_SHOW_KERNEL_DIAGNOSTICS": "on",
|
|
191
|
+
"XSUITE_CFFI_FORBID_COMPILE": "true",
|
|
192
|
+
"XSUITE_CFFI_KEEP_BUILD_FILES": "1",
|
|
193
|
+
"XSUITE_CUDA_BACKEND": "clang",
|
|
194
|
+
"XSUITE_CUDA_FAST_COMPILE": "false",
|
|
195
|
+
"XSUITE_CUDA_COMPILER": "/path/to/clang++",
|
|
196
|
+
}
|
|
197
|
+
)
|
|
191
198
|
code = (
|
|
192
|
-
|
|
199
|
+
"import xobjects as xo; "
|
|
193
200
|
'assert xo.settings.progress_indicator == "text"; '
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
201
|
+
"assert xo.settings.force_kernel_compilation is True; "
|
|
202
|
+
"assert xo.settings.show_kernel_diagnostics is True; "
|
|
203
|
+
"assert xo.settings.cffi_forbid_compile is True; "
|
|
204
|
+
"assert xo.settings.cffi_keep_build_files is True; "
|
|
198
205
|
'assert xo.settings.cuda_backend == "clang"; '
|
|
199
|
-
|
|
200
|
-
'assert xo.settings.cuda_compiler == "/path/to/clang++"'
|
|
206
|
+
"assert xo.settings.cuda_fast_compile is False; "
|
|
207
|
+
'assert xo.settings.cuda_compiler == "/path/to/clang++"'
|
|
208
|
+
)
|
|
201
209
|
|
|
202
210
|
subprocess.run(
|
|
203
|
-
[sys.executable,
|
|
211
|
+
[sys.executable, "-c", code],
|
|
204
212
|
env=environment,
|
|
205
213
|
capture_output=True,
|
|
206
214
|
text=True,
|
|
@@ -209,7 +217,7 @@ def test_runtime_settings_environment_defaults():
|
|
|
209
217
|
|
|
210
218
|
|
|
211
219
|
@pytest.mark.parametrize(
|
|
212
|
-
|
|
220
|
+
"allow, force, compilation_allowed",
|
|
213
221
|
[
|
|
214
222
|
(False, False, False),
|
|
215
223
|
(True, False, True),
|
|
@@ -222,12 +230,14 @@ def test_kernel_compilation_settings(allow, force, compilation_allowed):
|
|
|
222
230
|
allow_kernel_compilation=allow,
|
|
223
231
|
force_kernel_compilation=force,
|
|
224
232
|
):
|
|
225
|
-
assert
|
|
226
|
-
xo.ContextCpu())
|
|
233
|
+
assert (
|
|
234
|
+
xo.context_cpu.kernel_compilation_allowed(xo.ContextCpu())
|
|
235
|
+
is compilation_allowed
|
|
236
|
+
)
|
|
227
237
|
|
|
228
238
|
|
|
229
239
|
def test_user_context_environment_variable(monkeypatch):
|
|
230
|
-
monkeypatch.setenv(
|
|
240
|
+
monkeypatch.setenv("XOBJECTS_USER_CONTEXT", "ContextCpu:auto")
|
|
231
241
|
context = xo.get_user_context()
|
|
232
242
|
|
|
233
243
|
assert context.openmp_enabled
|
|
@@ -235,8 +245,8 @@ def test_user_context_environment_variable(monkeypatch):
|
|
|
235
245
|
|
|
236
246
|
def test_test_contexts_environment_variable(monkeypatch):
|
|
237
247
|
monkeypatch.setenv(
|
|
238
|
-
|
|
239
|
-
|
|
248
|
+
"XOBJECTS_TEST_CONTEXTS",
|
|
249
|
+
"ContextCpu;ContextCpu:auto",
|
|
240
250
|
)
|
|
241
251
|
|
|
242
252
|
contexts = list(xo.context.get_test_contexts())
|
|
@@ -252,8 +262,8 @@ def test_cffi_forbid_compile_setting():
|
|
|
252
262
|
xo.ContextCpu().build_kernels({})
|
|
253
263
|
|
|
254
264
|
message = str(err.value)
|
|
255
|
-
assert
|
|
256
|
-
assert
|
|
265
|
+
assert "xobjects.settings.cffi_forbid_compile" in message
|
|
266
|
+
assert "XSUITE_CFFI_FORBID_COMPILE" in message
|
|
257
267
|
|
|
258
268
|
|
|
259
269
|
def test_allow_kernel_compilation_decorator_restores_state():
|
|
@@ -332,6 +332,28 @@ def test_to_json_defaults():
|
|
|
332
332
|
assert b_dict == {}
|
|
333
333
|
|
|
334
334
|
|
|
335
|
+
def test_to_dict_scalar_raw_union_defaults():
|
|
336
|
+
class ScalarUnion(xo.RawUnion):
|
|
337
|
+
scalar = xo.Float64
|
|
338
|
+
bits = xo.UInt64
|
|
339
|
+
|
|
340
|
+
@classmethod
|
|
341
|
+
def _from_buffer(cls, buffer, offset=0, container=None):
|
|
342
|
+
return xo.Float64._from_buffer(buffer, offset)
|
|
343
|
+
|
|
344
|
+
class A(xo.HybridClass):
|
|
345
|
+
_xofields = {
|
|
346
|
+
"a": ScalarUnion,
|
|
347
|
+
"b": xo.Field(ScalarUnion, default=2.5),
|
|
348
|
+
"c": xo.Field(ScalarUnion, default_factory=lambda: 3.5),
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
assert A().to_dict() == {"__class__": "A"}
|
|
352
|
+
values = {"__class__": "A", "a": 1.5, "b": 0.0, "c": 0.0}
|
|
353
|
+
for copy_to_cpu in (True, False):
|
|
354
|
+
assert A.from_dict(values).to_dict(copy_to_cpu=copy_to_cpu) == values
|
|
355
|
+
|
|
356
|
+
|
|
335
357
|
def test_to_dict_python_vars():
|
|
336
358
|
class TD(xo.HybridClass):
|
|
337
359
|
_xofields = {
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# copyright ################################# #
|
|
2
|
+
# This file is part of the Xobjects Package. #
|
|
3
|
+
# Copyright (c) CERN, 2026. #
|
|
4
|
+
# ########################################### #
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
import xobjects as xo
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class RawValue(xo.RawUnion):
|
|
13
|
+
scalar = xo.Float64
|
|
14
|
+
bits = xo.UInt64
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Holder(xo.Struct):
|
|
18
|
+
value = RawValue
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _float_bits(value):
|
|
22
|
+
return np.array([value], dtype=np.float64).view(np.uint64)[0]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_raw_union_declaration_consumes_member_attributes():
|
|
26
|
+
assert RawValue._members == {"scalar": xo.Float64, "bits": xo.UInt64}
|
|
27
|
+
assert RawValue._size == 8
|
|
28
|
+
|
|
29
|
+
assert not hasattr(RawValue, "scalar")
|
|
30
|
+
assert not hasattr(RawValue, "bits")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_raw_union_standalone_instance_reads_explicit_members():
|
|
34
|
+
value = 3.5
|
|
35
|
+
raw_value = RawValue(value)
|
|
36
|
+
|
|
37
|
+
assert isinstance(raw_value, RawValue)
|
|
38
|
+
assert raw_value.scalar == value
|
|
39
|
+
assert raw_value.bits == _float_bits(value)
|
|
40
|
+
assert "scalar" in dir(raw_value)
|
|
41
|
+
assert "bits" in dir(raw_value)
|
|
42
|
+
|
|
43
|
+
with pytest.raises(AttributeError, match="missing"):
|
|
44
|
+
raw_value.missing
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def test_raw_union_struct_field_reads_explicit_members():
|
|
48
|
+
value = 3.5
|
|
49
|
+
holder = Holder(value=value)
|
|
50
|
+
|
|
51
|
+
assert isinstance(holder.value, RawValue)
|
|
52
|
+
assert holder.value.scalar == value
|
|
53
|
+
assert holder.value.bits == _float_bits(value)
|
|
54
|
+
|
|
55
|
+
with pytest.raises(TypeError):
|
|
56
|
+
float(holder.value)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def test_raw_union_constructor_accepts_explicit_member():
|
|
60
|
+
value = 3.5
|
|
61
|
+
value_bits = _float_bits(value)
|
|
62
|
+
holder = Holder(value=("bits", value_bits))
|
|
63
|
+
|
|
64
|
+
assert holder.value.scalar == value
|
|
65
|
+
assert holder.value.bits == value_bits
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def test_raw_union_copy_from_same_type():
|
|
69
|
+
source = RawValue(3.5)
|
|
70
|
+
holder = Holder(value=0.0)
|
|
71
|
+
|
|
72
|
+
holder.value = source
|
|
73
|
+
assert holder.value.scalar == source.scalar
|
|
74
|
+
assert holder.value.bits == source.bits
|
|
75
|
+
|
|
76
|
+
copied = RawValue(source)
|
|
77
|
+
assert copied.scalar == source.scalar
|
|
78
|
+
assert copied.bits == source.bits
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.7.1"
|
|
@@ -414,7 +414,7 @@ class Array(metaclass=MetaArray):
|
|
|
414
414
|
return info
|
|
415
415
|
|
|
416
416
|
@classmethod
|
|
417
|
-
def _from_buffer(cls, buffer, offset=0):
|
|
417
|
+
def _from_buffer(cls, buffer, offset=0, container=None):
|
|
418
418
|
self = object.__new__(cls)
|
|
419
419
|
self._buffer = buffer
|
|
420
420
|
self._offset = offset
|
|
@@ -451,7 +451,7 @@ class Array(metaclass=MetaArray):
|
|
|
451
451
|
return self
|
|
452
452
|
|
|
453
453
|
@classmethod
|
|
454
|
-
def _to_buffer(cls, buffer, offset, value, info=None):
|
|
454
|
+
def _to_buffer(cls, buffer, offset, value, info=None, container=None):
|
|
455
455
|
if info is None:
|
|
456
456
|
info = cls._inspect_args(value)
|
|
457
457
|
value = info.value # can be None if value contained shape info
|