ITADN

`RUST_LOG` influences returned directory in `prepare_metadata_for_build_wheel`

#3141ClosedThyre 创建于 2026-04-17
T
Thyrecommented
### Bug Description We are investigating build failures in our software stack we're currently building up. After installing Rust v1.94.1 and maturin v1.13.1, we tried to build a Python package (tibs) with our standard install procedure: ``` $ python -m pip install --prefix=[...]/software/tibs/0.6.0-GCCcore-15.2.0 --no-deps --ignore-installed --no-index --no-build-isolation . ``` In earlier `maturin` versions, this worked perfectly fine. However, with version v1.13.0 and later, we're getting the following build failure from `pip`: <details> <summary>Click to open</summary> ``` ERROR: Exception: Traceback (most recent call last): File "/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/lib/python3.14/site-packages/pip/_internal/cli/base_command.py", line 107, in _run_wrapper status = _inner_run() File "/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/lib/python3.14/site-packages/pip/_internal/cli/base_command.py", line 98, in _inner_run return self.run(options, args) ~~~~~~~~^^^^^^^^^^^^^^^ File "/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/lib/python3.14/site-packages/pip/_internal/cli/req_command.py", line 85, in wrapper return func(self, options, args) File "/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/lib/python3.14/site-packages/pip/_internal/commands/install.py", line 389, in run requirement_set = resolver.resolve( reqs, check_supported_wheels=not options.target_dir ) File "/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/lib/python3.14/site-packages/pip/_internal/resolution/resolvelib/resolver.py", line 79, in resolve collected = self.factory.collect_root_requirements(root_reqs) File "/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/lib/python3.14/site-packages/pip/_internal/resolution/resolvelib/factory.py", line 538, in collect_root_requirements reqs = list( self._make_requirements_from_install_req( ...<2 lines>... ) ) File "/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/lib/python3.14/site-packages/pip/_internal/resolution/resolvelib/factory.py", line 494, in _make_requirements_from_install_req cand = self._make_base_candidate_from_link( ireq.link, ...<2 lines>... version=None, ) File "/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/lib/python3.14/site-packages/pip/_internal/resolution/resolvelib/factory.py", line 226, in _make_base_candidate_from_link self._link_candidate_cache[link] = LinkCandidate( ~~~~~~~~~~~~~^ link, ^^^^^ ...<3 lines>... version=version, ^^^^^^^^^^^^^^^^ ) ^ File "/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/lib/python3.14/site-packages/pip/_internal/resolution/resolvelib/candidates.py", line 318, in __init__ super().__init__( ~~~~~~~~~~~~~~~~^ link=link, ^^^^^^^^^^ ...<4 lines>... version=version, ^^^^^^^^^^^^^^^^ ) ^ File "/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/lib/python3.14/site-packages/pip/_internal/resolution/resolvelib/candidates.py", line 161, in __init__ self.dist = self._prepare() ~~~~~~~~~~~~~^^ File "/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/lib/python3.14/site-packages/pip/_internal/resolution/resolvelib/candidates.py", line 238, in _prepare dist = self._prepare_distribution() File "/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/lib/python3.14/site-packages/pip/_internal/resolution/resolvelib/candidates.py", line 329, in _prepare_distribution return preparer.prepare_linked_requirement(self._ireq, parallel_builds=True) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/lib/python3.14/site-packages/pip/_internal/operations/prepare.py", line 543, in prepare_linked_requirement return self._prepare_linked_requirement(req, parallel_builds) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^ File "/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/lib/python3.14/site-packages/pip/_internal/operations/prepare.py", line 658, in _prepare_linked_requirement dist = _get_prepared_distribution( req, ...<3 lines>... self.check_build_deps, ) File "/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/lib/python3.14/site-packages/pip/_internal/operations/prepare.py", line 77, in _get_prepared_distribution abstract_dist.prepare_distribution_metadata( ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ build_env_installer, build_isolation, check_build_deps ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ) ^ File "/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/lib/python3.14/site-packages/pip/_internal/distributions/sdist.py", line 71, in prepare_distribution_metadata self.req.prepare_metadata() ~~~~~~~~~~~~~~~~~~~~~~~~~^^ File "/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/lib/python3.14/site-packages/pip/_internal/req/req_install.py", line 538, in prepare_metadata self._set_requirement() ~~~~~~~~~~~~~~~~~~~~~^^ File "/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/lib/python3.14/site-packages/pip/_internal/req/req_install.py", line 373, in _set_requirement if isinstance(parse_version(self.metadata["Version"]), Version): ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/lib/python3.14/site-packages/pip/_vendor/packaging/version.py", line 56, in parse return Version(version) File "/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/lib/python3.14/site-packages/pip/_vendor/packaging/version.py", line 200, in __init__ match = self._regex.search(version) TypeError: expected string or bytes-like object, got 'NoneType' ``` </details> After digging a bit deeper, I suspect that the following things happen: 1. `pip` calls into `generate_metadata -> prepare_metadata -> prepare_metadata_for_build_wheel`. This leads to [`prepare_metadata_for_build_wheel`](https://github.com/PyO3/maturin/blob/2582ab3763cf7b9d4b9dce25bc4c4299f074d914/maturin/__init__.py#L190) in `maturin`. 2. `maturin` calls `maturin pep517 write-dist-info --metadata-directory [...] --interpreter [...]` 3. `maturin` returns the _last_ line of the output, _not_ containing the expected output Checking `self.metadata_directory` in `pip` via some `print` debugging after `maturin` has finished (i.e. adding a print [here](https://github.com/pypa/pip/blob/2cb24160e92ba9e99b52fbc817c2500ec88da81a/src/pip/_internal/req/req_install.py#L530), I saw: ``` /tmp/eb-2gkjwrv2/pip-modern-metadata-8_54kgcy/2026-04-16T15:07:48.084403Z INFO pep517: maturin::commands::pep517: close time.busy=367ms time.idle=11.3µs ``` Here, we can see some `INFO` output instead of the directory name. Running `maturin pep517 write-dist-info --metadata-directory [...] --interpreter [...]` manually verifies that this is indeed the last line: ``` eb-shell> maturin pep517 write-dist-info --metadata-directory /tmp/eb-37jjd3ve/pip-modern-metadata-9rw9krgm --interpreter /p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/bin/python 2026-04-17T07:37:16.252630Z INFO pep517:into_build_context: maturin::build_options: close time.busy=1.44µs time.idle=810ns 2026-04-17T07:37:16.252805Z DEBUG pep517:build: maturin::project_layout: Found pyproject.toml in working directory at "/dev/shm/reuter1/easybuild/build/tibs/0.6.0/GCCcore-15.2.0/tibs-0.6.0/pyproject.toml" 2026-04-17T07:37:16.253378Z DEBUG pep517:build: maturin::project_layout: Using cargo manifest path from working directory: "/dev/shm/reuter1/easybuild/build/tibs/0.6.0/GCCcore-15.2.0/tibs-0.6.0/Cargo.toml" 2026-04-17T07:37:16.253585Z DEBUG pep517:build:resolve_cargo_metadata: maturin::project_layout: Resolving cargo metadata from "/dev/shm/reuter1/easybuild/build/tibs/0.6.0/GCCcore-15.2.0/tibs-0.6.0/Cargo.toml" 2026-04-17T07:37:16.318621Z INFO pep517:build:resolve_cargo_metadata: maturin::project_layout: close time.busy=65.0ms time.idle=3.50µs 📦 Including license file `LICENSE` 2026-04-17T07:37:16.319311Z DEBUG pep517:build: maturin::project_layout: Project layout resolved project_root=/dev/shm/reuter1/easybuild/build/tibs/0.6.0/GCCcore-15.2.0/tibs-0.6.0 python_dir=/dev/shm/reuter1/easybuild/build/tibs/0.6.0/GCCcore-15.2.0/tibs-0.6.0 rust_module=/dev/shm/reuter1/easybuild/build/tibs/0.6.0/GCCcore-15.2.0/tibs-0.6.0/tibs python_module=Some("/dev/shm/reuter1/easybuild/build/tibs/0.6.0/GCCcore-15.2.0/tibs-0.6.0/tibs") extension_name=tibs module_name=tibs 🔗 Found pyo3 bindings with abi3 support 2026-04-17T07:37:16.319501Z DEBUG pep517:build: maturin::build_context::builder: Resolved bridge model: PyO3(PyO3 { crate_name: pyo3, version: Version { major: 0, minor: 28, patch: 2 }, stable_abi: Some(StableAbi { kind: Abi3, version: Version(3, 8) }), metadata: Some(PyO3Metadata { cpython: PyO3VersionMetadata { min_minor: 7, max_minor: 15 }, pypy: PyO3VersionMetadata { min_minor: 11, max_minor: 11 } }) }) 2026-04-17T07:37:16.479623Z DEBUG pep517:build:check_executable: maturin::python_interpreter::discovery: Found CPython interpreter at /p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/bin/python executable=/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/bin/python 2026-04-17T07:37:16.479676Z INFO pep517:build:check_executable: maturin::python_interpreter::discovery: close time.busy=51.0ms time.idle=2.62µs executable=/p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/bin/python 🐍 Found CPython 3.14 at /p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/bin/python 📡 Using build options features from pyproject.toml 2026-04-17T07:37:16.479796Z INFO pep517:build: maturin::build_context::builder: close time.busy=227ms time.idle=4.22µs 2026-04-17T07:37:16.482808Z DEBUG pep517: maturin::module_writer::virtual_writer: Tracked entry "tibs-0.6.0.dist-info/METADATA" 2026-04-17T07:37:16.482840Z DEBUG pep517: maturin::module_writer::virtual_writer: Tracked entry "tibs-0.6.0.dist-info/WHEEL" 2026-04-17T07:37:16.482851Z DEBUG pep517: maturin::module_writer::virtual_writer: Tracked entry "tibs-0.6.0.dist-info/licenses/LICENSE" tibs-0.6.0.dist-info 2026-04-17T07:37:16.483749Z INFO pep517: maturin::commands::pep517: close time.busy=231ms time.idle=13.0µs ``` Some more debugging and searching later, it looks like this boils down to `RUST_LOG=debug` being set in our environment. Changing this to e.g. `RUST_LOG=warn` is sufficient enough to fix the issues we've seen. ``` eb-shell> RUST_LOG=warn maturin pep517 write-dist-info --metadata-directory /tmp/eb-37jjd3ve/pip-modern-metadata-9rw9krgm --interpreter /p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/bin/python 📦 Including license file `LICENSE` 🔗 Found pyo3 bindings with abi3 support 🐍 Found CPython 3.14 at /p/project1/cswmanage/reuter1/EasyBuild/apps/software/Python/3.14.2-GCCcore-15.2.0/bin/python 📡 Using build options features from pyproject.toml tibs-0.6.0.dist-info ``` ---- `maturin` should probably handle the case where an environment might set `RUST_LOG=[...]`, especially as the output is being parsed in `prepare_metadata_for_build_wheel`. Options might include to override / unset `RUST_LOG` for this particular call only, or to add a more robust handling for the returned directory name. ### Your maturin version (`maturin --version`) 1.13.0, 1.13.1 ### Your Python version (`python -V`) 3.14.2 ### Your pip version (`pip -V`) 25.3 ### What bindings you're using None ### 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 `/`)? - [ ] Yes The issues were encountered on different Linux systems (Arch Linux, Rocky Linux 9, RHEL, ...) ### Steps to Reproduce 1. Install `maturin` in a virtual environment: ```console $ python3 -m venv venv $ source venv/bin/activate $ pip install maturin==1.13.1 ``` 2. Try to install a package with `RUST_LOG=debug` set: ```console $ RUST_LOG=debug pip install --no-deps --ignore-installed --no-index --no-build-isolation https://github.com/scott-griffiths/tibs/archive/refs/tags/v0.6.0.tar.gz ``` This should yield the same error reported above: ``` File "/home/jreuter/venv/lib/python3.14/site-packages/pip/_internal/distributions/sdist.py", line 71, in prepare_distribution_metadata self.req.prepare_metadata() ~~~~~~~~~~~~~~~~~~~~~~~~~^^ File "/home/jreuter/venv/lib/python3.14/site-packages/pip/_internal/req/req_install.py", line 538, in prepare_metadata self._set_requirement() ~~~~~~~~~~~~~~~~~~~~~^^ File "/home/jreuter/venv/lib/python3.14/site-packages/pip/_internal/req/req_install.py", line 373, in _set_requirement if isinstance(parse_version(self.metadata["Version"]), Version): ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/jreuter/venv/lib/python3.14/site-packages/pip/_vendor/packaging/version.py", line 103, in parse return Version(version) File "/home/jreuter/venv/lib/python3.14/site-packages/pip/_vendor/packaging/version.py", line 359, in __init__ match = self._regex.fullmatch(version) TypeError: expected string or bytes-like object, got 'NoneType' ```
关闭于 2026-04-17 1 条评论