diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a5539643..59ad8b9c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -120,8 +120,8 @@ jobs: PYO3_CROSS_LIB_DIR: /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib run: | cd examples/namespace_package - pip install wheel - python setup.py bdist_wheel + pip install build wheel + python -m build --no-isolation ls -l dist/ pip install --force-reinstall dist/namespace_package*_universal2.whl cd - @@ -159,16 +159,18 @@ jobs: - name: Build an abi3 wheel shell: bash + env: + # https://github.com/actions/setup-python/issues/26 + MACOSX_DEPLOYMENT_TARGET: 10.9 + DIST_EXTRA_CONFIG: /tmp/build-opts.cfg run: | set -e cd examples/rust_with_cffi/ python --version - pip install -U wheel - python setup.py bdist_wheel --py-limited-api=cp39 + pip install -U build cffi wheel + echo -e "[bdist_wheel]\npy_limited_api=cp39" > $DIST_EXTRA_CONFIG + python -m build --no-isolation ls -la dist/ - env: - # https://github.com/actions/setup-python/issues/26 - MACOSX_DEPLOYMENT_TARGET: 10.9 # Now we switch to a differnet Python version and ensure we can install # the wheel we just built. @@ -222,12 +224,20 @@ jobs: python3.9 -m pip install crossenv python3.9 -m crossenv "/opt/python/cp39-cp39/bin/python3" --cc $TARGET_CC --cxx $TARGET_CXX --sysroot $TARGET_SYSROOT --env LIBRARY_PATH= --manylinux manylinux1 venv . venv/bin/activate - build-pip install cffi wheel "setuptools>=62.4" + + build-pip install -U pip>=23.2.1 setuptools>=68.0.0 wheel>=0.41.1 + cross-pip install -U pip>=23.2.1 setuptools>=68.0.0 wheel>=0.41.1 + build-pip install cffi cross-expose cffi - pip install wheel - pip install -e ../../ - python setup.py bdist_wheel --py-limited-api=cp37 + cross-pip install -e ../../ + cross-pip list + + export DIST_EXTRA_CONFIG=/tmp/build-opts.cfg + echo -e "[bdist_wheel]\npy_limited_api=cp37" > $DIST_EXTRA_CONFIG + + cross-pip wheel --no-build-isolation --no-deps --wheel-dir dist . ls -la dist/ + python -m zipfile -l dist/*.whl # debug all files inside wheel file ' > build-wheels.sh docker run --rm -v "$PWD":/io -w /io messense/manylinux2014-cross:${{ matrix.platform.arch }} bash build-wheels.sh @@ -269,12 +279,15 @@ jobs: CARGO: cross CARGO_BUILD_TARGET: aarch64-unknown-linux-gnu PYO3_CROSS_LIB_DIR: /opt/python/cp38-cp38/lib + DIST_EXTRA_CONFIG: /tmp/build-opts.cfg run: | cd examples/namespace_package docker build -t cross-pyo3:aarch64-unknown-linux-gnu . - python -m pip install wheel - python setup.py bdist_wheel --plat-name manylinux2014_aarch64 + python -m pip install build wheel + echo -e "[bdist_wheel]\nplat_name=manylinux2014_aarch64" > $DIST_EXTRA_CONFIG + python -m build --no-isolation ls -la dist/ + unzip -l dist/*.whl # debug all files inside wheel file - uses: uraimo/run-on-arch-action@v2.5.0 name: Install built wheel with: @@ -313,13 +326,16 @@ jobs: CARGO: cargo-zigbuild CARGO_BUILD_TARGET: aarch64-unknown-linux-gnu PYO3_CROSS_LIB_DIR: /opt/python/cp38-cp38/lib + DIST_EXTRA_CONFIG: /tmp/build-opts.cfg run: | mkdir -p $PYO3_CROSS_LIB_DIR docker cp -L $(docker create --rm quay.io/pypa/manylinux2014_aarch64:latest):/opt/python/cp38-cp38 /opt/python cd examples/namespace_package - python -m pip install wheel - python setup.py bdist_wheel --plat-name manylinux2014_aarch64 + python -m pip install build wheel + echo -e "[bdist_wheel]\nplat_name=manylinux2014_aarch64" > $DIST_EXTRA_CONFIG + python -m build --no-isolation ls -la dist/ + unzip -l dist/*.whl # debug all files inside wheel file - uses: uraimo/run-on-arch-action@v2.5.0 name: Install built wheel with: @@ -346,9 +362,15 @@ jobs: - uses: pypa/cibuildwheel@v2.3.1 env: CIBW_BUILD: cp39-* - CIBW_BEFORE_BUILD: pip install -e . + CIBW_BEFORE_BUILD: pip install -U 'pip>=23.2.1' 'setuptools>=68.0.0' 'wheel<=0.37.1' && pip install -e . && pip list + # ^-- cap on `wheel` is a workaround for pypa/auditwheel#436 + # setuptools needs to be upgraded before installing setuptools-rust CIBW_ARCHS_MACOS: "x86_64 universal2 arm64" - CIBW_BUILD_VERBOSITY: 1 + CIBW_BUILD_VERBOSITY: 3 + CIBW_BUILD_FRONTEND: pip # pip allows disabling isolation via env var + CIBW_ENVIRONMENT: PIP_NO_BUILD_ISOLATION=false + # ^-- necessary to use working copy of setuptools-rust, + # (however PIP_NO_BUILD_ISOLATION is counter-intuitive: see pypa/pip#5735) with: package-dir: examples/namespace_package diff --git a/CHANGELOG.md b/CHANGELOG.md index ae6b7ffc..e9e84de9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ ### Added - Add support for `pyproject.toml` configuration using `[tool.setuptools-rust]` options. [#348](https://github.com/PyO3/setuptools-rust/pull/348) +### Fixed +- Fix `plat_name` handling in the case `bdist_wheel.plat_name` is set via configuration file (e.g., `setup.cfg`). [#352](https://github.com/PyO3/setuptools-rust/pull/352) + ## 1.6.0 (2023-04-27) ### Changed - Prefer passing `--crate-type` option to cargo if "toolchain >= 1.64". [#322](https://github.com/PyO3/setuptools-rust/pull/322) diff --git a/examples/hello-world-pyprojecttoml/Cargo.lock b/examples/hello-world-pyprojecttoml/Cargo.lock deleted file mode 100644 index df786659..00000000 --- a/examples/hello-world-pyprojecttoml/Cargo.lock +++ /dev/null @@ -1,274 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "hello-world" -version = "0.1.0" -dependencies = [ - "pyo3", - "pyo3-build-config", -] - -[[package]] -name = "indoc" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" - -[[package]] -name = "libc" -version = "0.2.147" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" - -[[package]] -name = "lock_api" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - -[[package]] -name = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets", -] - -[[package]] -name = "proc-macro2" -version = "1.0.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "pyo3" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e681a6cfdc4adcc93b4d3cf993749a4552018ee0a9b65fc0ccfad74352c72a38" -dependencies = [ - "cfg-if", - "indoc", - "libc", - "memoffset", - "parking_lot", - "pyo3-build-config", - "pyo3-ffi", - "pyo3-macros", - "unindent", -] - -[[package]] -name = "pyo3-build-config" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076c73d0bc438f7a4ef6fdd0c3bb4732149136abd952b110ac93e4edb13a6ba5" -dependencies = [ - "once_cell", - "target-lexicon", -] - -[[package]] -name = "pyo3-ffi" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53cee42e77ebe256066ba8aa77eff722b3bb91f3419177cf4cd0f304d3284d9" -dependencies = [ - "libc", - "pyo3-build-config", -] - -[[package]] -name = "pyo3-macros" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfeb4c99597e136528c6dd7d5e3de5434d1ceaf487436a3f03b2d56b6fc9efd1" -dependencies = [ - "proc-macro2", - "pyo3-macros-backend", - "quote", - "syn", -] - -[[package]] -name = "pyo3-macros-backend" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "947dc12175c254889edc0c02e399476c2f652b4b9ebd123aa655c224de259536" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "quote" -version = "1.0.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "smallvec" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "target-lexicon" -version = "0.12.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" - -[[package]] -name = "unicode-ident" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" - -[[package]] -name = "unindent" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1766d682d402817b5ac4490b3c3002d91dfa0d22812f341609f97b08757359c" - -[[package]] -name = "windows-targets" -version = "0.48.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" diff --git a/examples/hello-world-pyprojecttoml/Cargo.toml b/examples/hello-world-pyprojecttoml/Cargo.toml deleted file mode 100644 index eda9301c..00000000 --- a/examples/hello-world-pyprojecttoml/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "hello-world" -version = "0.1.0" -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -pyo3 = { version = "0.19.2", features = ["extension-module"] } - -[profile.release-lto] -inherits = "release" -lto = true - -[lib] -# See https://github.com/PyO3/pyo3 for details -name = "_lib" # private module to be nested into Python package -crate-type = ["cdylib"] -path = "rust/lib.rs" - -[[bin]] -name = "print-hello" -path = "rust/print_hello.rs" - -[build-dependencies] -pyo3-build-config = "0.19.2" diff --git a/examples/hello-world-pyprojecttoml/MANIFEST.in b/examples/hello-world-pyprojecttoml/MANIFEST.in deleted file mode 100644 index c79be56f..00000000 --- a/examples/hello-world-pyprojecttoml/MANIFEST.in +++ /dev/null @@ -1,6 +0,0 @@ -graft python -graft rust -graft tests -include Cargo.toml noxfile.py build.rs -global-exclude */__pycache__/* -global-exclude *.pyc diff --git a/examples/hello-world-pyprojecttoml/noxfile.py b/examples/hello-world-pyprojecttoml/noxfile.py deleted file mode 100644 index 7aa13342..00000000 --- a/examples/hello-world-pyprojecttoml/noxfile.py +++ /dev/null @@ -1,20 +0,0 @@ -from os.path import dirname - -import nox - -SETUPTOOLS_RUST = dirname(dirname(dirname(__file__))) - - -@nox.session() -def test(session: nox.Session): - session.install(SETUPTOOLS_RUST, "wheel", "build", "pytest") - # Ensure build works as intended - session.install("--no-build-isolation", ".") - # Test Rust binary - session.run("print-hello") - # Test script wrapper for Python entry-point - session.run("sum-cli", "5", "7") - session.run("rust-demo", "5", "7") - # Test library - session.run("pytest", "tests", *session.posargs) - session.run("python", "-c", "from hello_world import _lib; print(_lib)") diff --git a/examples/hello-world-pyprojecttoml/pyproject.toml b/examples/hello-world-pyprojecttoml/pyproject.toml deleted file mode 100644 index 84163491..00000000 --- a/examples/hello-world-pyprojecttoml/pyproject.toml +++ /dev/null @@ -1,31 +0,0 @@ -[build-system] -requires = ["setuptools", "setuptools-rust"] -build-backend = "setuptools.build_meta" - -[project] -name = "hello-world" -version = "1.0" - -[project.scripts] -# Python entry-point wrapper to be installed in `$venv/bin` -sum-cli = "hello_world.sum_cli:main" # Python function that uses Rust -rust-demo = "hello_world._lib:demo" # Rust function that uses Python - -[tool.setuptools.packages] -# Pure Python packages/modules -find = { where = ["python"] } - -[[tool.setuptools-rust.ext-modules]] -# 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 - -[[tool.setuptools-rust.bins]] -# Rust executable to be installed in `$venv/bin` -target = "print-hello" # Needs to match bin.name in Cargo.toml -args = ["--profile", "release-lto"] # Extra args for Cargo -# See reference for RustBin in https://setuptools-rust.readthedocs.io/en/latest/reference.html -# Note that you can also use Python entry-points as alternative to Rust binaries diff --git a/examples/hello-world-pyprojecttoml/python/hello_world/__init__.py b/examples/hello-world-pyprojecttoml/python/hello_world/__init__.py deleted file mode 100644 index 30f12921..00000000 --- a/examples/hello-world-pyprojecttoml/python/hello_world/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from ._lib import sum_as_string # export public parts of the binary extension - -__all__ = ["sum_as_string"] diff --git a/examples/hello-world-script/Cargo.toml b/examples/hello-world-script/Cargo.toml index 3de8ff33..7556deb4 100644 --- a/examples/hello-world-script/Cargo.toml +++ b/examples/hello-world-script/Cargo.toml @@ -10,3 +10,15 @@ edition = "2018" [profile.release-lto] inherits = "release" lto = true + +[[bin]] +name = "hello-world-script" +path = "rust/main.rs" +# See https://doc.rust-lang.org/cargo/reference/cargo-targets.html#binaries +# +# If [[bin]] is not specified, but the file ``src/main.rs`` exists, +# you can also rely on an implicit definition which will behave similarly to: +# +# [[bin]] +# name = +# path = "src/main.rs" diff --git a/examples/hello-world-script/MANIFEST.in b/examples/hello-world-script/MANIFEST.in index 53741426..7c475173 100644 --- a/examples/hello-world-script/MANIFEST.in +++ b/examples/hello-world-script/MANIFEST.in @@ -1,3 +1,3 @@ include Cargo.toml -recursive-include src * +recursive-include rust * recursive-include python * diff --git a/examples/hello-world-script/noxfile.py b/examples/hello-world-script/noxfile.py index 3fed5bb9..2f34dc52 100644 --- a/examples/hello-world-script/noxfile.py +++ b/examples/hello-world-script/noxfile.py @@ -8,12 +8,9 @@ @nox.session() def test(session: nox.Session): session.install(SETUPTOOLS_RUST, "wheel") + # Ensure build uses version of setuptools-rust under development session.install("--no-build-isolation", ".") + # Test Rust binary session.run("hello-world-script", *session.posargs) - - -@nox.session() -def setuptools_install(session: nox.Session): - session.install(SETUPTOOLS_RUST) - session.run("python", "setup.py", "install") - session.run("hello-world-script", *session.posargs) + # Test Python package + session.run("python", "-c", "import hello_world; print(hello_world)") diff --git a/examples/hello-world-script/pyproject.toml b/examples/hello-world-script/pyproject.toml index 8619d878..8021b80c 100644 --- a/examples/hello-world-script/pyproject.toml +++ b/examples/hello-world-script/pyproject.toml @@ -1,3 +1,17 @@ [build-system] requires = ["setuptools", "wheel", "setuptools-rust"] build-backend = "setuptools.build_meta" + +[project] +name = "hello-world" +version = "1.0" + +[tool.setuptools.packages] +# Pure Python packages/modules +find = { where = ["python"] } + +[[tool.setuptools-rust.bins]] +# Private Rust extension module to be nested into Python package +target = "hello-world-script" # Matches bin.name in Cargo.toml +args = ["--profile", "release-lto"] # Extra args for Cargo +# See reference for RustBin in https://setuptools-rust.readthedocs.io/en/latest/reference.html diff --git a/examples/hello-world-script/src/main.rs b/examples/hello-world-script/rust/main.rs similarity index 100% rename from examples/hello-world-script/src/main.rs rename to examples/hello-world-script/rust/main.rs diff --git a/examples/hello-world-script/setup.py b/examples/hello-world-script/setup.py deleted file mode 100644 index 7ea2e072..00000000 --- a/examples/hello-world-script/setup.py +++ /dev/null @@ -1,20 +0,0 @@ -from setuptools import find_packages, setup - -from setuptools_rust import RustExtension, Binding - -setup( - name="hello-world-script", - version="1.0", - packages=find_packages(where="python"), - package_dir={"": "python"}, - rust_extensions=[ - RustExtension( - {"hello-world-script": "hello_world.hello-world-script"}, - binding=Binding.Exec, - script=True, - args=["--profile", "release-lto"], - ) - ], - # rust extensions are not zip safe, just like C-extensions. - zip_safe=False, -) diff --git a/examples/hello-world-setuppy/Cargo.lock b/examples/hello-world-setuppy/Cargo.lock new file mode 100644 index 00000000..e7cecae9 --- /dev/null +++ b/examples/hello-world-setuppy/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "hello-world" +version = "0.1.0" diff --git a/examples/hello-world-setuppy/Cargo.toml b/examples/hello-world-setuppy/Cargo.toml new file mode 100644 index 00000000..879d064b --- /dev/null +++ b/examples/hello-world-setuppy/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "hello-world" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + +[profile.release-lto] +inherits = "release" +lto = true + +[[bin]] +name = "hello-world" +path = "rust/main.rs" diff --git a/examples/hello-world-setuppy/MANIFEST.in b/examples/hello-world-setuppy/MANIFEST.in new file mode 100644 index 00000000..7c475173 --- /dev/null +++ b/examples/hello-world-setuppy/MANIFEST.in @@ -0,0 +1,3 @@ +include Cargo.toml +recursive-include rust * +recursive-include python * diff --git a/examples/hello-world-setuppy/noxfile.py b/examples/hello-world-setuppy/noxfile.py new file mode 100644 index 00000000..e7a54bdc --- /dev/null +++ b/examples/hello-world-setuppy/noxfile.py @@ -0,0 +1,14 @@ +from os.path import dirname + +import nox + +SETUPTOOLS_RUST = dirname(dirname(dirname(__file__))) + + +@nox.session() +def test(session: nox.Session): + session.install(SETUPTOOLS_RUST, "wheel") + # Ensure build uses version of setuptools-rust under development + session.install("--no-build-isolation", ".") + # Test Rust binary + session.run("hello-world", *session.posargs) diff --git a/examples/hello-world-setuppy/pyproject.toml b/examples/hello-world-setuppy/pyproject.toml new file mode 100644 index 00000000..8619d878 --- /dev/null +++ b/examples/hello-world-setuppy/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools", "wheel", "setuptools-rust"] +build-backend = "setuptools.build_meta" diff --git a/examples/hello-world/pytest.ini b/examples/hello-world-setuppy/pytest.ini similarity index 100% rename from examples/hello-world/pytest.ini rename to examples/hello-world-setuppy/pytest.ini diff --git a/examples/hello-world-setuppy/python/hello_world/__init__.py b/examples/hello-world-setuppy/python/hello_world/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/examples/hello-world/src/main.rs b/examples/hello-world-setuppy/rust/main.rs similarity index 100% rename from examples/hello-world/src/main.rs rename to examples/hello-world-setuppy/rust/main.rs diff --git a/examples/hello-world/setup.py b/examples/hello-world-setuppy/setup.py similarity index 100% rename from examples/hello-world/setup.py rename to examples/hello-world-setuppy/setup.py diff --git a/examples/hello-world/Cargo.lock b/examples/hello-world/Cargo.lock index e7cecae9..df786659 100644 --- a/examples/hello-world/Cargo.lock +++ b/examples/hello-world/Cargo.lock @@ -2,6 +2,273 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "hello-world" version = "0.1.0" +dependencies = [ + "pyo3", + "pyo3-build-config", +] + +[[package]] +name = "indoc" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" + +[[package]] +name = "libc" +version = "0.2.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "lock_api" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "pyo3" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e681a6cfdc4adcc93b4d3cf993749a4552018ee0a9b65fc0ccfad74352c72a38" +dependencies = [ + "cfg-if", + "indoc", + "libc", + "memoffset", + "parking_lot", + "pyo3-build-config", + "pyo3-ffi", + "pyo3-macros", + "unindent", +] + +[[package]] +name = "pyo3-build-config" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "076c73d0bc438f7a4ef6fdd0c3bb4732149136abd952b110ac93e4edb13a6ba5" +dependencies = [ + "once_cell", + "target-lexicon", +] + +[[package]] +name = "pyo3-ffi" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e53cee42e77ebe256066ba8aa77eff722b3bb91f3419177cf4cd0f304d3284d9" +dependencies = [ + "libc", + "pyo3-build-config", +] + +[[package]] +name = "pyo3-macros" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfeb4c99597e136528c6dd7d5e3de5434d1ceaf487436a3f03b2d56b6fc9efd1" +dependencies = [ + "proc-macro2", + "pyo3-macros-backend", + "quote", + "syn", +] + +[[package]] +name = "pyo3-macros-backend" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "947dc12175c254889edc0c02e399476c2f652b4b9ebd123aa655c224de259536" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "quote" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "smallvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "target-lexicon" +version = "0.12.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "unindent" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1766d682d402817b5ac4490b3c3002d91dfa0d22812f341609f97b08757359c" + +[[package]] +name = "windows-targets" +version = "0.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" diff --git a/examples/hello-world/Cargo.toml b/examples/hello-world/Cargo.toml index a432ecd4..eda9301c 100644 --- a/examples/hello-world/Cargo.toml +++ b/examples/hello-world/Cargo.toml @@ -6,7 +6,21 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +pyo3 = { version = "0.19.2", features = ["extension-module"] } [profile.release-lto] inherits = "release" lto = true + +[lib] +# See https://github.com/PyO3/pyo3 for details +name = "_lib" # private module to be nested into Python package +crate-type = ["cdylib"] +path = "rust/lib.rs" + +[[bin]] +name = "print-hello" +path = "rust/print_hello.rs" + +[build-dependencies] +pyo3-build-config = "0.19.2" diff --git a/examples/hello-world/MANIFEST.in b/examples/hello-world/MANIFEST.in index 53741426..c79be56f 100644 --- a/examples/hello-world/MANIFEST.in +++ b/examples/hello-world/MANIFEST.in @@ -1,3 +1,6 @@ -include Cargo.toml -recursive-include src * -recursive-include python * +graft python +graft rust +graft tests +include Cargo.toml noxfile.py build.rs +global-exclude */__pycache__/* +global-exclude *.pyc diff --git a/examples/hello-world-pyprojecttoml/build.rs b/examples/hello-world/build.rs similarity index 100% rename from examples/hello-world-pyprojecttoml/build.rs rename to examples/hello-world/build.rs diff --git a/examples/hello-world/noxfile.py b/examples/hello-world/noxfile.py index 2c14c8cf..7aa13342 100644 --- a/examples/hello-world/noxfile.py +++ b/examples/hello-world/noxfile.py @@ -7,13 +7,14 @@ @nox.session() def test(session: nox.Session): - session.install(SETUPTOOLS_RUST, "wheel") + session.install(SETUPTOOLS_RUST, "wheel", "build", "pytest") + # Ensure build works as intended session.install("--no-build-isolation", ".") - session.run("hello-world", *session.posargs) - - -@nox.session() -def setuptools_install(session: nox.Session): - session.install(SETUPTOOLS_RUST) - session.run("python", "setup.py", "install") - session.run("hello-world", *session.posargs) + # Test Rust binary + session.run("print-hello") + # Test script wrapper for Python entry-point + session.run("sum-cli", "5", "7") + session.run("rust-demo", "5", "7") + # Test library + session.run("pytest", "tests", *session.posargs) + session.run("python", "-c", "from hello_world import _lib; print(_lib)") diff --git a/examples/hello-world/pyproject.toml b/examples/hello-world/pyproject.toml index 8619d878..84163491 100644 --- a/examples/hello-world/pyproject.toml +++ b/examples/hello-world/pyproject.toml @@ -1,3 +1,31 @@ [build-system] -requires = ["setuptools", "wheel", "setuptools-rust"] +requires = ["setuptools", "setuptools-rust"] build-backend = "setuptools.build_meta" + +[project] +name = "hello-world" +version = "1.0" + +[project.scripts] +# Python entry-point wrapper to be installed in `$venv/bin` +sum-cli = "hello_world.sum_cli:main" # Python function that uses Rust +rust-demo = "hello_world._lib:demo" # Rust function that uses Python + +[tool.setuptools.packages] +# Pure Python packages/modules +find = { where = ["python"] } + +[[tool.setuptools-rust.ext-modules]] +# 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 + +[[tool.setuptools-rust.bins]] +# Rust executable to be installed in `$venv/bin` +target = "print-hello" # Needs to match bin.name in Cargo.toml +args = ["--profile", "release-lto"] # Extra args for Cargo +# See reference for RustBin in https://setuptools-rust.readthedocs.io/en/latest/reference.html +# Note that you can also use Python entry-points as alternative to Rust binaries diff --git a/examples/hello-world/python/hello_world/__init__.py b/examples/hello-world/python/hello_world/__init__.py index e69de29b..30f12921 100644 --- a/examples/hello-world/python/hello_world/__init__.py +++ b/examples/hello-world/python/hello_world/__init__.py @@ -0,0 +1,3 @@ +from ._lib import sum_as_string # export public parts of the binary extension + +__all__ = ["sum_as_string"] diff --git a/examples/hello-world-pyprojecttoml/python/hello_world/sum_cli.py b/examples/hello-world/python/hello_world/sum_cli.py similarity index 100% rename from examples/hello-world-pyprojecttoml/python/hello_world/sum_cli.py rename to examples/hello-world/python/hello_world/sum_cli.py diff --git a/examples/hello-world-pyprojecttoml/rust/lib.rs b/examples/hello-world/rust/lib.rs similarity index 100% rename from examples/hello-world-pyprojecttoml/rust/lib.rs rename to examples/hello-world/rust/lib.rs diff --git a/examples/hello-world-pyprojecttoml/rust/print_hello.rs b/examples/hello-world/rust/print_hello.rs similarity index 100% rename from examples/hello-world-pyprojecttoml/rust/print_hello.rs rename to examples/hello-world/rust/print_hello.rs diff --git a/examples/hello-world-pyprojecttoml/tests/test_hello_world.py b/examples/hello-world/tests/test_hello_world.py similarity index 100% rename from examples/hello-world-pyprojecttoml/tests/test_hello_world.py rename to examples/hello-world/tests/test_hello_world.py diff --git a/examples/html-py-ever/Cargo.toml b/examples/html-py-ever/Cargo.toml index bf387ab6..e469ed67 100644 --- a/examples/html-py-ever/Cargo.toml +++ b/examples/html-py-ever/Cargo.toml @@ -12,3 +12,4 @@ tendril = "0.4.3" [lib] name = "html_py_ever" crate-type = ["cdylib"] +path = "rust/lib.rs" diff --git a/examples/html-py-ever/MANIFEST.in b/examples/html-py-ever/MANIFEST.in index 53741426..7c475173 100644 --- a/examples/html-py-ever/MANIFEST.in +++ b/examples/html-py-ever/MANIFEST.in @@ -1,3 +1,3 @@ include Cargo.toml -recursive-include src * +recursive-include rust * recursive-include python * diff --git a/examples/html-py-ever/noxfile.py b/examples/html-py-ever/noxfile.py index 2c830e39..b2636c99 100644 --- a/examples/html-py-ever/noxfile.py +++ b/examples/html-py-ever/noxfile.py @@ -10,12 +10,7 @@ def test(session: nox.Session): session.install( SETUPTOOLS_RUST, "wheel", "pytest", "pytest-benchmark", "beautifulsoup4" ) + # Ensure build uses version of setuptools-rust under development session.install("--no-build-isolation", ".") - session.run("pytest", *session.posargs) - - -@nox.session() -def setuptools_install(session: nox.Session): - session.install(SETUPTOOLS_RUST, "pytest", "pytest-benchmark", "beautifulsoup4") - session.run("python", "setup.py", "install") + # Test Python package session.run("pytest", *session.posargs) diff --git a/examples/html-py-ever/pyproject.toml b/examples/html-py-ever/pyproject.toml index 8619d878..7e168df6 100644 --- a/examples/html-py-ever/pyproject.toml +++ b/examples/html-py-ever/pyproject.toml @@ -1,3 +1,19 @@ [build-system] requires = ["setuptools", "wheel", "setuptools-rust"] build-backend = "setuptools.build_meta" + +[project] +name = "html-py-ever" +version = "0.1.0" + +[tool.setuptools.packages] +# Pure Python packages/modules +find = { where = ["python"] } + + +[[tool.setuptools-rust.ext-modules]] +# Rust extension module to be nested into Python package +target = "html_py_ever.html_py_ever" +# ^-- The last part of the name (e.g. "html_py_ever") has to match lib.name in Cargo.toml, +# but you can add a prefix to nest it inside of a Python package. +# See reference for RustExtension in https://setuptools-rust.readthedocs.io/en/latest/reference.html diff --git a/examples/html-py-ever/src/lib.rs b/examples/html-py-ever/rust/lib.rs similarity index 100% rename from examples/html-py-ever/src/lib.rs rename to examples/html-py-ever/rust/lib.rs diff --git a/examples/html-py-ever/src/main.rs b/examples/html-py-ever/rust/main.rs similarity index 100% rename from examples/html-py-ever/src/main.rs rename to examples/html-py-ever/rust/main.rs diff --git a/examples/html-py-ever/setup.py b/examples/html-py-ever/setup.py deleted file mode 100755 index 7d236d43..00000000 --- a/examples/html-py-ever/setup.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -from setuptools import find_packages, setup - -from setuptools_rust import RustExtension - -setup( - packages=find_packages(where="python"), - package_dir={"": "python"}, - rust_extensions=[RustExtension("html_py_ever.html_py_ever")], -) diff --git a/examples/namespace_package/Cargo.toml b/examples/namespace_package/Cargo.toml index eed58b45..3c0019ee 100644 --- a/examples/namespace_package/Cargo.toml +++ b/examples/namespace_package/Cargo.toml @@ -4,7 +4,18 @@ version = "0.1.0" edition = "2018" [lib] +# When omitted, the name field will be assumed to have the same value as package.name +# https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-name-field crate-type = ["cdylib", "rlib"] +path = "rust/lib.rs" # When omitted, the value of "src/lib.rs" is assumed +# See https://doc.rust-lang.org/cargo/reference/cargo-targets.html#library +# +# If [lib] is not specified, but the file ``src/lib.rs`` exists, +# you can also rely on an implicit definition which will behave similarly to: +# +# [lib] +# name = +# path = "src/lib.rs" [dependencies] pyo3 = { version = "0.19.2", features = ["extension-module"] } diff --git a/examples/namespace_package/MANIFEST.in b/examples/namespace_package/MANIFEST.in index 53741426..f5c8d51c 100644 --- a/examples/namespace_package/MANIFEST.in +++ b/examples/namespace_package/MANIFEST.in @@ -1,3 +1,4 @@ include Cargo.toml -recursive-include src * +include Cross.toml +recursive-include rust * recursive-include python * diff --git a/examples/namespace_package/noxfile.py b/examples/namespace_package/noxfile.py index 089613f3..65d0a3f4 100644 --- a/examples/namespace_package/noxfile.py +++ b/examples/namespace_package/noxfile.py @@ -8,12 +8,7 @@ @nox.session() def test(session: nox.Session): session.install(SETUPTOOLS_RUST, "wheel", "pytest") + # Ensure build uses version of setuptools-rust under development session.install("--no-build-isolation", ".") - session.run("pytest", *session.posargs) - - -@nox.session() -def setuptools_install(session: nox.Session): - session.install(SETUPTOOLS_RUST, "pytest") - session.run("python", "setup.py", "install") + # Test Python package session.run("pytest", *session.posargs) diff --git a/examples/namespace_package/pyproject.toml b/examples/namespace_package/pyproject.toml index 8619d878..0b6302bd 100644 --- a/examples/namespace_package/pyproject.toml +++ b/examples/namespace_package/pyproject.toml @@ -1,3 +1,25 @@ [build-system] requires = ["setuptools", "wheel", "setuptools-rust"] build-backend = "setuptools.build_meta" + +[project] +name="namespace_package" +version="0.1.0" + +[tool.setuptools.packages] +# Pure Python packages/modules +find = { where = ["python"] } + +[[tool.setuptools-rust.ext-modules]] +target = "namespace_package.rust" +# ^-- The last part of the target name (e.g. "rust") should match lib.name in Cargo.toml, +# but you can add a prefix to nest it inside of a parent Python package or namespace. +# Note that lib.name may not be defined in the Cargo.toml, but you still +# have to match the name of the function with the `#[pymodule]` attribute. +path = "Cargo.toml" +# ^-- Default value for cargo's manifest (can be omitted) +# Each manifest can have a single [lib] definition. +# To specify multiple extension modules you can use different toml files (one each). +binding = "PyO3" # Default value, can be omitted +debug = false +# See reference for RustExtension in https://setuptools-rust.readthedocs.io/en/latest/reference.html diff --git a/examples/namespace_package/src/lib.rs b/examples/namespace_package/rust/lib.rs similarity index 100% rename from examples/namespace_package/src/lib.rs rename to examples/namespace_package/rust/lib.rs diff --git a/examples/namespace_package/setup.py b/examples/namespace_package/setup.py deleted file mode 100644 index 43003e94..00000000 --- a/examples/namespace_package/setup.py +++ /dev/null @@ -1,19 +0,0 @@ -from setuptools import setup, find_namespace_packages -from setuptools_rust import Binding, RustExtension - - -setup( - name="namespace_package", - version="0.1.0", - packages=find_namespace_packages(include=["namespace_package.*"], where="python"), - package_dir={"": "python"}, - zip_safe=False, - rust_extensions=[ - RustExtension( - "namespace_package.rust", - path="Cargo.toml", - binding=Binding.PyO3, - debug=False, - ) - ], -) diff --git a/examples/rust_with_cffi/Cargo.toml b/examples/rust_with_cffi/Cargo.toml index 3ea2bd48..ed70c85f 100644 --- a/examples/rust_with_cffi/Cargo.toml +++ b/examples/rust_with_cffi/Cargo.toml @@ -10,3 +10,4 @@ pyo3 = { version = "0.19.2", features = ["extension-module"] } [lib] name = "rust_with_cffi" crate-type = ["cdylib"] +path = "rust/lib.rs" diff --git a/examples/rust_with_cffi/MANIFEST.in b/examples/rust_with_cffi/MANIFEST.in index dba5df43..541ad8f4 100644 --- a/examples/rust_with_cffi/MANIFEST.in +++ b/examples/rust_with_cffi/MANIFEST.in @@ -1,4 +1,4 @@ include Cargo.toml include cffi_module.py -recursive-include src * +recursive-include rust * recursive-include python * diff --git a/examples/rust_with_cffi/noxfile.py b/examples/rust_with_cffi/noxfile.py index 7b3ec060..77b3287c 100644 --- a/examples/rust_with_cffi/noxfile.py +++ b/examples/rust_with_cffi/noxfile.py @@ -8,12 +8,7 @@ @nox.session() def test(session: nox.Session): session.install(SETUPTOOLS_RUST, "wheel", "pytest", "cffi") + # Ensure build uses version of setuptools-rust under development session.install("--no-build-isolation", ".") - session.run("pytest", *session.posargs) - - -@nox.session() -def setuptools_install(session: nox.Session): - session.install(SETUPTOOLS_RUST, "pytest", "cffi") - session.run("python", "setup.py", "install") + # Test Python package session.run("pytest", *session.posargs) diff --git a/examples/rust_with_cffi/pyproject.toml b/examples/rust_with_cffi/pyproject.toml index 8619d878..4b5a004a 100644 --- a/examples/rust_with_cffi/pyproject.toml +++ b/examples/rust_with_cffi/pyproject.toml @@ -1,3 +1,3 @@ [build-system] -requires = ["setuptools", "wheel", "setuptools-rust"] +requires = ["setuptools", "setuptools-rust", "cffi"] build-backend = "setuptools.build_meta" diff --git a/examples/rust_with_cffi/src/lib.rs b/examples/rust_with_cffi/rust/lib.rs similarity index 100% rename from examples/rust_with_cffi/src/lib.rs rename to examples/rust_with_cffi/rust/lib.rs diff --git a/examples/rust_with_cffi/setup.py b/examples/rust_with_cffi/setup.py index 3a99f443..87c223ee 100644 --- a/examples/rust_with_cffi/setup.py +++ b/examples/rust_with_cffi/setup.py @@ -21,7 +21,6 @@ ], cffi_modules=["cffi_module.py:ffi"], install_requires=["cffi"], - setup_requires=["cffi"], include_package_data=True, zip_safe=False, ) diff --git a/noxfile.py b/noxfile.py index 27f9547b..209785f9 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,5 +1,6 @@ import os import tarfile +from inspect import cleandoc as heredoc from glob import glob from pathlib import Path from unittest.mock import patch @@ -15,10 +16,22 @@ def test_examples(session: nox.Session): @nox.session(name="test-sdist-vendor") def test_sdist_vendor(session: nox.Session): - session.install(".") + session.install(".", "build", "wheel") namespace_package = Path(__file__).parent / "examples" / "namespace_package" os.chdir(namespace_package) - session.run("python", "setup.py", "sdist", "--vendor-crates", external=True) + tmp = session.create_tmp() + + build_config = """ + [sdist] + vendor_crates = True + """ + Path(tmp, "setup.cfg").write_text(heredoc(build_config), encoding="utf-8") + + env = os.environ.copy() + env.update(DIST_EXTRA_CONFIG=str(Path(tmp, "setup.cfg"))) + cmd = ["python", "-m", "build", "--sdist", "--no-isolation"] + session.run(*cmd, env=env, external=True) + dist = namespace_package / "dist" with tarfile.open(str(dist / "namespace_package-0.1.0.tar.gz")) as tf: tf.extractall(str(dist)) @@ -60,7 +73,9 @@ def chdir(path: Path): session.install(".") session.install("--no-build-isolation", str(examples / "hello-world")) - session.run("hello-world") + session.run("print-hello") + session.run("sum-cli", "5", "7") + session.run("rust-demo", "5", "7") session.install("pytest", "pytest-benchmark", "beautifulsoup4") session.install("--no-build-isolation", str(examples / "html-py-ever")) @@ -77,7 +92,7 @@ def chdir(path: Path): @nox.session(name="test-examples-emscripten") def test_examples_emscripten(session: nox.Session): - session.install(".") + session.install(".", "build") emscripten_dir = Path("./emscripten").resolve() session.run( @@ -108,7 +123,8 @@ def test_examples_emscripten(session: nox.Session): PYO3_CONFIG_FILE=str(emscripten_dir / "pyo3_config.ini"), ) with session.chdir(example): - session.run("python", "setup.py", "bdist_wheel", env=env, external=True) + cmd = ["python", "-m", "build", "--wheel", "--no-isolation"] + session.run(*cmd, env=env, external=True) with session.chdir(emscripten_dir): session.run("node", "runner.js", str(example), external=True) diff --git a/setuptools_rust/build.py b/setuptools_rust/build.py index 72e40cb2..70365b01 100644 --- a/setuptools_rust/build.py +++ b/setuptools_rust/build.py @@ -19,6 +19,8 @@ from typing import Dict, List, NamedTuple, Optional, Set, Tuple, cast import pkg_resources +from semantic_version import Version +from setuptools import Distribution from setuptools.command.build import build as CommandBuild from setuptools.command.build_ext import build_ext as CommandBuildExt from setuptools.command.build_ext import get_abi3_suffix @@ -36,6 +38,12 @@ logger = logging.getLogger(__name__) +try: + from wheel.bdist_wheel import bdist_wheel as CommandBdistWheel +except ImportError: # wheel installation might be deferred in PEP 517 + from setuptools import Command as CommandBdistWheel + + def _check_cargo_supports_crate_type_option() -> bool: version = get_rust_version() @@ -468,17 +476,13 @@ def get_dylib_ext_path(self, ext: RustExtension, target_fname: str) -> str: return ext_path def _py_limited_api(self) -> _PyLimitedApi: - bdist_wheel = self.distribution.get_command_obj("bdist_wheel", create=False) + bdist_wheel = _get_bdist_wheel_cmd(self.distribution, create=False) if bdist_wheel is None: # wheel package is not installed, not building a limited-api wheel return False else: - from wheel.bdist_wheel import bdist_wheel as CommandBdistWheel - - bdist_wheel_command = cast(CommandBdistWheel, bdist_wheel) # type: ignore[no-any-unimported] - bdist_wheel_command.ensure_finalized() - return cast(_PyLimitedApi, bdist_wheel_command.py_limited_api) + return cast(_PyLimitedApi, bdist_wheel.py_limited_api) def _detect_rust_target( self, forced_target_triple: Optional[str] = None @@ -773,3 +777,14 @@ def _replace_cross_target_dir(path: str, ext: RustExtension, *, quiet: bool) -> cross_target_dir = ext._metadata(cargo="cross", quiet=quiet)["target_directory"] local_target_dir = ext._metadata(cargo="cargo", quiet=quiet)["target_directory"] return path.replace(cross_target_dir, local_target_dir) + + +def _get_bdist_wheel_cmd( # type: ignore[no-any-unimported] + dist: Distribution, create: bool = True +) -> Optional[CommandBdistWheel]: + try: + cmd_obj = dist.get_command_obj("bdist_wheel", create=create) + cmd_obj.ensure_finalized() # type: ignore[union-attr] + return cast(CommandBdistWheel, cmd_obj) # type: ignore[no-any-unimported] + except Exception: + return None diff --git a/setuptools_rust/setuptools_ext.py b/setuptools_rust/setuptools_ext.py index 0a5d16f8..b59a7f52 100644 --- a/setuptools_rust/setuptools_ext.py +++ b/setuptools_rust/setuptools_ext.py @@ -4,7 +4,7 @@ import sysconfig import logging -from typing import List, Set, Tuple, Type, TypeVar, cast +from typing import List, Optional, Set, Tuple, Type, TypeVar, cast from functools import partial from setuptools.command.build_ext import build_ext @@ -16,6 +16,7 @@ from setuptools.dist import Distribution from typing_extensions import Literal +from .build import _get_bdist_wheel_cmd from .extension import Binding, RustBin, RustExtension, Strip try: @@ -163,13 +164,15 @@ def run(self) -> None: build_rust.inplace = self.inplace build_rust.target = self.target build_rust.verbose = self.verbose - options = self.distribution.get_cmdline_options().get("bdist_wheel", {}) - plat_name = options.get("plat-name") or self.plat_name - build_rust.plat_name = plat_name + build_rust.plat_name = self._get_wheel_plat_name() or self.plat_name build_rust.run() build_ext_base_class.run(self) + def _get_wheel_plat_name(self) -> Optional[str]: + cmd = _get_bdist_wheel_cmd(self.distribution) + return cast(Optional[str], getattr(cmd, "plat_name", None)) + dist.cmdclass["build_ext"] = build_ext_rust_extension clean_base_class = dist.cmdclass.get("clean")