pythonrustpackagingpyo3maturin

Building package for noarch with Maturin for Python >= 3.9


Current Version

I have published a package previously to PyPi and Conda. It was written in pure Python and used some of the following settings in pyproject.toml and was built with the native python -m build:

[build-system]
requires      = ["setuptools>=61.0.0", "wheel"]
build-backend = "setuptools.build_meta"

This produces two distribution files: a source and wheels, which are uploaded:

myproject-1.0.0.tar.gz
myproject-1.0.0-py3-none-any.whl

New Version

To improve performance I have now written some extensions in Rust and used pyo3 bindings, with build system maturin. Everything works locally.

I want to produce these generic distribution files, but obviously I don't fully understand the Python package distribution system.

If I change my pyproject.toml to read:

[build-system]
requires = ["maturin>=1.0,<2.0"]
build-backend = "maturin"

Then running maturin build --release --sdist --bindings pyo3 (on windows with Py3.11) produces the files

myproject-1.1.0.tar.gz
myproject-1.1.0-cp311-none-win_amd64.whl

Question

I want to understand how to cover all bases for distribution and what are the risks. For example,

If I upload these files to PyPi will it cause problems for users?

Can users who dont have Rust installed install my package from the source distibution?

Does the source distribution also need to be architecture dependent?

How can maturin produce wheels for all Python versions >= 3.9?


Solution

  • If I upload these files to PyPi will it cause problems for users?

    It definitely will if they use the --only-binary option.

    Can users who dont have Rust installed install my package from the source distibution?

    I don't think so: the source package should contain the artifacts necessary for building the wheel, but the wheel still needs to be built. If there is no pure wheel option, then there's nothing the user can do I believe.

    Sadly as far as I know maturin does not support pure Python fallbacks, which I've also been looking / hoping for for a personal project of mine

    Not everything is clear to me, but I think the best option currently is to compile the accelerator as a different crate, and make it an optional dependency. I don't know if there is a way to tell pip to install a dependency if it can and ignoring otherwise, but requirement specifiers can do the trick even if they're a pain in the ass to maintain.

    Does the source distribution also need to be architecture dependent?

    No, the source dist is the source.

    How can maturin produce wheels for all Python versions >= 3.9?

    I would assume if you use the limited ABI or cffi you might be able to produce a single cross-version wheel, otherwise you probably need to generate a wheel using every targeted interpreter in order to create the matching binary. Projects like cibuildwheel aim to assist with that sort of things.

    According to https://github.com/PyO3/maturin-action/issues/15#issuecomment-969833776 there might also be a -i option which lets you target an interpreter explicitely.