Skip to content

Commit d411d67

Browse files
dimblebyCopilot
andcommitted
fix: retry upload after package registration instead of raising
After _register() succeeded, resp.raise_for_status() raised on the original 400 response, so the upload was never retried. Now retries the upload once after registration, with a guard against infinite recursion if the server keeps returning 400. Co-authored-by: Copilot <[email protected]>
1 parent 95cd84c commit d411d67

2 files changed

Lines changed: 35 additions & 1 deletion

File tree

src/poetry/publishing/uploader.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,8 @@ def _upload_file(
204204
file: Path,
205205
dry_run: bool = False,
206206
skip_existing: bool = False,
207+
*,
208+
registered: bool = False,
207209
) -> None:
208210
from cleo.ui.progress_bar import ProgressBar
209211

@@ -254,7 +256,16 @@ def _upload_file(
254256
"Is the URL missing a trailing slash?"
255257
)
256258
elif resp.status_code == 400 and "was ever registered" in resp.text:
257-
self._register(session, url)
259+
if not registered:
260+
self._register(session, url)
261+
return self._upload_file(
262+
session,
263+
url,
264+
file,
265+
dry_run,
266+
skip_existing,
267+
registered=True,
268+
)
258269
resp.raise_for_status()
259270
elif skip_existing and self._is_file_exists_error(resp):
260271
bar.set_format(

tests/publishing/test_uploader.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,29 @@ def test_uploader_registers_with_sdist_for_appropriate_400_errors(
225225
assert b"bdist_wheel" not in bodies[1]
226226

227227

228+
def test_uploader_retries_upload_after_register(
229+
http: responses.RequestsMock, uploader: Uploader
230+
) -> None:
231+
"""After registering a package, the upload must be retried.
232+
233+
The server returns 400 "was ever registered" on the first upload,
234+
then 200 on the registration and the retried upload.
235+
"""
236+
http.post("https://foo.com", status=400, body="No package was ever registered")
237+
http.post("https://foo.com", status=200) # register
238+
http.post("https://foo.com", status=200) # retry upload (first file)
239+
http.post("https://foo.com", status=200) # upload second file
240+
241+
uploader.upload("https://foo.com")
242+
243+
assert len(http.calls) == 4
244+
bodies = [c.request.body or b"" for c in http.calls]
245+
assert b'name=":action"\r\n\r\nfile_upload\r\n' in bodies[0]
246+
assert b'name=":action"\r\n\r\nsubmit\r\n' in bodies[1]
247+
assert b'name=":action"\r\n\r\nfile_upload\r\n' in bodies[2]
248+
assert b'name=":action"\r\n\r\nfile_upload\r\n' in bodies[3]
249+
250+
228251
def test_uploader_register_uses_wheel_if_no_sdist(
229252
http: responses.RequestsMock, poetry: Poetry, tmp_path: Path
230253
) -> None:

0 commit comments

Comments
 (0)