Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
test_cython.py368 linesDownload Raw Back to tests
1import os
2import subprocess
3import sys
4import sysconfig
5from datetime import datetime
6
7import pytest
8
9import numpy as np
10from numpy.testing import IS_EDITABLE, IS_WASM, assert_array_equal
11
12# This import is copied from random.tests.test_extending
13try:
14    import cython
15    from Cython.Compiler.Version import version as cython_version
16except ImportError:
17    cython = None
18else:
19    from numpy._utils import _pep440
20
21    # Note: keep in sync with the one in pyproject.toml
22    required_version = "3.0.6"
23    if _pep440.parse(cython_version) < _pep440.Version(required_version):
24        # too old or wrong cython, skip the test
25        cython = None
26
27pytestmark = pytest.mark.skipif(cython is None, reason="requires cython")
28
29
30if IS_EDITABLE:
31    pytest.skip(
32        "Editable install doesn't support tests with a compile step",
33        allow_module_level=True
34    )
35
36
37@pytest.fixture(scope='module')
38def install_temp(tmpdir_factory):
39    # Based in part on test_cython from random.tests.test_extending
40    if IS_WASM:
41        pytest.skip("No subprocess")
42
43    srcdir = os.path.join(os.path.dirname(__file__), 'examples', 'cython')
44    build_dir = tmpdir_factory.mktemp("cython_test") / "build"
45    os.makedirs(build_dir, exist_ok=True)
46    # Ensure we use the correct Python interpreter even when `meson` is
47    # installed in a different Python environment (see gh-24956)
48    native_file = str(build_dir / 'interpreter-native-file.ini')
49    with open(native_file, 'w') as f:
50        f.write("[binaries]\n")
51        f.write(f"python = '{sys.executable}'\n")
52        f.write(f"python3 = '{sys.executable}'")
53
54    try:
55        subprocess.check_call(["meson", "--version"])
56    except FileNotFoundError:
57        pytest.skip("No usable 'meson' found")
58    if sysconfig.get_platform() == "win-arm64":
59        pytest.skip("Meson unable to find MSVC linker on win-arm64")
60    if sys.platform == "win32":
61        subprocess.check_call(["meson", "setup",
62                               "--buildtype=release",
63                               "--vsenv", "--native-file", native_file,
64                               str(srcdir)],
65                              cwd=build_dir,
66                              )
67    else:
68        subprocess.check_call(["meson", "setup",
69                               "--native-file", native_file, str(srcdir)],
70                              cwd=build_dir
71                              )
72    try:
73        subprocess.check_call(["meson", "compile", "-vv"], cwd=build_dir)
74    except subprocess.CalledProcessError:
75        print("----------------")
76        print("meson build failed when doing")
77        print(f"'meson setup --native-file {native_file} {srcdir}'")
78        print("'meson compile -vv'")
79        print(f"in {build_dir}")
80        print("----------------")
81        raise
82
83    sys.path.append(str(build_dir))
84
85
86def test_is_timedelta64_object(install_temp):
87    import checks
88
89    assert checks.is_td64(np.timedelta64(1234))
90    assert checks.is_td64(np.timedelta64(1234, "ns"))
91    assert checks.is_td64(np.timedelta64("NaT", "ns"))
92
93    assert not checks.is_td64(1)
94    assert not checks.is_td64(None)
95    assert not checks.is_td64("foo")
96    assert not checks.is_td64(np.datetime64("now", "s"))
97
98
99def test_is_datetime64_object(install_temp):
100    import checks
101
102    assert checks.is_dt64(np.datetime64(1234, "ns"))
103    assert checks.is_dt64(np.datetime64("NaT", "ns"))
104
105    assert not checks.is_dt64(1)
106    assert not checks.is_dt64(None)
107    assert not checks.is_dt64("foo")
108    assert not checks.is_dt64(np.timedelta64(1234))
109
110
111def test_get_datetime64_value(install_temp):
112    import checks
113
114    dt64 = np.datetime64("2016-01-01", "ns")
115
116    result = checks.get_dt64_value(dt64)
117    expected = dt64.view("i8")
118
119    assert result == expected
120
121
122def test_get_timedelta64_value(install_temp):
123    import checks
124
125    td64 = np.timedelta64(12345, "h")
126
127    result = checks.get_td64_value(td64)
128    expected = td64.view("i8")
129
130    assert result == expected
131
132
133def test_get_datetime64_unit(install_temp):
134    import checks
135
136    dt64 = np.datetime64("2016-01-01", "ns")
137    result = checks.get_dt64_unit(dt64)
138    expected = 10
139    assert result == expected
140
141    td64 = np.timedelta64(12345, "h")
142    result = checks.get_dt64_unit(td64)
143    expected = 5
144    assert result == expected
145
146
147def test_abstract_scalars(install_temp):
148    import checks
149
150    assert checks.is_integer(1)
151    assert checks.is_integer(np.int8(1))
152    assert checks.is_integer(np.uint64(1))
153
154def test_default_int(install_temp):
155    import checks
156
157    assert checks.get_default_integer() is np.dtype(int)
158
159
160def test_ravel_axis(install_temp):
161    import checks
162
163    assert checks.get_ravel_axis() == np.iinfo("intc").min
164
165
166def test_convert_datetime64_to_datetimestruct(install_temp):
167    # GH#21199
168    import checks
169
170    res = checks.convert_datetime64_to_datetimestruct()
171
172    exp = {
173        "year": 2022,
174        "month": 3,
175        "day": 15,
176        "hour": 20,
177        "min": 1,
178        "sec": 55,
179        "us": 260292,
180        "ps": 0,
181        "as": 0,
182    }
183
184    assert res == exp
185
186
187class TestDatetimeStrings:
188    def test_make_iso_8601_datetime(self, install_temp):
189        # GH#21199
190        import checks
191        dt = datetime(2016, 6, 2, 10, 45, 19)
192        # uses NPY_FR_s
193        result = checks.make_iso_8601_datetime(dt)
194        assert result == b"2016-06-02T10:45:19"
195
196    def test_get_datetime_iso_8601_strlen(self, install_temp):
197        # GH#21199
198        import checks
199        # uses NPY_FR_ns
200        res = checks.get_datetime_iso_8601_strlen()
201        assert res == 48
202
203
204@pytest.mark.parametrize(
205    "arrays",
206    [
207        [np.random.rand(2)],
208        [np.random.rand(2), np.random.rand(3, 1)],
209        [np.random.rand(2), np.random.rand(2, 3, 2), np.random.rand(1, 3, 2)],
210        [np.random.rand(2, 1)] * 4 + [np.random.rand(1, 1, 1)],
211    ]
212)
213def test_multiiter_fields(install_temp, arrays):
214    import checks
215    bcast = np.broadcast(*arrays)
216
217    assert bcast.ndim == checks.get_multiiter_number_of_dims(bcast)
218    assert bcast.size == checks.get_multiiter_size(bcast)
219    assert bcast.numiter == checks.get_multiiter_num_of_iterators(bcast)
220    assert bcast.shape == checks.get_multiiter_shape(bcast)
221    assert bcast.index == checks.get_multiiter_current_index(bcast)
222    assert all(
223        x.base is y.base
224        for x, y in zip(bcast.iters, checks.get_multiiter_iters(bcast))
225    )
226
227
228def test_dtype_flags(install_temp):
229    import checks
230    dtype = np.dtype("i,O")  # dtype with somewhat interesting flags
231    assert dtype.flags == checks.get_dtype_flags(dtype)
232
233
234def test_conv_intp(install_temp):
235    import checks
236
237    class myint:
238        def __int__(self):
239            return 3
240
241    # These conversion passes via `__int__`, not `__index__`:
242    assert checks.conv_intp(3.) == 3
243    assert checks.conv_intp(myint()) == 3
244
245
246def test_npyiter_api(install_temp):
247    import checks
248    arr = np.random.rand(3, 2)
249
250    it = np.nditer(arr)
251    assert checks.get_npyiter_size(it) == it.itersize == np.prod(arr.shape)
252    assert checks.get_npyiter_ndim(it) == it.ndim == 1
253    assert checks.npyiter_has_index(it) == it.has_index == False
254
255    it = np.nditer(arr, flags=["c_index"])
256    assert checks.npyiter_has_index(it) == it.has_index == True
257    assert (
258        checks.npyiter_has_delayed_bufalloc(it)
259        == it.has_delayed_bufalloc
260        == False
261    )
262
263    it = np.nditer(arr, flags=["buffered", "delay_bufalloc"])
264    assert (
265        checks.npyiter_has_delayed_bufalloc(it)
266        == it.has_delayed_bufalloc
267        == True
268    )
269
270    it = np.nditer(arr, flags=["multi_index"])
271    assert checks.get_npyiter_size(it) == it.itersize == np.prod(arr.shape)
272    assert checks.npyiter_has_multi_index(it) == it.has_multi_index == True
273    assert checks.get_npyiter_ndim(it) == it.ndim == 2
274    assert checks.test_get_multi_index_iter_next(it, arr)
275
276    arr2 = np.random.rand(2, 1, 2)
277    it = np.nditer([arr, arr2])
278    assert checks.get_npyiter_nop(it) == it.nop == 2
279    assert checks.get_npyiter_size(it) == it.itersize == 12
280    assert checks.get_npyiter_ndim(it) == it.ndim == 3
281    assert all(
282        x is y for x, y in zip(checks.get_npyiter_operands(it), it.operands)
283    )
284    assert all(
285        np.allclose(x, y)
286        for x, y in zip(checks.get_npyiter_itviews(it), it.itviews)
287    )
288
289
290def test_fillwithbytes(install_temp):
291    import checks
292
293    arr = checks.compile_fillwithbyte()
294    assert_array_equal(arr, np.ones((1, 2)))
295
296
297def test_complex(install_temp):
298    from checks import inc2_cfloat_struct
299
300    arr = np.array([0, 10 + 10j], dtype="F")
301    inc2_cfloat_struct(arr)
302    assert arr[1] == (12 + 12j)
303
304
305def test_npystring_pack(install_temp):
306    """Check that the cython API can write to a vstring array."""
307    import checks
308
309    arr = np.array(['a', 'b', 'c'], dtype='T')
310    assert checks.npystring_pack(arr) == 0
311
312    # checks.npystring_pack writes to the beginning of the array
313    assert arr[0] == "Hello world"
314
315def test_npystring_load(install_temp):
316    """Check that the cython API can load strings from a vstring array."""
317    import checks
318
319    arr = np.array(['abcd', 'b', 'c'], dtype='T')
320    result = checks.npystring_load(arr)
321    assert result == 'abcd'
322
323
324def test_npystring_multiple_allocators(install_temp):
325    """Check that the cython API can acquire/release multiple vstring allocators."""
326    import checks
327
328    dt = np.dtypes.StringDType(na_object=None)
329    arr1 = np.array(['abcd', 'b', 'c'], dtype=dt)
330    arr2 = np.array(['a', 'b', 'c'], dtype=dt)
331
332    assert checks.npystring_pack_multiple(arr1, arr2) == 0
333    assert arr1[0] == "Hello world"
334    assert arr1[-1] is None
335    assert arr2[0] == "test this"
336
337
338def test_npystring_allocators_other_dtype(install_temp):
339    """Check that allocators for non-StringDType arrays is NULL."""
340    import checks
341
342    arr1 = np.array([1, 2, 3], dtype='i')
343    arr2 = np.array([4, 5, 6], dtype='i')
344
345    assert checks.npystring_allocators_other_types(arr1, arr2) == 0
346
347
348@pytest.mark.skipif(sysconfig.get_platform() == 'win-arm64',
349                    reason='no checks module on win-arm64')
350def test_npy_uintp_type_enum(install_temp):
351    import checks
352    assert checks.check_npy_uintp_type_enum()
353
354
355@pytest.mark.skipif(
356    sys.version_info < (3, 14),
357    reason="Tests behavior that happens on Python 3.14 and newer"
358)
359@pytest.mark.skipif(
360    sysconfig.get_platform() == 'win-arm64',
361    reason='no checks module on win-arm64'
362)
363def test_resize_refcheck(install_temp):
364    import checks
365    msg = "It is possible that this is a false positive."
366    with pytest.raises(ValueError, match=msg):
367        checks.resize_refcheck_test()
368 
codekingpro/portable-devtools · Team Ai