Skip to content

feat: vips filters tests#43

Closed
JakubPekar wants to merge 2 commits intomainfrom
feature/vips-filters
Closed

feat: vips filters tests#43
JakubPekar wants to merge 2 commits intomainfrom
feature/vips-filters

Conversation

@JakubPekar
Copy link
Collaborator

@JakubPekar JakubPekar commented Mar 13, 2026

Summary by CodeRabbit

Release Notes

  • Refactor
    • Tissue mask filtering process updated with adjusted filter sequence.
    • Simplified tissue mask function return value structure.

@JakubPekar JakubPekar requested review from a team March 13, 2026 23:23
@gemini-code-assist
Copy link

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request refactors the tissue_mask function by embedding the default Vips filter directly into its function signature, eliminating a global variable. It also adjusts the order of morphological operations within the default filter and simplifies the function's return type, leading to a cleaner and more self-contained implementation.

Highlights

  • Refactoring: The default_filter global variable was removed, and its definition was moved directly into the tissue_mask function's signature as a default argument.
  • Filter Logic Adjustment: The order of morphological operations within the default Vips filter was changed, specifically swapping VipsOpening and VipsClosing.
  • Return Type Simplification: The tissue_mask function's return type was simplified from a tuple (pyvips.Image, Res) to just pyvips.Image, and the return statement was updated accordingly.
Changelog
  • ratiopath/masks/tissue_mask.py
    • Removed the default_filter global variable.
    • Modified the tissue_mask function signature to include the default filter directly.
    • Adjusted the return type and value of the tissue_mask function.
    • Swapped the order of VipsOpening and VipsClosing in the default filter.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link

coderabbitai bot commented Mar 13, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

The tissue_mask function has been refactored to return a single pyvips.Image instead of a tuple, with the module-level default_filter removed and inlined as a default parameter. The filter composition order is adjusted with Closing and Opening operations swapped.

Changes

Cohort / File(s) Summary
Tissue Mask Refactoring
ratiopath/masks/tissue_mask.py
Function signature simplified to return pyvips.Image instead of tuple; module-level default_filter removed and inlined in function signature with reordered filter chain (GrayScale, Otsu, Closing, Opening); return statement updated to extract first element only.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 A mask so neat, returns just one,
No tuples here, the refactor's done!
Closing meets Opening in perfect dance,
Inlined defaults—a tidier prance!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The PR title 'feat: vips filters tests' is vague and does not accurately reflect the main changes, which involve refactoring tissue_mask to return a single image instead of a tuple and updating filter defaults. Update the title to more specifically describe the primary change, such as 'feat: refactor tissue_mask to return single image' or 'feat: simplify tissue_mask return type'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/vips-filters
📝 Coding Plan
  • Generate coding plan for human review comments

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can use Trivy to scan for security misconfigurations and secrets in Infrastructure as Code files.

Add a .trivyignore file to your project to customize which findings Trivy reports.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the tissue_mask function. The default filter is now defined inline as a default argument, the order of morphological operations has been changed, and the function now returns only the mask image instead of a tuple.

My main feedback is regarding the use of a mutable object as a default function argument. This is a common pitfall in Python that can lead to unexpected behavior. I've suggested a safer pattern using None as the default and creating the filter object inside the function. This requires changes in two places, so I've added two linked comments.

Comment on lines 14 to +25
def tissue_mask(
slide: pyvips.Image, mpp: Res, filter: VipsFilter = default_filter
) -> tuple[pyvips.Image, Res]:
slide: pyvips.Image,
mpp: Res,
filter: VipsFilter = VipsCompose(
[
VipsGrayScaleFilter(),
VipsOtsu(),
VipsClosing(),
VipsOpening(),
]
),
) -> pyvips.Image:

Choose a reason for hiding this comment

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

high

Using a mutable object like a VipsCompose instance as a default argument is a common pitfall in Python. The default object is created only once when the function is defined and is shared across all calls. If this object is ever mutated, it will affect all subsequent calls that use the default. It's safer to use None as the default and create the object inside the function. This comment is paired with another one on the return statement to complete the fix.

def tissue_mask(
    slide: pyvips.Image,
    mpp: Res,
    filter: VipsFilter | None = None,
) -> pyvips.Image:

The generated tissue mask as pyvips.Image.
"""
return filter(slide, mpp)
return filter(slide, mpp)[0]

Choose a reason for hiding this comment

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

high

To complete the fix for the mutable default argument, we need to create the default VipsCompose filter when filter is None.

    if filter is None:
        filter = VipsCompose(
            [
                VipsGrayScaleFilter(),
                VipsOtsu(),
                VipsClosing(),
                VipsOpening(),
            ]
        )
    return filter(slide, mpp)[0]

@JakubPekar JakubPekar closed this Mar 13, 2026
@JakubPekar JakubPekar deleted the feature/vips-filters branch March 13, 2026 23:28
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