Replace broken upload attributes with new ones - #13427
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #13427 +/- ##
==========================================
- Coverage 99.00% 98.98% -0.02%
==========================================
Files 132 132
Lines 49531 49996 +465
Branches 2571 2593 +22
==========================================
+ Hits 49036 49490 +454
- Misses 371 381 +10
- Partials 124 125 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. |
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains. Reviews (12): Last reviewed commit: "Coverage" | Re-trigger Greptile |
Merging this PR will not alter performance
Comparing Footnotes
|
PR Review — Replace broken upload attributes with new onesRight call on the API replacement, and the implementation is clean — one gap in the abort path keeps it from being merge-ready. Moving progress tracking from
What needs attention:
🟡 Important
1. `upload_complete` never settles when the request fails before the body write starts
|
|
The review is thorough and the findings are accurate. Having read the diff: The abort path gap is the real blocker. The else:
await writer.write_eof()
body._finish_upload() # ← no track_progress guard
protocol.start_timeout()
def _mark_body_sent(self) -> None:
if (body := self._body) is not self._EMPTY_BODY:
body._finish_upload()The fix is a one-liner — wrap with
One additional note not called out above: In summary: address the abort path (🟡) and the |
|
The review is accurate. Here's confirmation against the diff for the two most actionable gaps: Critical issue is real. Suggestion #1 is also valid. In the else:
await writer.write_eof()
body._finish_upload() # no track_progress guard
protocol.start_timeout()
One nuance the review understates: The priority ordering is right: fix the pending-forever future first (it makes the documented API unreliable under the most common error condition), then the singleton mutation. The remaining suggestions are genuine polish but not blockers. |
| finally: | ||
| post_task.cancel() | ||
| with suppress(asyncio.CancelledError): | ||
| await post_task |
| finally: | ||
| slow_task.cancel() | ||
| with suppress(asyncio.CancelledError): | ||
| await slow_task |
| finally: | ||
| slow_task.cancel() | ||
| with suppress(asyncio.CancelledError): | ||
| await slow_task |
Co-authored-by: Sam Bull <aa6bs0@sambull.org>
| with pytest.raises(aiohttp.ClientError): | ||
| async with client.post("/", data=p): | ||
| assert False | ||
| assert p.upload_complete.done() |
| waiter.cancel() | ||
| slow_task.cancel() | ||
| with suppress(asyncio.CancelledError): | ||
| await slow_task |
| with pytest.raises(aiohttp.ClientError): | ||
| async with client.post("/", data=p): | ||
| assert False | ||
| assert p.upload_complete.done() |
Co-authored-by: Sam Bull <aa6bs0@sambull.org>
| raise exc_type("body source failed") | ||
|
|
||
| p = aiohttp.AsyncIterablePayload(failing_body()) | ||
| fut = p.upload_complete |
| raise exc_type("body source failed") | ||
|
|
||
| p = aiohttp.AsyncIterablePayload(failing_body()) | ||
| fut = p.upload_complete |
| await resp.read() | ||
| # Awaited first so an upload failure surfaces as the underlying | ||
| # ClientError rather than the cancellation of upload_complete. | ||
| await post_task |
| waiter.cancel() | ||
| slow_task.cancel() | ||
| with suppress(asyncio.CancelledError): | ||
| await slow_task |
| assert resp.upload_complete is fut | ||
|
|
||
| sampled.set() | ||
| await fut |
The upload progress attributes added recently fundamentally can't work as most servers won't send the headers in response to a request until they've read the entire body.
This replaces it with a new API.