Fix Param widget not reflecting value changes made in own callback - #8492
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8492 +/- ##
===========================================
+ Coverage 70.32% 86.04% +15.71%
===========================================
Files 348 349 +1
Lines 55093 55114 +21
===========================================
+ Hits 38744 47421 +8677
+ Misses 16349 7693 -8656 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
@philippjfr any suggestions? |
|
@SuMayaBee, the fix makes sense to me, though we do need some tests. |
@philippjfr I've added a parametrized test |
|
Nice, thank you @SuMayaBee! |
|
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Description
This PR fixes an issue where
pn.widgetsbuilt from aparam.Parameterizedmodel do not update in the UI when their value is changed inside their own@param.dependscallback. The param model updates correctly, but the change is never reflected in the frontend.Problem:
When a
@param.dependscallback modifies its own parameter, the widget doesn't reflect the new value even though the param model is correct.While investigating, I found that
link_widget()holds a re-entrancy lock (updating) while syncing the param model. If a watcher fires and changes the parameter during that window, the param→widget sync (link()) sees the lock and silently returns early, leaving the widget out of sync.Solution:
After releasing the lock, compare the current parameter value to what we originally set. If they differ, sync the widget immediately. This avoids infinite loops since it only fires when there's an actual mismatch.
Before/After UI:
Before:
PR11_before.mp4
After:
PR11after.mp4
Fixes #8159
How Has This Been Tested?
Two cases were tested to verify the fix and ensure no regressions:
pn.widgets.Checkboxwith a bound function that resets itself toFalse. This was already working before the fix and should continue to work.param.Parameterizedmodel with a@param.dependscallback that resets its own value. Before the fix, the param model would update correctly but the widget would stay stale in the UI. After the fix, both the param model and the widget correctly reflectFalse.To reproduce, run the following code:
AI Disclosure
Tools: Gemini 3 Flash - Used to analyze the bug and identify the root cause and the implementation.
Checklist