rasterize: reject partial width/height overrides instead of silent ignore#2579
Merged
Conversation
…nore (#2569) When only one of ``width`` / ``height`` was passed alongside ``like=``, the resolver fell through to the ``like`` branch and dropped the explicit dimension without warning. The docstring promised that ``like`` values "can still be overridden explicitly", so this was a silent contract violation. Raise ``ValueError`` naming which dimension was missing. Deriving the missing dimension from aspect/resolution was rejected because the bounds still come from ``like``, so the x and y pixel resolutions would diverge and the output coords would no longer match the template. Also update the ``width``, ``height``, and ``like`` docstring entries to spell out the both-or-neither contract.
brendancol
commented
May 28, 2026
Contributor
Author
brendancol
left a comment
There was a problem hiding this comment.
PR Review: rasterize: reject partial width/height overrides instead of silent ignore
Blockers
None.
Suggestions
None.
Nits (optional)
xrspatial/rasterize.py:3214-3228: the partial-dims check runs after_parse_inputand the inferred-bounds computation. A caller passing onlywidthwith a large geometry set pays the bbox-inference cost before the error fires. Moving the check up to right after argument unpacking would fail faster on the unhappy path. Strictly cosmetic; the practical impact is small.xrspatial/rasterize.py:3228: the error message ends with "use resolution or like to size the output". Resolution alone still needsbounds(explicit or inferable from geometries), so the phrasing slightly oversells what resolution covers. Something like "pass both width and height together, or omit both and supply resolution or like" would avoid the implication.
What looks good
(width is None) != (height is None)is the clean XOR form and reads well.- The error message names the missing dimension, which is exactly what the issue asked for.
- Tests cover all four cases from the issue (both / only-width / only-height / neither) plus a no-
likevariant that catches a related silent fall-through. - Docstring updates on
width,height, andlikekeep the documented contract aligned with the runtime check. - Full
test_rasterize.pystill passes (215 passed, 2 skipped). No regression.
Checklist
- Algorithm matches reference/paper (N/A, argument validation only)
- All backends behave consistently (check runs before backend dispatch)
- NaN handling correct (N/A)
- Edge cases covered by tests
- Dask chunk boundaries handled correctly (N/A)
- No premature materialization
- Benchmark exists or not needed (validation-only)
- README feature matrix (no change required)
- Docstrings present and accurate
#2569) - Move the (width is None) != (height is None) check to right after merge validation, before _extract_grid_from_like and _parse_input. The check has no dependency on geometries or the template, so the earlier placement surfaces the contract violation without paying the bbox-inference cost on the unhappy path. - Reword the error message to "pass both width and height together, or omit both and supply resolution or like" so it no longer implies resolution alone is sufficient (resolution still needs bounds).
brendancol
commented
May 28, 2026
Contributor
Author
brendancol
left a comment
There was a problem hiding this comment.
Follow-up review (after ce0acc1)
Both nits from the previous review have been addressed:
- The partial-dims check now sits right after merge validation, before
_extract_grid_from_likeand_parse_input. The error fires before any geometry or template work, so a caller passing onlywidthno longer pays the bbox-inference cost. - The error message now reads "pass both width and height together, or omit both and supply resolution or like to size the output", so the phrasing no longer suggests resolution alone is sufficient.
Status
- Blockers: none
- Suggestions: none
- Nits: none
Tests still green (221 passed, 2 skipped). Ready from the review side.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2569.
Summary
rasterize(..., like=template, width=W)used to silently dropwidthand return the template's size. Now it raisesValueErrornaming the missing dimension.like: passing only one ofwidth/height(with or withoutresolution) now raises with a clear message instead of falling through to the next branch.Why ValueError rather than deriving the missing dim
When
likeis given, the bounds also come from the template. Filling in the missing dimension from aspect/resolution would force the x and y pixel sizes to disagree, and the output coords would no longer matchlike. A loud error is the less surprising behaviour.Backend coverage
This is in the front-end argument resolver, before any backend dispatch. Same behaviour for numpy / cupy / dask+numpy / dask+cupy.
Test plan
like+ bothwidthandheighthonored (size matches the explicit args)like+ onlywidthraises with "height was not"like+ onlyheightraises with "width was not"like+ neither uses the template grid bit-exactlylike: only-width-plus-resolution raiseslike: only-height raisesxrspatial/tests/test_rasterize.pystill passes (215 passed, 2 skipped)