Skip to content

Add explicit error handling in _make_tiles.py#1130

Merged
timtreis merged 5 commits intomainfrom
fix/1086-make-tiles-error-handling
Mar 3, 2026
Merged

Add explicit error handling in _make_tiles.py#1130
timtreis merged 5 commits intomainfrom
fix/1086-make-tiles-error-handling

Conversation

@timtreis
Copy link
Member

Summary

  • Adds upfront parameter validation with clear KeyError/ValueError messages to make_tiles(), make_tiles_from_spots(), _get_largest_scale_dimensions(), and _get_spot_coordinates()
  • Validates that image/spots keys exist in sdata, tile_size has positive values, and min_tissue_fraction is in [0, 1]
  • Adds 5 test cases covering all new error conditions

Closes #1086

Test plan

  • test_make_tiles_invalid_image_key — bad image key raises KeyError
  • test_make_tiles_invalid_tile_size — non-positive tile size raises ValueError
  • test_make_tiles_invalid_min_tissue_fraction — out-of-range fraction raises ValueError
  • test_make_tiles_from_spots_invalid_spots_key — bad spots key raises KeyError
  • test_make_tiles_from_spots_invalid_image_key — bad image key raises KeyError

🤖 Generated with Claude Code

timtreis and others added 3 commits February 27, 2026 23:15
Add upfront parameter validation with clear error messages to
make_tiles(), make_tiles_from_spots(), and their helpers. Validates
image/spots keys exist, tile_size is positive, and min_tissue_fraction
is in [0, 1]. Adds 5 test cases for the new error conditions.

Closes #1086

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@timtreis timtreis marked this pull request as ready for review February 27, 2026 22:19
Comment on lines +173 to +174
if image_key not in sdata.images:
raise KeyError(f"Image key '{image_key}' not found in sdata.images. Available: {list(sdata.images.keys())}")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these can be one liners with a common check function. also easier to read

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer not to code-golf at the sake of readability. Generally I find the asser thing, text pattern ugly

Copy link
Member

@selmanozleyen selmanozleyen Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not just code golfing, it makes sense as a function itself. When the error message or access pattern changes you could change it from the function instead modifying it everywhere. Also I find it more readable this way. I can just skip reading those functions as they aren't part of the core algo. These kinds of trivial checks bloat the core function.

Idk something like this

def check_element_exists(
    sdata,
    key,
    element_type,
):
    store = getattr(sdata, element_type)
    if key not in store:
        available = list(store.keys())
        raise KeyError(
            f"Key {key!r} not found in sdata.{element_type}. "
            f"Available keys: {available}"
        )

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wondering if we should just let it error from spatialdata? Like the error message would be almost the same

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wondering if we should just let it error from spatialdata? Like the error message would be almost the same

I see the rational but dislike it in this case because sdata core has quite a few error messages that a biologist probably wouldn't intuitively understand and they also usually don't proactively offer help by f.e. giving the valid keys. There's also quite a few empty asserts which I find quite problematic.

When the error message or access pattern changes you could change it from the function instead modifying it everywhere. Also I find it more readable this way. I can just skip reading those functions as they aren't part of the core algo. These kinds of trivial checks bloat the core function.

I do see that point, but I think then it should be a separate PR where we do this across the entire codebase. wdyt?

Copy link
Member

@selmanozleyen selmanozleyen Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure it can be a separate PR but isn't this Pr already small. Why not start here?

Update: sorry was in the bus so the comment was incomplete bc of that

@selmanozleyen
Copy link
Member

but does this get rid of the try except block as written in the issue linked?

@codecov
Copy link

codecov bot commented Feb 27, 2026

Codecov Report

❌ Patch coverage is 6.66667% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.96%. Comparing base (95d8b18) to head (4c230be).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/squidpy/experimental/im/_make_tiles.py 6.66% 7 Missing and 7 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1130      +/-   ##
==========================================
- Coverage   73.10%   72.96%   -0.14%     
==========================================
  Files          38       38              
  Lines        6473     6484      +11     
  Branches     1144     1151       +7     
==========================================
- Hits         4732     4731       -1     
- Misses       1265     1270       +5     
- Partials      476      483       +7     
Files with missing lines Coverage Δ
src/squidpy/experimental/im/_make_tiles.py 67.56% <6.66%> (-2.12%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

get_transformation(element, get_all=True) cannot raise KeyError or
ValueError for valid SpatialData elements, and callers already
validate elements exist before calling this helper.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@timtreis
Copy link
Member Author

but does this get rid of the try except block as written in the issue linked?

True, we're validating beforehand, so the function should never crash and burn.

Copy link
Member

@selmanozleyen selmanozleyen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry but I stand by the comments I made earlier.

From the other codes I have read, I find these changes reasonable to expect.

For example see:
https://github.com/scverse/annbatch/blob/d47240f883f64b86524d6bc32731ce3e15be2984/src/annbatch/utils.py#L114

I don't think this is overengineering or anything I think it is a necessity

@timtreis
Copy link
Member Author

timtreis commented Mar 2, 2026

sorry but I stand by the comments I made earlier.

From the other codes I have read, I find these changes reasonable to expect.

For example see: https://github.com/scverse/annbatch/blob/d47240f883f64b86524d6bc32731ce3e15be2984/src/annbatch/utils.py#L114

I don't think this is overengineering or anything I think it is a necessity

I just think it's suboptimal to do one function here and then others in a separate PR. If we do something like that, it should be across the entire package. I can just do that in this PR and rename it, but I'd rather not sneak in such a major refactor under "added error handling"

@selmanozleyen
Copy link
Member

I just think it's suboptimal to do one function here and then others in a separate PR. If we do something like that, it should be across the entire package. I can just do that in this PR and rename it, but I'd rather not sneak in such a major refactor under "added error handling"

ok if you say so. I just feel like there are already lot's one can refactor we might as well start when we add new code but if you think you can do the PR then sure.

@timtreis
Copy link
Member Author

timtreis commented Mar 3, 2026

discussed: have separate PR for type checking refactor

@timtreis timtreis merged commit 240dcfe into main Mar 3, 2026
14 checks passed
@timtreis timtreis deleted the fix/1086-make-tiles-error-handling branch March 3, 2026 15:12
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.

Handle cases explicitly for KeyError or ValueError in _make_tiles

2 participants