Skip to content

RuntimeError "no running event loop"/"Kernel didn't respond in 60 seconds" with Python 3.14 #1079

@khaeru

Description

@khaeru

We experience the following error, e.g. here, with Python 3.14 on GitHub Actions Linux, macOS, and Windows runners. Specifically, from the job log, the following are installed:

CPython 3.14.0
ipykernel==7.0.0
ipython==9.6.0
jupyter==1.1.1
jupyter-client==8.6.3
jupyter-core==5.8.1
nbclient==0.10.2
nbformat==5.10.4

The error does not occur with the same package versions and Python 3.13, e.g. here.

The test code that raises the exception uses nbclient, but the two exceptions are raised from jupyter_client and jupyter_core. I also can't find any concrete declaration of Python 3.14 support on any of the 3 repos, or issues/PRs tracking work to provide such support. So, I've filed the issue here; if it is better filed against one of the other two repos, please say which one.

Apologies for a long traceback.

________________________ test_computationerror_ipython ________________________
[gw1] win32 -- Python 3.14.0 D:\a\genno\genno\.venv\Scripts\python.exe

args = (<nbclient.client.NotebookClient object at 0x0000020DB95FE690>,)
kwargs = {'env': {'ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE': 'C:\\actionarchivecache\\', 'AGENT_TOOLSDIRECTORY': 'C:\\hostedtoolcache\\windows', 'ALLUSERSPROFILE': 'C:\\ProgramData', 'ANDROID_HOME': 'C:\\Android\\android-sdk', ...}}
name = 'MainThread'
inner = <coroutine object NotebookClient.async_execute at 0x0000020DB960C170>
loop = <ProactorEventLoop running=False closed=False debug=False>

    def wrapped(*args: Any, **kwargs: Any) -> Any:
        name = threading.current_thread().name
        inner = coro(*args, **kwargs)
        try:
>           asyncio.get_running_loop()
E           RuntimeError: no running event loop

.venv\Lib\site-packages\jupyter_core\utils\__init__.py:154: RuntimeError

During handling of the above exception, another exception occurred:

test_data_path = MultiplexedPath('D:\a\genno\genno\genno\tests\data')
tmp_path = WindowsPath('C:/Users/runneradmin/AppData/Local/Temp/pytest-of-runneradmin/pytest-0/popen-gw1/test_computationerror_ipython5')

    @pytest.mark.flaky(
        reruns=5,
        rerun_delay=2,
        condition="GITHUB_ACTIONS" in os.environ,
        reason="Flaky; fails occasionally on GitHub Actions runners",
    )
    def test_computationerror_ipython(test_data_path, tmp_path):
        # NB this requires nbformat >= 5.0, because the output kind "evalue" was
        #    different pre-5.0
        fname = test_data_path / "exceptions.ipynb"
>       nb, _ = run_notebook(fname, tmp_path, allow_errors=True)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

genno\tests\core\test_exceptions.py:68: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
genno\testing\jupyter.py:78: in run_notebook
    client.execute(env=env)
.venv\Lib\site-packages\jupyter_core\utils\__init__.py:158: in wrapped
    return loop.run_until_complete(inner)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
C:\Users\runneradmin\AppData\Roaming\uv\python\cpython-3.14.0-windows-x86_64-none\Lib\asyncio\base_events.py:719: in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
.venv\Lib\site-packages\nbclient\client.py:693: in async_execute
    async with self.async_setup_kernel(**kwargs):
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
C:\Users\runneradmin\AppData\Roaming\uv\python\cpython-3.14.0-windows-x86_64-none\Lib\contextlib.py:214: in __aenter__
    return await anext(self.gen)
           ^^^^^^^^^^^^^^^^^^^^^
.venv\Lib\site-packages\nbclient\client.py:651: in async_setup_kernel
    await self.async_start_new_kernel_client()
.venv\Lib\site-packages\nbclient\client.py:566: in async_start_new_kernel_client
    await ensure_async(self.kc.wait_for_ready(timeout=self.startup_timeout))
.venv\Lib\site-packages\jupyter_core\utils\__init__.py:197: in ensure_async
    result = await obj
             ^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <jupyter_client.asynchronous.client.AsyncKernelClient object at 0x0000020DB95FEE70>
timeout = 60

    async def _async_wait_for_ready(self, timeout: t.Optional[float] = None) -> None:
        """Waits for a response when a client is blocked
    
        - Sets future time for timeout
        - Blocks on shell channel until a message is received
        - Exit if the kernel has died
        - If client times out before receiving a message from the kernel, send RuntimeError
        - Flush the IOPub channel
        """
        if timeout is None:
            timeout = float("inf")
        abs_timeout = time.time() + timeout
    
        from .manager import KernelManager
    
        if not isinstance(self.parent, KernelManager):
            # This Client was not created by a KernelManager,
            # so wait for kernel to become responsive to heartbeats
            # before checking for kernel_info reply
            while not await self._async_is_alive():
                if time.time() > abs_timeout:
                    raise RuntimeError(
                        "Kernel didn't respond to heartbeats in %d seconds and timed out" % timeout
                    )
                await asyncio.sleep(0.2)
    
        # Wait for kernel info reply on shell channel
        while True:
            self.kernel_info()
            try:
                msg = await ensure_async(self.shell_channel.get_msg(timeout=1))
            except Empty:
                pass
            else:
                if msg["msg_type"] == "kernel_info_reply":
                    # Checking that IOPub is connected. If it is not connected, start over.
                    try:
                        await ensure_async(self.iopub_channel.get_msg(timeout=0.2))
                    except Empty:
                        pass
                    else:
                        self._handle_kernel_info_reply(msg)
                        break
    
            if not await self._async_is_alive():
                msg = "Kernel died before replying to kernel_info"
                raise RuntimeError(msg)
    
            # Check if current time is ready check time plus timeout
            if time.time() > abs_timeout:
>               raise RuntimeError("Kernel didn't respond in %d seconds" % timeout)
E               RuntimeError: Kernel didn't respond in 60 seconds

.venv\Lib\site-packages\jupyter_client\client.py:207: RuntimeError

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions