Type-check compression_level in to_geotiff#3324
Merged
Merged
Conversation
brendancol
commented
Jun 14, 2026
brendancol
left a comment
Contributor
Author
There was a problem hiding this comment.
PR Review: Type-check compression_level in to_geotiff
Blockers
None.
Suggestions
None.
Nits
_validation.py/eager.py: the new_validate_compression_level_argis wired intoto_geotiffonly. The second range check in_write_vrt_tiled(eager.py ~1273) and the GPU writer's own range check (gpu.py ~395) still have no type guard. Both are internal and only reachable throughto_geotiff, which now validates first, so there is no live bug here. A one-line comment at those two sites noting the type guard runs upstream would save a future direct caller some confusion. Not blocking.
What looks good
- The new helper matches
_validate_overview_level_arg: same None passthrough, same(int, np.integer)plusnot boolcheck, same TypeError message shape. Reads cleanly against the existing precedent. - Placement is right. It runs after compression-name validation (so
compressionis already a known-good string) and before the range check and backend dispatch, so one path covers numpy, cupy, and dask. - Tests cover bool, str, list, float, and an arbitrary object, plus the no-level-range codec (lzw), a valid int that still writes, and an out-of-range int that still raises ValueError. Temp files carry the issue number.
- Keeping the silent-ignore behavior for well-typed-but-inapplicable ints (rather than rejecting them the way max_z_error does) is the minimal change and matches the rest of the module. The PR body says so.
Checklist
- Algorithm matches reference: n/a (input validation)
- Backends consistent: yes, single pre-dispatch path
- NaN handling: n/a
- Edge cases covered: yes
- Dask boundaries: n/a
- No premature materialization: n/a
- Benchmark: not needed
- README matrix: n/a (no new function)
- Docstrings present and accurate: yes
brendancol
commented
Jun 14, 2026
brendancol
left a comment
Contributor
Author
There was a problem hiding this comment.
PR Review (follow-up pass)
The one nit from the first pass is addressed: the internal range checks in _write_vrt_tiled (eager.py) and _write_geotiff_gpu (gpu.py) now carry a one-line note that to_geotiff rejects non-int / bool compression_level upstream (#3321), so those comparisons are type-safe on the normal dispatch path.
No new findings. Comment-only changes since the last pass; the write + codec-roundtrip suites still pass.
Blockers
None.
Suggestions
None.
Nits
None remaining.
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 #3321
to_geotiffdocumentscompression_levelasint | None, but thevalidation only did a range comparison. That left three holes:
compression_level=Truewas accepted as level 1 (boolis an int subclass).TypeErrorfrom thelo <= compression_level <= hicomparison instead of a clear message._LEVEL_RANGESentry (e.g. lzw) skipped the check, so junk passed through and was ignored.This adds
_validate_compression_level_argin_validation.py, mirroringthe existing
_validate_overview_level_argguard, and calls it into_geotiffbefore the range check. It rejectsbooland any non-intwith a
TypeErrorthat names the parameter, for every codec. Valid intskeep the existing out-of-range
ValueErrorbehavior. Well-typed ints forcodecs without a level range are still silently ignored, matching how the
rest of the module treats inapplicable-but-well-typed params.
Backend coverage: the guard runs in
to_geotiffbefore backend dispatch,so it covers numpy, cupy, dask+numpy, and dask+cupy through one path.
Test plan:
compression_level=TrueraisesTypeError'9',[9],9.0,object()raiseTypeErrorValueError