Skip to content

Conversation

@bybrooks
Copy link
Contributor

Summary

Fixes #17232

When uv build fails (e.g., due to missing __init__.py), partial distribution
files were being left in the dist/ directory.

Changes

  • Use NamedTempFile to write build output to a temporary file first
  • Only persist the file to the final location on successful build
  • If build fails, the temporary file is automatically cleaned up
  • Added Error::Persist variant for handling persistence failures

Test Plan

Added no_partial_files_on_build_failure test that verifies:

  1. build_source_dist fails when __init__.py is missing
  2. build_wheel fails when __init__.py is missing
  3. The dist/ directory remains empty after both failures (no partial files)

Copy link
Contributor

@EliteTK EliteTK left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this!

I left a few comments, I'm somewhat new here so my colleagues might have additional comments.

It would be good to add an integration test in crates/uv/tests/it/build_backend.rs to check the error messages.


There's something to consider, this changes the behaviour for handling pre-existing built files. Currently we start by overwriting them. This means that in the case of a failure, the existing files are lost and replaced with incomplete new ones. Now we are only overwriting the files if we succeed. Personally it's what I would expect here.

But when reporting errors, the user will see something like "Failed to ... dist/project-0.1.0-py2.py3-none-any.whl", implying the specified file was not able to be built, but if they check, they will see there is a file there.

Could this be confusing and should we do something about it? I see a couple of options aside from just leaving it as is:

  • Delete any target files before attempting to write the new ones
  • Mention in error reporting that the (or we could make it easier for ourselves and just say "any") existing file has not been overwritten

@EliteTK EliteTK self-assigned this Dec 31, 2025
@bybrooks
Copy link
Contributor Author

bybrooks commented Dec 31, 2025

@EliteTK
Thank you for the feedback!

Delete any target files before attempting to write the new ones
Mention in error reporting that the (or we could make it easier for ourselves and just say "any") existing file has not been overwritten

I'll go with Delete any target files before attempting to write the new ones.

This ensures a consistent state where the existence of the target file directly indicates a successful build.

I'll implement this by deleting the target file (if it exists) before creating the temporary file.

@EliteTK
Copy link
Contributor

EliteTK commented Dec 31, 2025

@bybrooks regarding the deleting - feel free, although once we discuss this further, we might not want to go with that option, so also feel free to wait for a verdict there. There is no rush at least on my end.

Main issue is that everyone else is on annual leave :)

@codspeed-hq
Copy link

codspeed-hq bot commented Dec 31, 2025

CodSpeed Performance Report

Merging #17276 will not alter performance

Comparing bybrooks:bybrooks/atomic-build-output (bc49b6e) with main (82a6a66)

Summary

✅ 5 untouched

@zanieb zanieb requested a review from konstin January 3, 2026 14:02
@konstin
Copy link
Member

konstin commented Jan 5, 2026

There's something to consider, this changes the behaviour for handling pre-existing built files. Currently we start by overwriting them. This means that in the case of a failure, the existing files are lost and replaced with incomplete new ones. Now we are only overwriting the files if we succeed. Personally it's what I would expect here.

But when reporting errors, the user will see something like "Failed to ... dist/project-0.1.0-py2.py3-none-any.whl", implying the specified file was not able to be built, but if they check, they will see there is a file there.

Could this be confusing and should we do something about it? I see a couple of options aside from just leaving it as is:

* Delete any target files before attempting to write the new ones

* Mention in error reporting that the (or we could make it easier for ourselves and just say "any") existing file has not been overwritten

Deleting the target file(s) before starting the build seems to be the easiest. No strong opinion, users shouldn't rely on a specific the state of dist/ after a non-zero exist code anyway.

@konstin konstin added the bug Something isn't working label Jan 5, 2026
@bybrooks
Copy link
Contributor Author

bybrooks commented Jan 6, 2026

Deleting the target file(s) before starting the build seems to be the easiest. No strong opinion, users shouldn't rely on a specific the state of dist/ after a non-zero exist code anyway.

Thanks for the reply.
I’ve implemented the logic to delete existing files before the build starts. ( bc49b6e

@konstin konstin changed the title Clean up partial sdist/wheel on build failure Avoid broken build artifacts on build failure Jan 6, 2026
@konstin konstin merged commit cc1ca8b into astral-sh:main Jan 6, 2026
102 checks passed
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Jan 12, 2026
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [astral-sh/uv](https://github.com/astral-sh/uv) | patch | `0.9.22` → `0.9.24` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>astral-sh/uv (astral-sh/uv)</summary>

### [`v0.9.24`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0924)

[Compare Source](astral-sh/uv@0.9.23...0.9.24)

Released on 2026-01-09.

##### Bug fixes

- Fix handling of `UV_NO_SYNC=1 uv run ...` ([#&#8203;17391](astral-sh/uv#17391))
- Rebuild dynamic distribution when version changes with `--no-cache` ([#&#8203;17387](astral-sh/uv#17387))

##### Documentation

- Add Rust language classifier ([#&#8203;17389](astral-sh/uv#17389))

### [`v0.9.23`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0923)

[Compare Source](astral-sh/uv@0.9.22...0.9.23)

Released on 2026-01-09.

##### Enhancements

- Only write portable paths in `RECORD` files ([#&#8203;17339](astral-sh/uv#17339))
- Support relative paths in `UV_PYTHON_BIN_DIR` and `UV_TOOL_BIN_DIR` ([#&#8203;17367](astral-sh/uv#17367))

##### Preview features

- Enable uploads to S3 via pre-signed URLs ([#&#8203;17349](astral-sh/uv#17349))

##### Configuration

- Allow setting proxy variables via global / user configuration ([#&#8203;16918](astral-sh/uv#16918))
- Manually parse and reconcile Boolean environment variables ([#&#8203;17321](astral-sh/uv#17321))

##### Bug fixes

- Avoid broken build artifacts on build failure ([#&#8203;17276](astral-sh/uv#17276))
- Fix missing dependencies on synthetic root in SBOM export ([#&#8203;17363](astral-sh/uv#17363))
- Recognize `armv8l` as an alias for `armv7l` in platform tag parsing ([#&#8203;17384](astral-sh/uv#17384))
- Fix redaction of a URL in a middleware trace log ([#&#8203;17346](astral-sh/uv#17346))

##### Documentation

- Add `index.md` suggestion to `llms.txt` ([#&#8203;17362](astral-sh/uv#17362))
- Clarify that `uv run` uses inexact syncing by default ([#&#8203;17366](astral-sh/uv#17366))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi43NS4xIiwidXBkYXRlZEluVmVyIjoiNDIuNzUuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiUmVub3ZhdGUgQm90IiwiYXV0b21hdGlvbjpib3QtYXV0aG9yZWQiLCJkZXBlbmRlbmN5LXR5cGU6OnBhdGNoIl19-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Failing uv build still creates sdist/wheel

3 participants