Skip to content

fix: ImageConstantsMixin factories silently downcast explicit dtype requests - #88

Open
petercorke wants to merge 1 commit into
fix/infer-dtype-alias-mismatchfrom
fix/image-constants-dtype-downcast
Open

fix: ImageConstantsMixin factories silently downcast explicit dtype requests#88
petercorke wants to merge 1 commit into
fix/infer-dtype-alias-mismatchfrom
fix/image-constants-dtype-downcast

Conversation

@petercorke

Copy link
Copy Markdown
Owner

Summary

Stacked on #86 (needs DTYPE_ALIASES). A third, distinct dtype bug found while auditing every dtype-resolving entry point (see #86, #87):

Image.Zeros()/.Constant()/.Random()/.Squares()/.Circles()/.Ramp()/.Sin()/.Chequerboard()/.Polygons() all build their raw pixel array with the caller's dtype, but never forward dtype= to the final Image(...) constructor call. Since dtype=None triggers the constructor's own auto-detect ("no dtype given -> any floating input becomes float32"), even a fully-correct, explicit dtype='float64' request was silently downcast to float32 -- Image.Zeros(size=5, dtype='float64').dtype was float32.

Two fixes:

  • _resolve_pattern_options() (shared by all 9 factories above) now resolves DTYPE_ALIASES itself, uniformly regardless of whether dtype came from the caller's own argument or a default_dtype/like.dtype fallback -- Constant()'s default_dtype='float' for float values needed this too, not just the explicit-argument path.
  • Each factory's final constructor call now passes dtype=True ("trust the array I already built, don't second-guess it") instead of omitting dtype= entirely. Squares/Circles/Ramp/Sin/Chequerboard/Polygons share a _pattern_image() helper -- fixed once there rather than at each of the 6 call sites.

String() was already fine -- it forwards **kwargs straight to the (already-fixed) constructor rather than handling dtype itself.

Test plan

  • Extended tests/test_dtype_resolution.py with a factory x dtype matrix (10 factories x 8 dtype cases = 80 new cases) rather than one-off tests per factory
  • Verified against pre-fix code: 45 of the 80 fail (the cases where a factory's own default dtype doesn't coincidentally already match the auto-detect outcome); all pass with the fix
  • Full tests/test_image_constants.py + tests/test_dtype_resolution.py + tests/test_image_core.py suites pass (189 passed)

…equests

A third, distinct dtype bug from the constructor/convert() alias
mismatch this branch is based on: Image.Zeros()/.Constant()/.Random()/
.Squares()/.Circles()/.Ramp()/.Sin()/.Chequerboard()/.Polygons() all
build their raw pixel array with the caller's dtype, but never forward
dtype= to the final Image(...) constructor call. Since dtype=None
triggers the constructor's own auto-detect ("no dtype given -> any
floating input becomes float32"), even a fully-correct, explicit
dtype='float64' request was silently downcast to float32 --
Image.Zeros(size=5, dtype='float64').dtype was float32.

Two fixes:
- _resolve_pattern_options() (shared by all 9 factories above) now
  resolves DTYPE_ALIASES itself, uniformly regardless of whether dtype
  came from the caller's own argument or a default_dtype/like.dtype
  fallback -- Constant()'s default_dtype='float' for float values
  needed this too, not just the explicit-argument path.
- Each factory's final constructor call now passes dtype=True ("trust
  the array I already built, don't second-guess it") instead of
  omitting dtype= entirely. Squares/Circles/Ramp/Sin/Chequerboard/
  Polygons share a _pattern_image() helper -- fixed once there rather
  than at each of the 6 call sites.

String() was already fine -- it forwards **kwargs straight to the
(already-fixed) constructor rather than handling dtype itself.

Extended tests/test_dtype_resolution.py with a factory x dtype matrix
(10 factories x 8 dtype cases = 80 new cases) rather than one-off
tests per factory. Verified against pre-fix code: 45 of the 80 fail
(the cases where a factory's own default dtype doesn't coincidentally
already match the auto-detect outcome), all pass with the fix.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 complexity · 0 duplication

Metric Results
Complexity 0
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

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.

1 participant