Skip to content

Commit 67dc1d2

Browse files
authored
Merge pull request #229 from thisisthepy/feat/tp-numpy-optional
Fix: The buffer tests run without numpy; CI installs numpy for the numpy pins
2 parents e650658 + 7d5c594 commit 67dc1d2

3 files changed

Lines changed: 68 additions & 34 deletions

File tree

‎.github/workflows/typedpython.yml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
# pyrefly is pinned exactly: the gate reads its versioned type-report format.
3535
run: |
3636
uv venv .venv --python 3.15t
37-
uv pip install --python .venv/bin/python "pyrefly==1.3.2" pytest
37+
uv pip install --python .venv/bin/python "pyrefly==1.3.2" pytest numpy
3838
3939
- name: Behaviour tests
4040
run: .venv/bin/python -m pytest -q -m "not measurement and not race_mutant"
@@ -62,7 +62,7 @@ jobs:
6262
- name: Create the environment
6363
run: |
6464
uv venv .venv --python 3.15t
65-
uv pip install --python .venv/bin/python "pyrefly==1.3.2" pytest
65+
uv pip install --python .venv/bin/python "pyrefly==1.3.2" pytest numpy
6666
6767
- name: Relax ASLR entropy (ASan shadow mapping on newer kernels)
6868
run: sudo sysctl -w vm.mmap_rnd_bits=28 || true
@@ -103,7 +103,7 @@ jobs:
103103
working-directory: python-multiplatform-ksp
104104
run: |
105105
uv venv .venv --python 3.15t
106-
uv pip install --python .venv/bin/python "pyrefly==1.3.2" pytest
106+
uv pip install --python .venv/bin/python "pyrefly==1.3.2" pytest numpy
107107
108108
- name: App fixture tests
109109
run: |

‎python-multiplatform-ksp/src/test/python/test_buffer_arrays.py‎

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,13 @@
2424
import importlib.util
2525
import textwrap
2626

27-
import numpy as np
2827
import pytest
2928

3029
from typedpython import cbuild, cgen, frontend, ir, verify
3130

3231
SOURCE = textwrap.dedent('''
3332
# typedpython: compiled
3433
import array
35-
import numpy as np
36-
import numpy.typing as npt
3734
3835
3936
def sum_ad(a: array.array[float]) -> float:
@@ -119,22 +116,13 @@ def rebind_view(a: array.array[float]) -> None:
119116
y[0] = 5.0
120117
121118
122-
def nd_first(x: npt.NDArray[np.float64]) -> object:
123-
return x[0]
124-
125-
126-
def nd_sum(x: npt.NDArray[np.float64]) -> object:
127-
s = 0.0
128-
for i in range(len(x)):
129-
s += x[i]
130-
return s
131119
''')
132120

133121
COMPILED = {
134122
"sum_ad", "sum_aq", "get_ad", "get_aq", "set_ad", "set_aq", "length_ad", "scale_ad", "iota_aq",
135123
"copy_ad", "cascade_ad", "fill_n", "mixed", "four", "div_ad",
136124
}
137-
SKIPPED = {"open_ad", "rebind_view", "nd_first", "nd_sum"}
125+
SKIPPED = {"open_ad", "rebind_view"}
138126

139127

140128
def build_source(d, source, name="bufmod"):
@@ -252,23 +240,6 @@ def wrapper_text(c, name):
252240
return c[start:c.index("\n}\n", start)]
253241

254242

255-
# --- numpy is not supported (#220): an ordinary object parameter ----------------------------------
256-
257-
def test_numpy_parameter_is_an_ordinary_object_and_keeps_numpy_results(built):
258-
for f in built.proved.functions:
259-
assert all(not isinstance(p, ir.ArrayParam) or p.buffer == "array" or p.buffer is None
260-
for p in f.params)
261-
assert not (f.name.startswith("nd_") and any(isinstance(p, ir.ArrayParam) for p in f.params))
262-
x = np.array(F, dtype=np.float64)
263-
r = built.module.nd_first(x)
264-
assert type(r) is np.float64 and r == F[0]
265-
r = built.module.nd_sum(x) # never compiled: the module's plain function
266-
ref = 0.0
267-
for v in x:
268-
ref += v
269-
assert type(r) is np.float64 and r == ref
270-
271-
272243
# --- reads, writes, len ---------------------------------------------------------------------------
273244

274245
@pytest.mark.parametrize("name,make", [
@@ -375,7 +346,6 @@ class SubArray(array.array):
375346
("sum_ad", lambda: (array.array("f", [1.0, 2.0]),)),
376347
("sum_ad", lambda: (SubArray("d", F),)),
377348
("sum_ad", lambda: (list(F),)),
378-
("sum_ad", lambda: (np.array(F),)),
379349
("sum_ad", lambda: (memoryview(AD()),)),
380350
("sum_ad", lambda: (None,)),
381351
])
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"""numpy arrays are not compiled yet (#220): an `NDArray[...]` parameter is an ordinary object
2+
parameter, so results and their numpy scalar types equal the interpreter's. Skipped without numpy."""
3+
import textwrap
4+
5+
import pytest
6+
7+
np = pytest.importorskip("numpy")
8+
9+
from typedpython import cbuild, ir # noqa: E402
10+
from test_buffer_arrays import AD, F, build_source, differential, load_so # noqa: E402
11+
12+
SOURCE = textwrap.dedent('''
13+
# typedpython: compiled
14+
import array
15+
import numpy as np
16+
import numpy.typing as npt
17+
18+
19+
def sum_ad(a: array.array[float]) -> float:
20+
s = 0.0
21+
for i in range(len(a)):
22+
s += a[i]
23+
return s
24+
25+
26+
def nd_first(x: npt.NDArray[np.float64]) -> object:
27+
return x[0]
28+
29+
30+
def nd_sum(x: npt.NDArray[np.float64]) -> object:
31+
s = 0.0
32+
for i in range(len(x)):
33+
s += x[i]
34+
return s
35+
''')
36+
37+
38+
@pytest.fixture(scope="module")
39+
def built(tmp_path_factory):
40+
d = tmp_path_factory.mktemp("bufnp")
41+
path, proved, diags, c = build_source(d, SOURCE)
42+
so = cbuild.build(c, path.stem, d / "out")
43+
return proved, load_so(so)
44+
45+
46+
def test_numpy_parameter_is_an_ordinary_object_and_keeps_numpy_results(built):
47+
proved, m = built
48+
for f in proved.functions:
49+
assert all(not isinstance(p, ir.ArrayParam) or p.buffer == "array" or p.buffer is None
50+
for p in f.params)
51+
assert not (f.name.startswith("nd_") and any(isinstance(p, ir.ArrayParam) for p in f.params))
52+
x = np.array(F, dtype=np.float64)
53+
r = m.nd_first(x)
54+
assert type(r) is np.float64 and r == F[0]
55+
r = m.nd_sum(x)
56+
ref = 0.0
57+
for v in x:
58+
ref += v
59+
assert type(r) is np.float64 and r == ref
60+
61+
62+
def test_a_numpy_array_given_to_an_array_parameter_takes_the_object_path(built):
63+
_, m = built
64+
differential(m, "sum_ad", lambda: (np.array(F),), expect_deopt=True)

0 commit comments

Comments
 (0)