From e374a5696281c0e1def56e74e70dd29341a39a5b Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Thu, 1 Feb 2024 21:55:47 +0000 Subject: [PATCH 1/2] update detail on `py_limited_api` for `pyproject.toml` builds --- docs/building_wheels.md | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/docs/building_wheels.md b/docs/building_wheels.md index 80e04fed..dbe702b3 100644 --- a/docs/building_wheels.md +++ b/docs/building_wheels.md @@ -4,19 +4,36 @@ Because `setuptools-rust` is an extension to `setuptools`, the standard [`python (or [`pip wheel --no-deps . --wheel-dir dist`](https://pip.pypa.io/en/stable/cli/pip_wheel/)) can be used to build distributable wheels. These wheels can be uploaded to PyPI using standard tools such as [twine](https://github.com/pypa/twine). -`setuptools-rust` supports building for the [PEP 384](https://www.python.org/dev/peps/pep-0384/) "stable" (aka "limited") API when the `py_limited_api` option is set on the `[bdist_wheel]` section of `setup.cfg`. -If using PyO3 bindings for `RustExtension`, then the correct [`pyo3/abi3`](https://pyo3.rs/v0.14.5/features.html#abi3) sub-feature is automatically enabled. -In this way, abi3 wheels can be uploaded to make package distributors' roles easier, and package users installing from source with `pip install .` can use optimizations specific to their Python version. +A key choice to make is whether to upload [PEP 384](https://www.python.org/dev/peps/pep-0384/) "stable" (aka "limited") API wheels which support multiple Python versions in a single binary, or to build individual artifacts for each Python version. There is a longer discussion of this [in the PyO3 docs](https://pyo3.rs/latest/building_and_distribution#py_limited_apiabi3). -This chapter of the documentation explains two possible ways to build wheels for multiple Python versions below. +This chapter covers each of these options below. -## Using `cibuildwheel` +## Building for ABI3 + +`setuptools-rust` will automatically configure for the limited API when this is set in the `[bdist_wheel]` configuration section of [`setup.cfg`](https://setuptools.pypa.io/en/latest/deprecated/distutils/configfile.html#writing-the-setup-configuration-file): + +```ini +[bdist_wheel] +py_limited_api=cp37 # replace with desired minimum Python version +``` + +If using a `pyproject.toml`-based build, then save the above in a file and use the `DIST_EXTRA_CONFIG` environment variable to instruct `setuptools` to pick up this extra configuration. (`DIST_EXTRA_CONFIG` is documented [on this page](https://setuptools.pypa.io/en/latest/deprecated/distutils/configfile.html#writing-the-setup-configuration-file) of the `setuptools` docs.) + +It is also possible to pass this setting via the command line, e.g. + +``` +python -m build --config-settings=--build-option=--py-limited-api=cp37 +``` + +## Building for multiple Python versions + +### Using `cibuildwheel` [`cibuildwheel`][cibuildwheel] is a tool to build wheels for multiple platforms using Github Actions. The [`rtoml` package does this, for example](https://github.com/samuelcolvin/rtoml/blob/143ee0907bba616cbcd5cc58eefe9000fcc2b5f2/.github/workflows/ci.yml#L99-L195). -## Building manually +### Building manually Place a script called `build-wheels.sh` with the following contents in your project root (next to the `setup.py` file): @@ -27,7 +44,7 @@ Place a script called `build-wheels.sh` with the following contents in your proj This script can be used to produce wheels for multiple Python versions. -### Binary wheels on linux +#### Binary wheels on linux To build binary wheels on linux, you need to use the [manylinux docker container](https://github.com/pypa/manylinux). You will run the `build-wheels.sh` from above inside that container. @@ -54,7 +71,7 @@ hello_rust-0.1.0-cp39-cp39-linux_x86_64.whl hello_rust-0.1.0-cp39-cp39 It is possible to use any of the `manylinux` docker images: `manylinux1`, `manylinux2010` or `manylinux2014`. (Just replace `manylinux2014` in the above instructions with the alternative version you wish to use.) -### Binary wheels on macOS +#### Binary wheels on macOS For building wheels on macOS it is sufficient to use one of the default `python -m build` or `pip wheel --no-deps . --wheel-dir dist` commands. From ebc9e8277f2f7761fff989a7f8f1eb196ae1759b Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Thu, 1 Feb 2024 21:56:07 +0000 Subject: [PATCH 2/2] deprecate `RustExtension.py_limited_api` --- CHANGELOG.md | 4 ++++ README.md | 1 - examples/hello-world-setuppy/setup.py | 1 - examples/hello-world/pyproject.toml | 1 - examples/rust_with_cffi/setup.py | 2 +- setuptools_rust/extension.py | 24 ++++++++---------------- 6 files changed, 13 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a132961..367818e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased +### Changed +- Deprecate `py_limited_api` option to `RustExtension` in favour of always using `"auto"` to configure this from `bdist_wheel`. [#410](https://github.com/PyO3/setuptools-rust/pull/410) + ## 1.8.1 (2023-10-30) ### Fixed - Fix regression in `install_extension` crashing since 1.8.0. [#380](https://github.com/PyO3/setuptools-rust/pull/380) diff --git a/README.md b/README.md index 89a54da7..e0310841 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,6 @@ target = "hello_world._lib" # The last part of the name (e.g. "_lib") has to ma # but you can add a prefix to nest it inside of a Python package. path = "Cargo.toml" # Default value, can be omitted binding = "PyO3" # Default value, can be omitted -py-limited-api = "auto" # Default value, can be omitted ``` Each extension module should map directly into the corresponding `[lib]` table on the diff --git a/examples/hello-world-setuppy/setup.py b/examples/hello-world-setuppy/setup.py index 44be5d43..15c3a002 100644 --- a/examples/hello-world-setuppy/setup.py +++ b/examples/hello-world-setuppy/setup.py @@ -14,7 +14,6 @@ # in Cargo.toml and the function name in the `.rs` file, # but you can add a prefix to nest it inside of a Python package. path="Cargo.toml", # Default value, can be omitted - py_limited_api="auto", # Default value, can be omitted binding=Binding.PyO3, # Default value, can be omitted ) ], diff --git a/examples/hello-world/pyproject.toml b/examples/hello-world/pyproject.toml index 84163491..7afbac54 100644 --- a/examples/hello-world/pyproject.toml +++ b/examples/hello-world/pyproject.toml @@ -19,7 +19,6 @@ find = { where = ["python"] } # Private Rust extension module to be nested into Python package target = "hello_world._lib" # The last part of the name (e.g. "_lib") has to match lib.name in Cargo.toml, # but you can add a prefix to nest it inside of a Python package. -py-limited-api = "auto" # Default value, can be omitted binding = "PyO3" # Default value, can be omitted # See reference for RustExtension in https://setuptools-rust.readthedocs.io/en/latest/reference.html diff --git a/examples/rust_with_cffi/setup.py b/examples/rust_with_cffi/setup.py index 87c223ee..a288a58f 100644 --- a/examples/rust_with_cffi/setup.py +++ b/examples/rust_with_cffi/setup.py @@ -17,7 +17,7 @@ packages=find_packages(where="python"), package_dir={"": "python"}, rust_extensions=[ - RustExtension("rust_with_cffi.rust", py_limited_api="auto"), + RustExtension("rust_with_cffi.rust"), ], cffi_modules=["cffi_module.py:ffi"], install_requires=["cffi"], diff --git a/setuptools_rust/extension.py b/setuptools_rust/extension.py index 698188fb..2d6e5aa7 100644 --- a/setuptools_rust/extension.py +++ b/setuptools_rust/extension.py @@ -107,22 +107,7 @@ class RustExtension: optional: If it is true, a build failure in the extension will not abort the build process, and instead simply not install the failing extension. - py_limited_api: Similar to ``py_limited_api`` on - ``setuptools.Extension``, this controls whether the built extension - should be considered compatible with the PEP 384 "limited API". - - - ``'auto'``: the ``py_limited_api`` option of - ``bdist_wheel`` will control whether the extension is - built as a limited api extension. The corresponding - ``pyo3/abi3-pyXY`` feature will be set accordingly. - This is the recommended setting, as it allows - to build a version-specific extension for best performance. - - - ``True``: the extension is assumed to be compatible with the - limited abi. You must ensure this is the case (e.g. by setting - the ``pyo3/abi3`` feature). - - - ``False``: the extension is version-specific. + py_limited_api: Deprecated. """ def __init__( @@ -180,6 +165,13 @@ def __init__( DeprecationWarning, ) + if self.py_limited_api != "auto": + warnings.warn( + "`RustExtension.py_limited_api` is deprecated, use [bdist_wheel] configuration " + "in `setup.cfg` or `DIST_EXTRA_CONFIG` to build abi3 wheels.", + DeprecationWarning, + ) + def get_lib_name(self, *, quiet: bool) -> str: """Parse Cargo.toml to get the name of the shared library.""" metadata = self.metadata(quiet=quiet)