maturin icon indicating copy to clipboard operation
maturin copied to clipboard

"Failed to write to mylib\_mylib.pyd" in multi-crate workspace

Open Tim-Evans-Seequent opened this issue 6 months ago • 0 comments

Bug Description

Maturin uses the .gitignore to ignore files from the wheel, and in a mixed rust/python wheel this is supposed to ignore the .pyd or .so that maturin develop copies into the source tree. This works for simple projects, but not for complex multi-crate workspaces, because it look for a .gitignore file in a sidirectory rather than the project root. See the reproduction steps for a complete explanation.

I think the best solution here would be for maturin build to always ignore whatever maturin develop creates, rather than relying on reading the config file for a different tool. The second best solution would be to check the workspace root for .gitignore and not just the crate directory.

A workaround is to create a second .gitignore in the Python bindings crate folder. Having that documented clearly, or suggested by Maturin when this failure occurs, would be the minimal fix.

Your maturin version (maturin --version)

1.8.7

Your Python version (python -V)

3.10.0

Your pip version (pip -V)

25.1.1

What bindings you're using

pyo3

Does cargo build work?

  • [x] Yes, it works

If on windows, have you checked that you aren't accidentally using unix path (those with the forward slash /)?

  • [x] Yes

Steps to Reproduce

Create a Rust workspace with two packages. The first, "foo" will contain the Rust code. The second "foo_python" will contain the Python bindings created with PyO3. The file structure should look like this:

foo/
    src/
        lib.rs
    Cargo.toml
foo_python/
    python/
        foo/
            __init__.py
            extras.py
    src/
        lib.rs
    Cargo.toml
    pyproject.toml
Cargo.toml
.gitignore

This is a pretty common setup for large projects. There might be several more crates as well, like proc-macros, sub-libraries, or bindings for other languages.

When you run cd foo_python && maturin develop the file foo_python/python/foo/_foo.pyd (or similar) will be created so local Python development is easy. You will also need to add that file to /.gitignore so it doesn't get checked in. So far, this all works. But when you then run cd foo_python && maturin build, it fails with this error:

💥 maturin failed
  Caused by: Failed to add the files to the wheel
  Caused by: Failed to write to gneiss\_gneiss.pyd
  Caused by: File foo\_foo.pyd was already added from D:\foo\foo_python\python\foo\_foo.pyd, can't added it from D:\foo\target\maturin\_foo.dll

This happens because Maturin is looking at D:/foo/foo_python/.gitignore (which does not exist) rather than D:\foo\.gitignore where the .pyd file is correctly ignored.

Tim-Evans-Seequent avatar Jun 22 '25 22:06 Tim-Evans-Seequent