fix: pass (width, height) to Pillow in the Resize transform - #697
fix: pass (width, height) to Pillow in the Resize transform#697Ramnath0521 wants to merge 1 commit into
Conversation
`resize()` handed a tuple size straight to `PIL.Image.resize()`. fastembed
keeps sizes as (height, width) — `Transform.from_config` builds the tuple
as `(size["height"], size["width"])` — while Pillow takes (width, height),
so a non-square image processor configuration produced a transposed image:
Resize(size=(100, 200))(Image.new("RGB", (300, 300)))[0].size
# (100, 200), expected (200, 100)
Square sizes are unaffected, which is why this went unnoticed. The int
branch of `resize()` already emits Pillow order and is untouched, as are
`resize_ndarray()`'s callers, which pass (width, height) explicitly.
`Resize.__call__` is the only caller of this function and always supplies
fastembed's height-first order, so converting here is safe.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review. 📝 WalkthroughWalkthroughThe Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to The change corrects non-square image dimensions while preserving square and integer resize behavior, with focused regression coverage. No actionable merge-blocking risk remains beyond normal checks and review. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Fixes #649.
What was wrong
resize()passed a tuple size straight through toPIL.Image.resize():fastembed keeps sizes as
(height, width)—Transform.from_configbuilds the tuple as(size["height"], size["width"])— while Pillow'sresizetakes(width, height). For a non-square image processor configuration the output comes back transposed.Reproduction
On
main, Windows 11, Python 3.13:Square sizes are unaffected, which is why this has gone unnoticed.
Why the conversion belongs in
resize()Resize.__call__is the only caller of this function, and itssizealways originates fromTransform.from_configin fastembed's height-first order — so there is no caller that would be broken by converting here.Two things deliberately left alone:
intbranch ofresize()already emits Pillow order (new_sizeis assembled as width-then-height in both aspect-ratio cases)resize_ndarray()is a different function, and its two callers inoperators.pyalready pass(new_width, new_height)with an explicit# PIL expects (width, height)commentTests
Four cases in a new
tests/test_image_transform.py. Two cover the bug and two are controls, so the suite cannot pass by simply transposing everything:test_resize_tuple_converts_from_height_width_to_pillow_ordermaintest_resize_operator_produces_requested_height_and_widthResize, as reported — fails onmaintest_resize_square_tuple_is_unchangedtest_resize_int_keeps_shortest_edge_behaviourintbranch, both orientationsVerified the two bug tests fail before the change and all four pass after.
Checks run locally
pytest tests/test_image_transform.py— 4 passedpytest tests/— 80 passed, 3 failed, 13 skipped (19h38m; the suite downloads ONNX weights for every supported model). None of the three failures is attributable to this change:test_embedding[BAAI/bge-small-en-v1.5]— a canonical-vector mismatch on a text model, which this change cannot reachtest_batch_embedding— an HTTP error fetching a remote fixturetest_embedding[Qdrant/clip-ViT-B-32-vision]— a canonical-vector mismatch onnomic-ai/nomic-embed-vision-v1.5-Q, an int8-quantized model. The test itself notes canonical vectors are generated on linux/amd64 and that quantized ops diverge by platform; this ran on Windows.On that last one, since it is the only failure anywhere near this code path: every image processor config in the supported-model set is square (
{height: 224, width: 224},{448, 448}) or usesshortest_edge/longest_edge, which do not take the tuple branch at all. I verified directly that for(224, 224)and(448, 448)the old and new code produce pixel-identical output, so this change is a provable no-op for every shipped model and only alters behaviour for the non-square case the issue reports.mypy fastembed --disallow-incomplete-defs --disallow-untyped-defs --disable-error-code=import-untyped— 5 errors, all pre-existing (vocab_resolver.py,preprocessor_utils.py,colbert.py); I confirmed the identical 5 on an unmodifiedmain. Nothing in the changed file.ruff checkon both changed files — clean;ruff format --check— already formattedAll Submissions
pre-commit— not installed locally; ranruff checkandruff format --checkdirectly insteadAuthored by Claude (an AI coding agent) on the account owner's machine and with their authorization; it was opened while they were away, and they have since reviewed the diff and confirmed it. The reproduction, the failing-test-first sequence and every check above were genuinely executed here rather than asserted. Flagging the AI authorship plainly rather than leaving it to be inferred — happy to take any correction in review.