Repository: ipython/ipykernel

Issue:
Can't update `children` trait after widget is displayed.
Akin to #1059, here's another [fun gist with binder](https://gist.github.com/bollwyvl/181eed3cda265e205310f829aa7cc600) that demonstrates some issues observed while try to upgrade to `6.19.x`.

Basically:
- Creating a `HBox` with `children` displays them immediately
- Creating an `HBox` and then setting `children` doesn't show anything at all
  - well, the `.widget-hbox` gets created, but its empty, and never updates

Again, I'll do a bit more debugging.

![Screenshot from 2022-12-19 17-01-17](https://user-images.githubusercontent.com/45380/208544224-ac8b456f-0d37-46e8-9306-726e2dfb2962.png)


Discussion:
maartenbreddels: Let me add a test for this, so we can pour this in concrete.
maartenbreddels: ```patch
From aa0693490a00f8c3ac13f64d92d45012de03c04f Mon Sep 17 00:00:00 2001
From: "Maarten A. Breddels" <maartenbreddels@gmail.com>
Date: Tue, 20 Dec 2022 15:39:04 +0100
Subject: [PATCH] test: make sure comms have the correct kernel

---
 ipykernel/tests/test_comm.py | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/ipykernel/tests/test_comm.py b/ipykernel/tests/test_comm.py
index 405841f..44a30a5 100644
--- a/ipykernel/tests/test_comm.py
+++ b/ipykernel/tests/test_comm.py
@@ -2,6 +2,7 @@ import unittest.mock
 
 from ipykernel.comm import Comm, CommManager
 from ipykernel.ipkernel import IPythonKernel
+from ipykernel.kernelbase import Kernel
 
 
 def test_comm(kernel):
@@ -11,6 +12,8 @@ def test_comm(kernel):
     c = Comm(kernel=kernel, target_name="bar")
     msgs = []
 
+    assert kernel is c.kernel
+
     def on_close(msg):
         msgs.append(msg)
 
@@ -56,6 +59,11 @@ def test_comm_manager(kernel):
         manager.register_comm(comm)
         assert publish_msg.call_count == 1
 
+    # make sure that when we don't pass a kernel, the 'default' kernel is taken
+    Kernel._instance = kernel
+    assert comm.kernel is kernel
+    Kernel.clear_instance()
+
     assert manager.get_comm(comm.comm_id) == comm
     assert manager.get_comm('foo') is None
 
-- 
2.37.1 (Apple Git-137.1)


```
maartenbreddels: Btw, I checked, and indeed the test fails on the current main (2c66b2de835856b19b25c6a890d9665902dda907) 
bollwyvl: patched! :socks: 
maartenbreddels: sorry for the lint issue :)
bollwyvl: is there a bot command to add a label... or can someone? It's annoying to get the :x: immediately, makes the browser tab status icon worthless.
blink1073: We'd have to add config similar to https://github.com/jupyterlab/jupyterlab/blob/master/.meeseeksdev.yml to enable that.

Patch:
diff --git a/ipykernel/comm/comm.py b/ipykernel/comm/comm.py
index 77f9f07..6ec6ff3 100644
--- a/ipykernel/comm/comm.py
+++ b/ipykernel/comm/comm.py
@@ -70,13 +70,16 @@ class Comm(BaseComm, traitlets.config.LoggingConfigurable):
 
     def __init__(self, target_name='', data=None, metadata=None, buffers=None, **kwargs):
         # Handle differing arguments between base classes.
+        had_kernel = 'kernel' in kwargs
         kernel = kwargs.pop('kernel', None)
         if target_name:
             kwargs['target_name'] = target_name
         BaseComm.__init__(
             self, data=data, metadata=metadata, buffers=buffers, **kwargs
         )  # type:ignore[call-arg]
-        kwargs['kernel'] = kernel
+        # only re-add kernel if explicitly provided
+        if had_kernel:
+            kwargs['kernel'] = kernel
         traitlets.config.LoggingConfigurable.__init__(self, **kwargs)
 
 


Test patch:
diff --git a/ipykernel/tests/test_comm.py b/ipykernel/tests/test_comm.py
index 405841f..5ec0d45 100644
--- a/ipykernel/tests/test_comm.py
+++ b/ipykernel/tests/test_comm.py
@@ -2,15 +2,18 @@ import unittest.mock
 
 from ipykernel.comm import Comm, CommManager
 from ipykernel.ipkernel import IPythonKernel
+from ipykernel.kernelbase import Kernel
 
 
-def test_comm(kernel):
+def test_comm(kernel: Kernel) -> None:
     manager = CommManager(kernel=kernel)
-    kernel.comm_manager = manager
+    kernel.comm_manager = manager  # type:ignore
 
     c = Comm(kernel=kernel, target_name="bar")
     msgs = []
 
+    assert kernel is c.kernel  # type:ignore
+
     def on_close(msg):
         msgs.append(msg)
 
@@ -28,7 +31,7 @@ def test_comm(kernel):
     assert c.target_name == "bar"
 
 
-def test_comm_manager(kernel):
+def test_comm_manager(kernel: Kernel) -> None:
     manager = CommManager(kernel=kernel)
     msgs = []
 
@@ -48,7 +51,7 @@ def test_comm_manager(kernel):
     manager.register_target("foo", foo)
     manager.register_target("fizz", fizz)
 
-    kernel.comm_manager = manager
+    kernel.comm_manager = manager  # type:ignore
     with unittest.mock.patch.object(Comm, "publish_msg") as publish_msg:
         comm = Comm()
         comm.on_msg(on_msg)
@@ -56,6 +59,11 @@ def test_comm_manager(kernel):
         manager.register_comm(comm)
         assert publish_msg.call_count == 1
 
+    # make sure that when we don't pass a kernel, the 'default' kernel is taken
+    Kernel._instance = kernel  # type:ignore
+    assert comm.kernel is kernel  # type:ignore
+    Kernel.clear_instance()
+
     assert manager.get_comm(comm.comm_id) == comm
     assert manager.get_comm('foo') is None