diff --git a/Cargo.lock b/Cargo.lock index fb66e5eaa..5aaf59dcc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1090,6 +1090,7 @@ dependencies = [ "native-tls", "normpath", "once_cell", + "path-slash", "pep440_rs", "pep508_rs", "platform-info", diff --git a/Cargo.toml b/Cargo.toml index 6bac735fc..280efb7bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,6 +71,7 @@ lddtree = "0.3.3" cc = "1.0.72" dunce = "1.0.2" normpath = "1.0.0" +path-slash = "0.2.1" pep440_rs = { version = "0.3.6", features = ["serde"] } pep508_rs = { version = "0.2.1", features = ["serde"] } time = "0.3.17" diff --git a/src/source_distribution.rs b/src/source_distribution.rs index 0f4361a72..fe7022329 100644 --- a/src/source_distribution.rs +++ b/src/source_distribution.rs @@ -6,6 +6,7 @@ use cargo_metadata::{Metadata, MetadataCommand}; use fs_err as fs; use ignore::overrides::Override; use normpath::PathExt as _; +use path_slash::PathExt as _; use std::collections::HashMap; use std::path::{Path, PathBuf}; use std::process::Command; @@ -456,9 +457,9 @@ fn add_cargo_package_files_to_sdist( let mut deps_to_keep = known_path_deps.clone(); // Also need to the main Python binding crate let main_member_name = abs_manifest_dir - .strip_prefix(&sdist_root) + .strip_prefix(workspace_root) .unwrap() - .to_str() + .to_slash() .unwrap() .to_string(); deps_to_keep.insert( diff --git a/test-crates/pyo3-mixed-workspace/README.md b/test-crates/pyo3-mixed-workspace/README.md new file mode 100644 index 000000000..ae4698129 --- /dev/null +++ b/test-crates/pyo3-mixed-workspace/README.md @@ -0,0 +1,14 @@ +# pyo3-mixed src layout + +A package for testing maturin with a nested workspace. + +## Usage + +```bash +pip install . +``` + +```python +import pyo3_mixed_workspace +assert pyo3_mixed_workspace.get_42() == 42 +``` diff --git a/test-crates/pyo3-mixed-workspace/check_installed/check_installed.py b/test-crates/pyo3-mixed-workspace/check_installed/check_installed.py new file mode 100755 index 000000000..0b891b235 --- /dev/null +++ b/test-crates/pyo3-mixed-workspace/check_installed/check_installed.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python3 + +import pyo3_mixed_workspace as pyo3_mixed + +assert pyo3_mixed.get_42() == 42 + +print("SUCCESS") diff --git a/test-crates/pyo3-mixed-workspace/pyproject.toml b/test-crates/pyo3-mixed-workspace/pyproject.toml new file mode 100644 index 000000000..de98823c9 --- /dev/null +++ b/test-crates/pyo3-mixed-workspace/pyproject.toml @@ -0,0 +1,19 @@ +[build-system] +requires = ["maturin>=1.0,<2.0"] +build-backend = "maturin" + +[project] +name = "pyo3-mixed-workspace" +classifiers = [ + "Programming Language :: Python", + "Programming Language :: Rust" +] +requires-python = ">=3.7" + +[project.scripts] +get_42 = "pyo3_mixed_workspace:get_42" + +[tool.maturin] +python-packages = ["pyo3_mixed_workspace", "tests"] +module-name = "pyo3_mixed_workspace.pyo3_mixed_workspace_py" +manifest-path = "rust/python/pyo3-mixed-workspace-py/Cargo.toml" diff --git a/test-crates/pyo3-mixed-workspace/rust/Cargo.lock b/test-crates/pyo3-mixed-workspace/rust/Cargo.lock new file mode 100644 index 000000000..833e5715d --- /dev/null +++ b/test-crates/pyo3-mixed-workspace/rust/Cargo.lock @@ -0,0 +1,297 @@ +# 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 = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[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.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +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", + "python3-dll-a", + "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 = "pyo3-mixed-workspace" +version = "2.1.3" + +[[package]] +name = "pyo3-mixed-workspace-py" +version = "2.1.3" +dependencies = [ + "pyo3", + "pyo3-mixed-workspace", +] + +[[package]] +name = "python3-dll-a" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f07cd4412be8fa09a721d40007c483981bbe072cd6a21f2e83e04ec8f8343f" +dependencies = [ + "cc", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" + +[[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.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/test-crates/pyo3-mixed-workspace/rust/Cargo.toml b/test-crates/pyo3-mixed-workspace/rust/Cargo.toml new file mode 100644 index 000000000..3e2e6ad57 --- /dev/null +++ b/test-crates/pyo3-mixed-workspace/rust/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] +resolver = "2" +members = [ + "pyo3-mixed-workspace", + "python/pyo3-mixed-workspace-py", +] diff --git a/test-crates/pyo3-mixed-workspace/rust/pyo3-mixed-workspace/Cargo.toml b/test-crates/pyo3-mixed-workspace/rust/pyo3-mixed-workspace/Cargo.toml new file mode 100644 index 000000000..1c3bae17e --- /dev/null +++ b/test-crates/pyo3-mixed-workspace/rust/pyo3-mixed-workspace/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "pyo3-mixed-workspace" +version = "2.1.3" +description = "Implements a dummy function combining rust and python" +edition = "2021" + +[dependencies] diff --git a/test-crates/pyo3-mixed-workspace/rust/pyo3-mixed-workspace/src/lib.rs b/test-crates/pyo3-mixed-workspace/rust/pyo3-mixed-workspace/src/lib.rs new file mode 100644 index 000000000..d681ef926 --- /dev/null +++ b/test-crates/pyo3-mixed-workspace/rust/pyo3-mixed-workspace/src/lib.rs @@ -0,0 +1,3 @@ +pub fn get_21_lib() -> usize { + 21 +} diff --git a/test-crates/pyo3-mixed-workspace/rust/python/pyo3-mixed-workspace-py/Cargo.toml b/test-crates/pyo3-mixed-workspace/rust/python/pyo3-mixed-workspace-py/Cargo.toml new file mode 100644 index 000000000..db38ad4f0 --- /dev/null +++ b/test-crates/pyo3-mixed-workspace/rust/python/pyo3-mixed-workspace-py/Cargo.toml @@ -0,0 +1,14 @@ +[package] +authors = ["konstin "] +name = "pyo3-mixed-workspace-py" +version = "2.1.3" +description = "Implements a dummy function combining rust and python" +edition = "2021" + +[dependencies] +pyo3-mixed-workspace = { path = "../../pyo3-mixed-workspace" } +pyo3 = { version = "0.19.0", features = ["extension-module", "generate-import-lib"] } + +[lib] +name = "pyo3_mixed_workspace_py" +crate-type = ["cdylib"] diff --git a/test-crates/pyo3-mixed-workspace/rust/python/pyo3-mixed-workspace-py/src/lib.rs b/test-crates/pyo3-mixed-workspace/rust/python/pyo3-mixed-workspace-py/src/lib.rs new file mode 100644 index 000000000..8b0e0d629 --- /dev/null +++ b/test-crates/pyo3-mixed-workspace/rust/python/pyo3-mixed-workspace-py/src/lib.rs @@ -0,0 +1,15 @@ +use pyo3::prelude::*; + +use pyo3_mixed_workspace::get_21_lib; + +#[pyfunction] +fn get_21() -> usize { + get_21_lib() +} + +#[pymodule] +fn pyo3_mixed_workspace_py(_py: Python, m: &PyModule) -> PyResult<()> { + m.add_function(wrap_pyfunction!(get_21, m)?)?; + + Ok(()) +} diff --git a/test-crates/pyo3-mixed-workspace/src/pyo3_mixed_workspace/__init__.py b/test-crates/pyo3-mixed-workspace/src/pyo3_mixed_workspace/__init__.py new file mode 100644 index 000000000..0674c34a4 --- /dev/null +++ b/test-crates/pyo3-mixed-workspace/src/pyo3_mixed_workspace/__init__.py @@ -0,0 +1,6 @@ +from .python_module.double import double +from .pyo3_mixed_workspace_py import get_21 + + +def get_42() -> int: + return double(get_21) diff --git a/test-crates/pyo3-mixed-workspace/src/pyo3_mixed_workspace/python_module/__init__.py b/test-crates/pyo3-mixed-workspace/src/pyo3_mixed_workspace/python_module/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/test-crates/pyo3-mixed-workspace/src/pyo3_mixed_workspace/python_module/double.py b/test-crates/pyo3-mixed-workspace/src/pyo3_mixed_workspace/python_module/double.py new file mode 100644 index 000000000..2eed18d52 --- /dev/null +++ b/test-crates/pyo3-mixed-workspace/src/pyo3_mixed_workspace/python_module/double.py @@ -0,0 +1,5 @@ +from typing import Callable + + +def double(fn: Callable[[], int]) -> int: + return 2 * fn() diff --git a/test-crates/pyo3-mixed-workspace/src/tests/test_pyo3_mixed.py b/test-crates/pyo3-mixed-workspace/src/tests/test_pyo3_mixed.py new file mode 100644 index 000000000..903c95b2a --- /dev/null +++ b/test-crates/pyo3-mixed-workspace/src/tests/test_pyo3_mixed.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python3 + +import pyo3_mixed_workspace as pyo3_mixed + + +def test_get_42(): + assert pyo3_mixed.get_42() == 42 diff --git a/test-crates/pyo3-mixed-workspace/tox.ini b/test-crates/pyo3-mixed-workspace/tox.ini new file mode 100644 index 000000000..a7427eacf --- /dev/null +++ b/test-crates/pyo3-mixed-workspace/tox.ini @@ -0,0 +1,7 @@ +[tox] +envlist = py36,py37,py38 +isolated_build = True + +[testenv] +deps = pytest +commands = pytest src/tests/ diff --git a/tests/run.rs b/tests/run.rs index f0e87078a..0e132631f 100644 --- a/tests/run.rs +++ b/tests/run.rs @@ -483,6 +483,40 @@ fn workspace_cargo_lock() { handle_result(other::test_workspace_cargo_lock()) } +#[test] +fn workspace_members_beneath_pyproject_sdist() { + let cargo_toml = expect![[r#" + [workspace] + resolver = "2" + members = ["pyo3-mixed-workspace", "python/pyo3-mixed-workspace-py"] + "#]]; + handle_result(other::test_source_distribution( + "test-crates/pyo3-mixed-workspace/rust/python/pyo3-mixed-workspace-py", + SdistGenerator::Cargo, + expect![[r#" + { + "pyo3_mixed_workspace-2.1.3/PKG-INFO", + "pyo3_mixed_workspace-2.1.3/pyproject.toml", + "pyo3_mixed_workspace-2.1.3/rust/Cargo.lock", + "pyo3_mixed_workspace-2.1.3/rust/Cargo.toml", + "pyo3_mixed_workspace-2.1.3/rust/pyo3-mixed-workspace/Cargo.toml", + "pyo3_mixed_workspace-2.1.3/rust/pyo3-mixed-workspace/src/lib.rs", + "pyo3_mixed_workspace-2.1.3/rust/python/pyo3-mixed-workspace-py/Cargo.toml", + "pyo3_mixed_workspace-2.1.3/rust/python/pyo3-mixed-workspace-py/src/lib.rs", + "pyo3_mixed_workspace-2.1.3/src/pyo3_mixed_workspace/__init__.py", + "pyo3_mixed_workspace-2.1.3/src/pyo3_mixed_workspace/python_module/__init__.py", + "pyo3_mixed_workspace-2.1.3/src/pyo3_mixed_workspace/python_module/double.py", + "pyo3_mixed_workspace-2.1.3/src/tests/test_pyo3_mixed.py", + } + "#]], + Some(( + Path::new("pyo3_mixed_workspace-2.1.3/rust/Cargo.toml"), + cargo_toml, + )), + "sdist-workspace-members-beneath_pyproject", + )) +} + #[test] fn workspace_members_non_local_dep_sdist() { let cargo_toml = expect![[r#"