diff --git a/README.md b/README.md index 15939642..ae358912 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,30 @@ Numerical integration: >>> acb.integral(lambda x, _: (-x**2).exp(), -100, 100) ** 2 [3.141592653589793238462643383 +/- 3.11e-28] +Cython API +------------------------------------- + +The PyPI/conda wheels install the ``.pxd`` files. A third-party Cython +module can then ``cimport`` the ``acb`` class and the libflint declarations +and operate on the underlying ``acb_t``: + +.. code-block:: cython + + from flint.types.acb cimport acb + from flint.flintlib.functions.acb cimport acb_exp, acb_t + from flint.flint_base.flint_context cimport getprec + + def exp_c(acb z): + cdef acb out = acb.__new__(acb) + acb_exp(out.val, z.val, getprec()) + return out + +Compiling that still needs the FLINT C headers (``flint/acb.h``) and +``libflint`` on the linker line, same versions as the ``python-flint`` +build. The Windows PyPI wheel ships ``libflint`` but not the headers; +use a FLINT development install (for example conda-forge ``libflint``) +when building the extension. + To do ------------------------------------- diff --git a/src/flint/flint_base/meson.build b/src/flint/flint_base/meson.build index 328494f2..8a84a5e3 100644 --- a/src/flint/flint_base/meson.build +++ b/src/flint/flint_base/meson.build @@ -4,6 +4,8 @@ pyfiles = [ '__init__.py', 'flint_base.pyi', 'flint_context.pyi', + 'flint_base.pxd', + 'flint_context.pxd', ] exts = [ diff --git a/src/flint/flintlib/functions/meson.build b/src/flint/flintlib/functions/meson.build new file mode 100644 index 00000000..5593bfd0 --- /dev/null +++ b/src/flint/flintlib/functions/meson.build @@ -0,0 +1,88 @@ +py.install_sources( + [ + '__init__.py', + '__init__.pxd', + 'acb.pxd', + 'acb_calc.pxd', + 'acb_dft.pxd', + 'acb_dirichlet.pxd', + 'acb_elliptic.pxd', + 'acb_hypgeom.pxd', + 'acb_mat.pxd', + 'acb_modular.pxd', + 'acb_poly.pxd', + 'acb_theta.pxd', + 'arb.pxd', + 'arb_fmpz_poly.pxd', + 'arb_hypgeom.pxd', + 'arb_mat.pxd', + 'arb_poly.pxd', + 'arf.pxd', + 'arith.pxd', + 'bernoulli.pxd', + 'compat.pxd', + 'dirichlet.pxd', + 'flint.pxd', + 'fmpq.pxd', + 'fmpq_mat.pxd', + 'fmpq_mpoly.pxd', + 'fmpq_mpoly_factor.pxd', + 'fmpq_poly.pxd', + 'fmpq_vec.pxd', + 'fmpz.pxd', + 'fmpz_factor.pxd', + 'fmpz_lll.pxd', + 'fmpz_mat.pxd', + 'fmpz_mod.pxd', + 'fmpz_mod_mat.pxd', + 'fmpz_mod_mpoly.pxd', + 'fmpz_mod_mpoly_factor.pxd', + 'fmpz_mod_poly.pxd', + 'fmpz_mod_poly_factor.pxd', + 'fmpz_mod_vec.pxd', + 'fmpz_mpoly.pxd', + 'fmpz_mpoly_factor.pxd', + 'fmpz_mpoly_q.pxd', + 'fmpz_poly.pxd', + 'fmpz_poly_factor.pxd', + 'fmpz_vec.pxd', + 'fq.pxd', + 'fq_default.pxd', + 'fq_default_mat.pxd', + 'fq_default_poly.pxd', + 'fq_default_poly_factor.pxd', + 'fq_mat.pxd', + 'fq_nmod.pxd', + 'fq_nmod_mat.pxd', + 'fq_nmod_poly.pxd', + 'fq_nmod_poly_factor.pxd', + 'fq_poly.pxd', + 'fq_poly_factor.pxd', + 'fq_zech.pxd', + 'fq_zech_mat.pxd', + 'fq_zech_poly.pxd', + 'fq_zech_poly_factor.pxd', + 'gr.pxd', + 'gr_domains.pxd', + 'gr_generic.pxd', + 'gr_implementing.pxd', + 'gr_mat.pxd', + 'gr_mpoly.pxd', + 'gr_poly.pxd', + 'gr_special.pxd', + 'gr_vec.pxd', + 'mag.pxd', + 'mpoly.pxd', + 'nmod.pxd', + 'nmod_mat.pxd', + 'nmod_mpoly.pxd', + 'nmod_mpoly_factor.pxd', + 'nmod_poly.pxd', + 'nmod_poly_factor.pxd', + 'nmod_vec.pxd', + 'partitions.pxd', + 'ulong_extras.pxd', + ], + pure: false, + subdir: 'flint/flintlib/functions', +) diff --git a/src/flint/flintlib/meson.build b/src/flint/flintlib/meson.build new file mode 100644 index 00000000..52c1d12a --- /dev/null +++ b/src/flint/flintlib/meson.build @@ -0,0 +1,13 @@ +# Cython declarations for libflint. Needed on the install path so a +# third-party .pyx can `cimport flint.types.acb` and call acb_* on `.val`. +py.install_sources( + [ + '__init__.py', + 'README.md', + ], + pure: false, + subdir: 'flint/flintlib', +) + +subdir('functions') +subdir('types') diff --git a/src/flint/flintlib/types/meson.build b/src/flint/flintlib/types/meson.build new file mode 100644 index 00000000..64e43753 --- /dev/null +++ b/src/flint/flintlib/types/meson.build @@ -0,0 +1,29 @@ +py.install_sources( + [ + '__init__.py', + 'acb.pxd', + 'acb_calc.pxd', + 'acb_dirichlet.pxd', + 'acb_theta.pxd', + 'arb.pxd', + 'arf.pxd', + 'arith.pxd', + 'dirichlet.pxd', + 'flint.pxd', + 'fmpq.pxd', + 'fmpz.pxd', + 'fmpz_mod.pxd', + 'fmpz_mod_mat_compat.pxd', + 'fmpz_mod_poly.pxd', + 'fq.pxd', + 'fq_default.pxd', + 'fq_nmod.pxd', + 'fq_zech.pxd', + 'gr.pxd', + 'mpoly.pxd', + 'nmod.pxd', + 'undocumented.pxd', + ], + pure: false, + subdir: 'flint/flintlib/types', +) diff --git a/src/flint/meson.build b/src/flint/meson.build index 4feb64ea..abb4e568 100644 --- a/src/flint/meson.build +++ b/src/flint/meson.build @@ -5,6 +5,7 @@ pyfiles = [ 'typing.py', 'py.typed', 'pyflint.pyi', + 'pyflint.pxd', ] exts = [ @@ -17,6 +18,7 @@ pkgs = [ 'functions', 'utils', 'test', + 'flintlib', ] py.install_sources( diff --git a/src/flint/test/meson.build b/src/flint/test/meson.build index 77c102c9..7c797d31 100644 --- a/src/flint/test/meson.build +++ b/src/flint/test/meson.build @@ -18,6 +18,7 @@ pyfiles = [ 'test_fmpz_vec.py', 'test_docstrings.py', 'test_dirichlet.py', + 'test_pxd.py', ] py.install_sources( diff --git a/src/flint/test/test_pxd.py b/src/flint/test/test_pxd.py new file mode 100644 index 00000000..2f4d9087 --- /dev/null +++ b/src/flint/test/test_pxd.py @@ -0,0 +1,18 @@ +"""Installed wheels must ship .pxd so third-party Cython can cimport acb_t.""" +from pathlib import Path + +import flint + + +def test_cython_pxd_files_are_installed() -> None: + root = Path(flint.__file__).resolve().parent + needed = [ + root / "pyflint.pxd", + root / "types" / "acb.pxd", + root / "flint_base" / "flint_base.pxd", + root / "flintlib" / "functions" / "acb.pxd", + root / "flintlib" / "types" / "acb.pxd", + root / "flintlib" / "functions" / "acb_hypgeom.pxd", + ] + missing = [str(p.relative_to(root)) for p in needed if not p.is_file()] + assert missing == [], missing diff --git a/src/flint/types/meson.build b/src/flint/types/meson.build index 1e527091..f2dedd53 100644 --- a/src/flint/types/meson.build +++ b/src/flint/types/meson.build @@ -47,6 +47,42 @@ pyfiles = [ 'dirichlet.pyi', # # '_gr.pyi', + + # Cython declarations for third-party cimport (acb.val is acb_t). + '_gr.pxd', + 'acb.pxd', + 'acb_mat.pxd', + 'acb_poly.pxd', + 'acb_series.pxd', + 'arb.pxd', + 'arb_mat.pxd', + 'arb_poly.pxd', + 'arb_series.pxd', + 'arf.pxd', + 'dirichlet.pxd', + 'fmpq.pxd', + 'fmpq_mat.pxd', + 'fmpq_mpoly.pxd', + 'fmpq_poly.pxd', + 'fmpq_series.pxd', + 'fmpq_vec.pxd', + 'fmpz.pxd', + 'fmpz_mat.pxd', + 'fmpz_mod.pxd', + 'fmpz_mod_mat.pxd', + 'fmpz_mod_mpoly.pxd', + 'fmpz_mod_poly.pxd', + 'fmpz_mpoly.pxd', + 'fmpz_poly.pxd', + 'fmpz_series.pxd', + 'fmpz_vec.pxd', + 'fq_default.pxd', + 'fq_default_poly.pxd', + 'nmod.pxd', + 'nmod_mat.pxd', + 'nmod_mpoly.pxd', + 'nmod_poly.pxd', + 'nmod_series.pxd', ] exts = [ diff --git a/src/flint/utils/meson.build b/src/flint/utils/meson.build index 8ec2da5c..4e908815 100644 --- a/src/flint/utils/meson.build +++ b/src/flint/utils/meson.build @@ -3,6 +3,8 @@ thisdir = 'flint/utils' pyfiles = [ '__init__.py', 'flint_exceptions.py', + 'conversion.pxd', + 'typecheck.pxd', ] exts = []