Skip to content

Enable setting and resetting a thread-local parent header - #1546

Open
jasongrout wants to merge 6 commits into
ipython:mainfrom
jasongrout:threadlocal-header
Open

Enable setting and resetting a thread-local parent header#1546
jasongrout wants to merge 6 commits into
ipython:mainfrom
jasongrout:threadlocal-header

Conversation

@jasongrout

@jasongrout jasongrout commented Aug 11, 2026

Copy link
Copy Markdown
Member

As mentioned in #1289 (comment) and #1451, there should be a public api for setting and clearing a thread-local parent header. This PR creates a recommended public api for setting/resetting a single thread's parent without setting the global fallback header. An ipywidget OutputWidget can use this to temporarily redirect output from a single thread, for example.

Changelog entry:

Output from threads can be explicitly routed using the new get_ipython().set_thread_parent(), which also returns a token that can be used to undo the set with get_ipython().reset_thread_parent(token). Unlike set_parent(), using set_thread_parent() does not affect the default shell parent, so does not affect output routing in other threads. Since the thread parent is stored in a thread ContextVar, techniques for propagating a thread's ContextVars will also propagate the thread parent without having to explicitly call set_thread_parent().

I also added a number of x.parent = ... parent setters to be more consistent - I'm not directly going to use those, but happy to remove those if there is an objection.

Claude Fable 5 assisted in this PR

jasongrout pushed a commit to jasongrout/ipywidgets that referenced this pull request Aug 11, 2026
When the shell provides set_thread_parent/reset_thread_parent
(ipython/ipykernel#1546), Output.__enter__ delegates the thread-scoped
pinning to it: set_thread_parent(parent) on enter (passing the full
parent request when one is available, so ip.get_parent() also reflects
the capture inside the block, and covering every parent-bearing object
the kernel knows about), and reset_thread_parent(tokens) on exit. The
direct _parent_header ContextVar pinning is kept as a fallback for
ipykernel versions without the API, and everything remains
capability-guarded so non-ipykernel kernels are untouched.

Verified against real kernels: ipykernel 6.29.5 and 7.3.0 (fallback
path) and a kernel built from the ipython/ipykernel#1546 branch (public
API path — confirmed via a live probe that each capture block performs
exactly one set_thread_parent/reset_thread_parent pair). All real-kernel
and mock tests pass on all three; a new mock test pins the API
selection, the full-request argument, and the token round-trip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0136XmUCLSRfgHrrVw1QYMiW
@jasongrout
jasongrout marked this pull request as ready for review August 12, 2026 23:35
@jasongrout
jasongrout requested review from krassowski and minrk August 12, 2026 23:35
@jasongrout jasongrout changed the title Enable temporarily setting a parent header that is only thread-local. Enable setting and resetting a thread-local parent header Aug 12, 2026
@jasongrout

jasongrout commented Aug 12, 2026

Copy link
Copy Markdown
Member Author

@minrk, @krassowski - this finishes out the ideas from #1289 and #1451 to make it easy to set and reset just the thread parent. This will make the OutputWidget's temporary overriding the parent much easier (i.e., helping fix jupyter-widgets/ipywidgets#4020 more cleanly than jupyter-widgets/ipywidgets#4021). I think both of you have the context from #1289 and #1451 to review this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant