Skip to content

Commit 0cbd389

Browse files
committed
Install Cython .pxd files so third-party modules can cimport acb_t.
The wheels currently ship only .py/.pyi/.pyd, so another Cython extension cannot cimport flint.types.acb and call libflint on acb.val. Install the declaration files next to the extensions, including flintlib. Compiling still needs the FLINT C headers; the Windows PyPI wheel ships libflint without them.
1 parent 848e579 commit 0cbd389

10 files changed

Lines changed: 215 additions & 0 deletions

File tree

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,30 @@ Numerical integration:
114114
>>> acb.integral(lambda x, _: (-x**2).exp(), -100, 100) ** 2
115115
[3.141592653589793238462643383 +/- 3.11e-28]
116116

117+
Cython API
118+
-------------------------------------
119+
120+
The PyPI/conda wheels install the ``.pxd`` files. A third-party Cython
121+
module can then ``cimport`` the ``acb`` class and the libflint declarations
122+
and operate on the underlying ``acb_t``:
123+
124+
.. code-block:: cython
125+
126+
from flint.types.acb cimport acb
127+
from flint.flintlib.functions.acb cimport acb_exp, acb_t
128+
from flint.flint_base.flint_context cimport getprec
129+
130+
def exp_c(acb z):
131+
cdef acb out = acb.__new__(acb)
132+
acb_exp(out.val, z.val, getprec())
133+
return out
134+
135+
Compiling that still needs the FLINT C headers (``flint/acb.h``) and
136+
``libflint`` on the linker line, same versions as the ``python-flint``
137+
build. The Windows PyPI wheel ships ``libflint`` but not the headers;
138+
use a FLINT development install (for example conda-forge ``libflint``)
139+
when building the extension.
140+
117141
To do
118142
-------------------------------------
119143

src/flint/flint_base/meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ pyfiles = [
44
'__init__.py',
55
'flint_base.pyi',
66
'flint_context.pyi',
7+
'flint_base.pxd',
8+
'flint_context.pxd',
79
]
810

