Explain figure rendering failures caused by kernel subshells - #597
Open
SimonHeybrock wants to merge 1 commit into
Open
Explain figure rendering failures caused by kernel subshells#597SimonHeybrock wants to merge 1 commit into
SimonHeybrock wants to merge 1 commit into
Conversation
JupyterLab >= 4.4 routes widget messages over kernel subshells, which ipykernel >= 7 services on their own threads. Drawing a live canvas then races with figure creation during cell execution, and Matplotlib is not thread-safe. The resulting mathtext parse error gives users no hint of the cause or of the available workarounds. When laying out a canvas fails while subshells are active, chain the original error into one that names the cause and both workarounds, and document them alongside the installation instructions. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Member
|
See also matplotlib/ipympl#621 |
nvaytet
reviewed
Jul 31, 2026
Member
There was a problem hiding this comment.
I have my reservations as to how useful these tests are. We are trying to make a workaround for an issue that we hope will be fixed upstream.
Creating these fakes that mimic some private or undocumented properties of ipykernel feels like they could get out of date without us noticing.
We are also faking the error from the canvas, so the tests seem quite remote from the actual behaviour?
Member
Author
There was a problem hiding this comment.
Should we try monkey-patching as in the PR you linked instead?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #596 (as far as plopp can), and gives #499 a user-visible answer.
JupyterLab >= 4.4 defaults to routing widget comm messages over kernel subshells, which ipykernel >= 7 services on their own threads. ipympl canvas draw/resize requests are then handled concurrently with cell execution, and Matplotlib is not thread-safe: a live canvas racing a figure build corrupts the global mathtext parser state. Users see
ParseException: Expected end of text, found '$'with a traceback that points at plopp and suggests nothing actionable. See ipympl#610 for the full analysis; the symptom also appears as blank canvases and kernel crashes.There is no fix on our side -- a lock around our own calls does not cover ipympl's frame production and resize handlers. What we can do is stop the error from being a dead end, so this chains it into one that names the cause and the two verified workarounds (
commsOverSubshells: disabled, oripykernel<7), and documents them next to the installation instructions.The message is only substituted when the kernel actually reports active subshells, so nothing changes for other rendering failures. Deliberately reactive rather than a warning at figure creation: with JupyterLab >= 4.4 and ipykernel >= 7 becoming the default, a proactive warning would fire in nearly every session, whether or not the race ever bites.
Test plan
to_widget(explanatory error when subshells are active, original error re-raised otherwise).