Unnecessary restrictions on project layout due to bad heuristic
Maturin seems to make incorrect assumptions about the project layout that restricts the kinds of wheels you can build with it. For example, when building mixed Rust/Python projects with `python-source` and `module-name` set, maturin assumes that the path pointed to by `module-name` is an existing Python module if: it either contains an `__init__.py` file or **does _not_ contain a `Cargo.toml` file**.
This comes from the following excerpt in [Maturin's source code](https://github.com/PyO3/maturin/blob/120e2e588a92c67dd451a2042006818a8160f01a/src/project_layout.rs#L429):
```rust
let python_module = if !python_module.join("__init__.py").is_file()
&& python_module.join("Cargo.toml").is_file()
{
debug!("No __init__.py file found in {}", python_module.display());
None
} else {
Some(python_module)
};
```
This prevents you having multiple top-level modules, e.g.:
```
module/
python_code.py
_module.cp312-win_amd64.pyd
```
compiled from:
```
rust/
lib.rs
src/
module/
python_code.py
Cargo.toml
pyproject.toml
```
This layout cannot be achieved by setting:
```toml
[tool.maturin]
python-source = "src"
module-name = "_module"
```
since maturin looks for `src/_module`, sees that `src/_module/Cargo.toml` doesn't exist, and determines that it must therefore be a Python module, yielding the following error when running `maturin develop`:
```
💥 maturin failed
Caused by: python-source is set to `...\python\src`, but the python module at
`...\python\src\_module` does not exist. Either create the Python module or remove the `python-source` setting from
pyproject.toml.
```
Fundamentally: **Maturin's code seems to assume that a mixed Rust/Python project consists of *one* Python module that contains the Rust extension module**. However, this assumption is not correct: Python distributions can contain arbitrarily many top-level modules and there's no reason to require that the Rust extension module is inside the main Python module.
## Feature Request
Maturin should not make unnecessary assumptions about project layout. Python distributions can contain arbitrarily many top-level modules - some may be plain Python code, some may be compiled extension modules, and others may be directories that contain both. Maturin's goal should basically be to copy the Python source tree into the wheel (subject to filtering), and insert the compiled extension module at the desired place implied by `module-name`, which may be at the root of the distribution.
1 条评论