911
exts = [
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
py.install_sources(
2+
[
3+
'__init__.py',
4+
'__init__.pxd',
5+
'acb.pxd',
6+
'acb_calc.pxd',
7+
'acb_dft.pxd',
8+
'acb_dirichlet.pxd',
9+
'acb_elliptic.pxd',
10+
'acb_hypgeom.pxd',
11+
'acb_mat.pxd',
12+
'acb_modular.pxd',
13+
'acb_poly.pxd',
14+
'acb_theta.pxd',
15+
'arb.pxd',
16+
'arb_fmpz_poly.pxd',
17+
'arb_hypgeom.pxd',
18+
'arb_mat.pxd',
19+
'arb_poly.pxd',
20+
'arf.pxd',
21+
'arith.pxd',
22+
'bernoulli.pxd',
23+
'compat.pxd',
24+
'dirichlet.pxd',
25+
'flint.pxd',
26+
'fmpq.pxd',
27+
'fmpq_mat.pxd',
28+
'fmpq_mpoly.pxd',
29+
'fmpq_mpoly_factor.pxd',
30+
'fmpq_poly.pxd',
31+
'fmpq_vec.pxd',
32+
'fmpz.pxd',
33+
'fmpz_factor.pxd',
34+
'fmpz_lll.pxd',
35+
'fmpz_mat.pxd',
36+
'fmpz_mod.pxd',
37+
'fmpz_mod_mat.pxd',
38+
'fmpz_mod_mpoly.pxd',
39+
'fmpz_mod_mpoly_factor.pxd',
40+
'fmpz_mod_poly.pxd',
41+
'fmpz_mod_poly_factor.pxd',
42+
'fmpz_mod_vec.pxd',
43+
'fmpz_mpoly.pxd',
44+
'fmpz_mpoly_factor.pxd',
45+
'fmpz_mpoly_q.pxd',
46+
'fmpz_poly.pxd',
47+
'fmpz_poly_factor.pxd',
48+
'fmpz_vec.pxd',
49+
'fq.pxd',
50+
'fq_default.pxd',
51+
'fq_default_mat.pxd',
52+
'fq_default_poly.pxd',
53+
'fq_default_poly_factor.pxd',
54+
'fq_mat.pxd',
55+
'fq_nmod.pxd',
56+
'fq_nmod_mat.pxd',
57+
'fq_nmod_poly.pxd',
58+
'fq_nmod_poly_factor.pxd',
59+
'fq_poly.pxd',
60+
'fq_poly_factor.pxd',
61+
'fq_zech.pxd',
62+
'fq_zech_mat.pxd',
63+
'fq_zech_poly.pxd',
64+
'fq_zech_poly_factor.pxd',
65+
'gr.pxd',
66+
'gr_domains.pxd',
67+
'gr_generic.pxd',
68+
'gr_implementing.pxd',
69+
'gr_mat.pxd',
70+
'gr_mpoly.pxd',
71+
'gr_poly.pxd',
72+
'gr_special.pxd',
73+
'gr_vec.pxd',
74+
'mag.pxd',
75+
'mpoly.pxd',
76+
'nmod.pxd',
77+
'nmod_mat.pxd',
78+
'nmod_mpoly.pxd',
79+
'nmod_mpoly_factor.pxd',
80+
'nmod_poly.pxd',
81+
'nmod_poly_factor.pxd',
82+
'nmod_vec.pxd',
83+
'partitions.pxd',
84+
'ulong_extras.pxd',
85+
],
86+
pure: false,
87+
subdir: 'flint/flintlib/functions',
88+
)

src/flint/flintlib/meson.build

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Cython declarations for libflint. Needed on the install path so a
2+
# third-party .pyx can `cimport flint.types.acb` and call acb_* on `.val`.
3+
py.install_sources(
4+
[
5+
'__init__.py',
6+
'README.md',
7+
],
8+
pure: false,
9+
subdir: 'flint/flintlib',
10+
)
11+
12+
subdir('functions')
13+
subdir('types')
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
py.install_sources(
2+
[
3+
'__init__.py',
4+
'acb.pxd',
5+
'acb_calc.pxd',
6+
'acb_dirichlet.pxd',
7+
'acb_theta.pxd',
8+
'arb.pxd',
9+
'arf.pxd',
10+
'arith.pxd',
11+
'dirichlet.pxd',
12+
'flint.pxd',
13+
'fmpq.pxd',
14+
'fmpz.pxd',
15+
'fmpz_mod.pxd',
16+
'fmpz_mod_mat_compat.pxd',
17+
'fmpz_mod_poly.pxd',
18+
'fq.pxd',
19+
'fq_default.pxd',
20+
'fq_nmod.pxd',
21+
'fq_zech.pxd',
22+
'gr.pxd',
23+
'mpoly.pxd',
24+
'nmod.pxd',
25+
'undocumented.pxd',
26+
],
27+
pure: false,
28+
subdir: 'flint/flintlib/types',
29+
)

src/flint/meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pyfiles = [
55
'typing.py',
66
'py.typed',
77
'pyflint.pyi',
8+
'pyflint.pxd',
89
]
910

1011
exts = [
@@ -17,6 +18,7 @@ pkgs = [
1718
'functions',
1819
'utils',
1920
'test',
21+
'flintlib',
2022
]
2123

2224
py.install_sources(

src/flint/test/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pyfiles = [
1818
'test_fmpz_vec.py',
1919
'test_docstrings.py',
2020
'test_dirichlet.py',
21+
'test_pxd.py',
2122
]
2223

2324
py.install_sources(

src/flint/test/test_pxd.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""Installed wheels must ship .pxd so third-party Cython can cimport acb_t."""
2+
from pathlib import Path
3+
4+
import flint
5+
6+
7+
def test_cython_pxd_files_are_installed() -> None:
8+
root = Path(flint.__file__).resolve().parent
9+
needed = [
10+
root / "pyflint.pxd",
11+
root / "types" / "acb.pxd",
12+
root / "flint_base" / "flint_base.pxd",
13+
root / "flintlib" / "functions" / "acb.pxd",
14+
root / "flintlib" / "types" / "acb.pxd",
15+
root / "flintlib" / "functions" / "acb_hypgeom.pxd",
16+
]
17+
missing = [str(p.relative_to(root)) for p in needed if not p.is_file()]
18+
assert missing == [], missing

src/flint/types/meson.build

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,42 @@ pyfiles = [
4747
'dirichlet.pyi',
4848
#
4949
# '_gr.pyi',
50+
51+
# Cython declarations for third-party cimport (acb.val is acb_t).
52+
'_gr.pxd',
53+
'acb.pxd',
54+
'acb_mat.pxd',
55+
'acb_poly.pxd',
56+
'acb_series.pxd',
57+
'arb.pxd',
58+
'arb_mat.pxd',
59+
'arb_poly.pxd',
60+
'arb_series.pxd',
61+
'arf.pxd',
62+
'dirichlet.pxd',
63+
'fmpq.pxd',
64+
'fmpq_mat.pxd',
65+
'fmpq_mpoly.pxd',
66+
'fmpq_poly.pxd',
67+
'fmpq_series.pxd',
68+
'fmpq_vec.pxd',
69+
'fmpz.pxd',
70+
'fmpz_mat.pxd',
71+
'fmpz_mod.pxd',
72+
'fmpz_mod_mat.pxd',
73+
'fmpz_mod_mpoly.pxd',
74+
'fmpz_mod_poly.pxd',
75+
'fmpz_mpoly.pxd',
76+
'fmpz_poly.pxd',
77+
'fmpz_series.pxd',
78+
'fmpz_vec.pxd',
79+
'fq_default.pxd',
80+
'fq_default_poly.pxd',
81+
'nmod.pxd',
82+
'nmod_mat.pxd',
83+
'nmod_mpoly.pxd',
84+
'nmod_poly.pxd',
85+
'nmod_series.pxd',
5086
]
5187

5288
exts = [

src/flint/utils/meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ thisdir = 'flint/utils'
33
pyfiles = [
44
'__init__.py',
55
'flint_exceptions.py',
6+
'conversion.pxd',
7+
'typecheck.pxd',
68
]
79

810
exts = []

0 commit comments

Comments
 (0)