Skip to content

Fix: Resolve TypeError for None variant in plot_frequencies_map_markers (#725)#1030

Open
ArnabTechiee wants to merge 7 commits into
malariagen:masterfrom
ArnabTechiee:fix-map-marker-typeerror
Open

Fix: Resolve TypeError for None variant in plot_frequencies_map_markers (#725)#1030
ArnabTechiee wants to merge 7 commits into
malariagen:masterfrom
ArnabTechiee:fix-map-marker-typeerror

Conversation

@ArnabTechiee
Copy link
Copy Markdown

Description

This PR addresses the lingering TypeError reported in Issue #725 during the test suite runs (specifically originating from test_dipclust.py).

The Bug:
When plot_frequencies_interactive_map initializes its ipywidgets.Dropdown for the variant parameter, the widget briefly holds a value of None before the data is fully populated. Because the plot_frequencies_map_markers function strictly enforced variant: Union[int, str], the typeguard library threw a TypeError.

The Fix:

  1. Updated the type hint in plot_frequencies_map_markers to Optional[Union[int, str]].
  2. Added an early return (if variant is None: return) right after the widget imports to safely catch the initial unpopulated state and prevent the downstream AssertionError.

All tests in tests/anoph/test_dipclust.py now pass with zero warnings.

Resolves: #725

@jonbrenas
Copy link
Copy Markdown
Collaborator

Hi @ArnabTechiee,

Your solution does remove the error message but doesn't really solve the problem (which was that plot_frequencies_map_markers was called with 'variant == None' when it shouldn't be in tests). Can you explain in more details why you think it is the way yo go?

@ArnabTechiee
Copy link
Copy Markdown
Author

ArnabTechiee commented Mar 15, 2026

Hi @jonbrenas,

Thank you for the review, and that is a very fair point. You are absolutely right—my current fix treats the symptom (the TypeError) rather than the underlying root cause.

To answer your question on my original reasoning: Because ipywidgets (like Dropdowns) often experience brief transitional states—such as during initial rendering or when options are being asynchronously updated—the widget's internal value can temporarily default to None. I assumed the test suite (test_dipclust.py) was simply catching this transient UI initialization state. I added the early return in the core function to gracefully handle that temporary state without crashing the user's Jupyter cell.

The better approach moving forward:
After reading your feedback, I agree that relaxing the strict type constraints of the core plot_frequencies_map_markers function is the wrong place to handle this. For clean separation of concerns, the core backend function should remain strict and pure, expecting only valid data without needing to know about transient UI states.

Instead, we should handle this at the UI boundary. I propose removing my changes to the plotting function and instead creating a wrapper function (_update_map) inside plot_frequencies_interactive_map. This wrapper will:

Act as a UI shield: It will filter out the temporary None values emitted by the widgets during initialization and only pass valid data downstream.

Improve the interactive call: By defining the wrapper inside the function (closure capture), we avoid having to pass freq_map and ds as clunky ipywidgets.fixed() arguments.

Add future-proofing: We can also check taxon and period for None so if those dropdowns ever glitch in the same way, the shield catches them too.

Does moving the logic upstream to the widget boundary align better with how you'd like to handle this? If so, I will happily refactor this PR (and fix the trailing newline linting failure that just popped up, too!).

Thanks for pushing me to find the cleaner architectural solution!

@ArnabTechiee ArnabTechiee force-pushed the fix-map-marker-typeerror branch from 8c74de4 to ed1e649 Compare March 16, 2026 18:30
Comment thread malariagen_data/anoph/frq_base.py Outdated
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.

2 participants