Skip to content

Fix BodyPartReader.read() returning bytearray instead of bytes#12671

Open
jesustorres-code wants to merge 1 commit into
aio-libs:masterfrom
jesustorres-code:fix/body-part-reader-returns-bytes
Open

Fix BodyPartReader.read() returning bytearray instead of bytes#12671
jesustorres-code wants to merge 1 commit into
aio-libs:masterfrom
jesustorres-code:fix/body-part-reader-returns-bytes

Conversation

@jesustorres-code
Copy link
Copy Markdown

Fixes #12404

Problem

BodyPartReader.read() accumulates data in a bytearray internally and returns it directly, violating the -> bytes return type annotation. With decode=True the decoded accumulation buffer also returns as bytearray.

This causes downstream failures like TypeError: Object of type bytearray is not JSON serializable when the result is passed to json.dumps, and silently breaks code that checks isinstance(result, bytes).

Fix

Convert the internal bytearray to bytes at the return point in both code paths:

# before
return decoded_data  # bytearray
return data          # bytearray

# after
return bytes(decoded_data)
return bytes(data)

The bytearray is still used internally for efficient .extend() accumulation; only the final return value changes.

Tests

  • Added assert type(result) is bytes to the existing test_read test
  • Added test_read_returns_bytes_not_bytearray_with_decode covering the decode=True path with Content-Encoding: identity

The read() method accumulated data in a bytearray internally but returned
it without converting to bytes, violating the return type annotation and
breaking downstream code that relies on bytes (e.g. json.dumps serialization).

Both code paths (decode=True and the plain path) now return bytes().

Fixes aio-libs#12404
@codecov
Copy link
Copy Markdown

codecov Bot commented May 21, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.56%. Comparing base (a0a03ca) to head (0fa69e9).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #12671      +/-   ##
==========================================
- Coverage   98.95%   98.56%   -0.39%     
==========================================
  Files         131      131              
  Lines       46688    46696       +8     
  Branches     2421     2421              
==========================================
- Hits        46200    46026     -174     
- Misses        366      526     +160     
- Partials      122      144      +22     
Flag Coverage Δ
Autobahn 22.41% <10.00%> (-0.01%) ⬇️
CI-GHA 98.01% <100.00%> (-0.91%) ⬇️
OS-Linux 97.69% <100.00%> (-0.99%) ⬇️
OS-Windows ?
OS-macOS 97.93% <100.00%> (-0.01%) ⬇️
Py-3.10 97.20% <100.00%> (-0.96%) ⬇️
Py-3.11 97.44% <100.00%> (-0.97%) ⬇️
Py-3.12 97.53% <100.00%> (-0.97%) ⬇️
Py-3.13 97.61% <100.00%> (-0.87%) ⬇️
Py-3.14 97.63% <100.00%> (-0.87%) ⬇️
Py-3.14t ?
Py-pypy-3.11 ?
VM-macos 97.93% <100.00%> (-0.01%) ⬇️
VM-ubuntu 97.69% <100.00%> (-0.99%) ⬇️
VM-windows ?
cython-coverage 37.93% <20.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 21, 2026

Merging this PR will not alter performance

✅ 72 untouched benchmarks
⏩ 72 skipped benchmarks1


Comparing jesustorres-code:fix/body-part-reader-returns-bytes (0fa69e9) with master (a0a03ca)

Open in CodSpeed

Footnotes

  1. 72 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: BodyPartReader.filename and read() leak bytearray instead of str/bytes, violating API contract and breaking JSON serialization

1 participant