From 199f674ca45878bd25496df638594d9893398a5a Mon Sep 17 00:00:00 2001 From: M Bussonnier Date: Mon, 14 Sep 2026 13:25:25 +0200 Subject: [PATCH 1/2] MAINT: Autotype methods For the goal of tightening mypy later, potentialy on a per-file basis autotype some methonds $ autotyping ipykernel --safe --- ipykernel/_eventloop_macos.py | 8 ++-- ipykernel/comm/comm.py | 4 +- ipykernel/comm/manager.py | 4 +- ipykernel/compiler.py | 4 +- ipykernel/control.py | 2 +- ipykernel/debugger.py | 42 ++++++++--------- ipykernel/displayhook.py | 32 ++++++------- ipykernel/embed.py | 2 +- ipykernel/eventloops.py | 68 ++++++++++++++-------------- ipykernel/gui/gtk3embed.py | 12 ++--- ipykernel/gui/gtkembed.py | 12 ++--- ipykernel/heartbeat.py | 2 +- ipykernel/inprocess/blocking.py | 10 ++--- ipykernel/inprocess/channels.py | 22 ++++----- ipykernel/inprocess/client.py | 2 +- ipykernel/inprocess/ipkernel.py | 12 ++--- ipykernel/inprocess/manager.py | 12 ++--- ipykernel/inprocess/socket.py | 4 +- ipykernel/iostream.py | 70 ++++++++++++++--------------- ipykernel/ipkernel.py | 30 ++++++------- ipykernel/kernelapp.py | 48 ++++++++++---------- ipykernel/kernelbase.py | 80 ++++++++++++++++----------------- ipykernel/log.py | 4 +- ipykernel/parentpoller.py | 6 +-- ipykernel/shellchannel.py | 2 +- ipykernel/socket_pair.py | 6 +-- ipykernel/subshell.py | 2 +- ipykernel/subshell_manager.py | 4 +- ipykernel/thread.py | 2 +- ipykernel/trio_runner.py | 10 ++--- ipykernel/utils.py | 4 +- ipykernel/zmqshell.py | 58 ++++++++++++------------ 32 files changed, 290 insertions(+), 290 deletions(-) diff --git a/ipykernel/_eventloop_macos.py b/ipykernel/_eventloop_macos.py index c55546fe2..567af6a3d 100644 --- a/ipykernel/_eventloop_macos.py +++ b/ipykernel/_eventloop_macos.py @@ -83,7 +83,7 @@ def _NSApp(): return msg(C("NSApplication"), n("sharedApplication")) -def _wake(NSApp): +def _wake(NSApp) -> None: """Wake the Application""" objc.objc_msgSend.argtypes = [ void_p, @@ -121,7 +121,7 @@ def _wake(NSApp): _triggered = Event() -def stop(timer=None, loop=None): +def stop(timer=None, loop=None) -> None: """Callback to fire when there's input to be read""" _triggered.set() NSApp = _NSApp() @@ -140,7 +140,7 @@ def stop(timer=None, loop=None): _c_stop_callback = _c_callback_func_type(stop) -def _stop_after(delay): +def _stop_after(delay) -> None: """Register callback to stop eventloop after a delay""" timer = CFRunLoopTimerCreate( None, # allocator @@ -158,7 +158,7 @@ def _stop_after(delay): ) -def mainloop(duration=1): +def mainloop(duration=1) -> None: """run the Cocoa eventloop for the specified duration (seconds)""" _triggered.clear() diff --git a/ipykernel/comm/comm.py b/ipykernel/comm/comm.py index 9be5e23d0..11ed421b3 100644 --- a/ipykernel/comm/comm.py +++ b/ipykernel/comm/comm.py @@ -21,7 +21,7 @@ class BaseComm(comm.base_comm.BaseComm): kernel: Optional["Kernel"] = None - def publish_msg(self, msg_type, data=None, metadata=None, buffers=None, **keys): + def publish_msg(self, msg_type, data=None, metadata=None, buffers=None, **keys) -> None: """Helper for sending a comm message on IOPub""" if not Kernel.initialized(): return @@ -75,7 +75,7 @@ def _default_comm_id(self): def __init__( self, target_name="", data=None, metadata=None, buffers=None, show_warning=True, **kwargs - ): + ) -> None: """Initialize a comm.""" if show_warning: warn( diff --git a/ipykernel/comm/manager.py b/ipykernel/comm/manager.py index 092754946..7d83b3ed3 100644 --- a/ipykernel/comm/manager.py +++ b/ipykernel/comm/manager.py @@ -21,13 +21,13 @@ class CommManager(comm.base_comm.CommManager, traitlets.config.LoggingConfigurab comms = traitlets.Dict() targets = traitlets.Dict() - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: """Initialize the manager.""" # CommManager doesn't take arguments, so we explicitly forward arguments comm.base_comm.CommManager.__init__(self) traitlets.config.LoggingConfigurable.__init__(self, **kwargs) - def comm_open(self, stream, ident, msg): + def comm_open(self, stream, ident, msg) -> None: """Handler for comm_open messages""" # This is for backward compatibility, the comm_open creates a a new ipykernel.comm.Comm # but we should let the base class create the comm with comm.create_comm in a major release diff --git a/ipykernel/compiler.py b/ipykernel/compiler.py index 254642109..348055e15 100644 --- a/ipykernel/compiler.py +++ b/ipykernel/compiler.py @@ -79,7 +79,7 @@ def get_tmp_directory(): return tmp_dir + os.sep + "ipykernel_" + str(pid) -def get_tmp_hash_seed(): +def get_tmp_hash_seed() -> int: """Get a temp hash seed.""" return 0xC70F6907 @@ -96,7 +96,7 @@ def get_file_name(code): class XCachingCompiler(CachingCompiler): """A custom caching compiler.""" - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: """Initialize the compiler.""" super().__init__(*args, **kwargs) self.log = None diff --git a/ipykernel/control.py b/ipykernel/control.py index 21d6d9962..81ad07e00 100644 --- a/ipykernel/control.py +++ b/ipykernel/control.py @@ -6,6 +6,6 @@ class ControlThread(BaseThread): """A thread for a control channel.""" - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: """Initialize the thread.""" super().__init__(name=CONTROL_THREAD_NAME, **kwargs) diff --git a/ipykernel/debugger.py b/ipykernel/debugger.py index ebb9c7777..781d8fece 100644 --- a/ipykernel/debugger.py +++ b/ipykernel/debugger.py @@ -51,7 +51,7 @@ class _FakeCode: """Fake code class.""" - def __init__(self, co_filename, co_name): + def __init__(self, co_filename, co_name) -> None: """Init.""" self.co_filename = co_filename self.co_name = co_name @@ -60,7 +60,7 @@ def __init__(self, co_filename, co_name): class _FakeFrame: """Fake frame class.""" - def __init__(self, f_code, f_globals, f_locals): + def __init__(self, f_code, f_globals, f_locals) -> None: """Init.""" self.f_code = f_code self.f_globals = f_globals @@ -71,7 +71,7 @@ def __init__(self, f_code, f_globals, f_locals): class _DummyPyDB: """Fake PyDb class.""" - def __init__(self): + def __init__(self) -> None: """Init.""" from _pydevd_bundle.pydevd_api import PyDevdAPI @@ -81,20 +81,20 @@ def __init__(self): class VariableExplorer: """A variable explorer.""" - def __init__(self): + def __init__(self) -> None: """Initialize the explorer.""" self.suspended_frame_manager = SuspendedFramesManager() self.py_db = _DummyPyDB() self.tracker = _FramesTracker(self.suspended_frame_manager, self.py_db) self.frame = None - def track(self): + def track(self) -> None: """Start tracking.""" var = t.cast("InteractiveShell", get_ipython()).user_ns self.frame = _FakeFrame(_FakeCode("", get_file_name("sys._getframe()")), var, var) self.tracker.track("thread1", pydevd_frame_utils.create_frames_list_from_frame(self.frame)) - def untrack_all(self): + def untrack_all(self) -> None: """Stop tracking.""" self.tracker.untrack_all() @@ -115,7 +115,7 @@ class DebugpyMessageQueue: SEPARATOR = "\r\n\r\n" SEPARATOR_LENGTH = 4 - def __init__(self, event_callback, log): + def __init__(self, event_callback, log) -> None: """Init the queue.""" self.tcp_buffer = "" self._reset_tcp_pos() @@ -123,13 +123,13 @@ def __init__(self, event_callback, log): self.message_queue: Queue[t.Any] = Queue() self.log = log - def _reset_tcp_pos(self): + def _reset_tcp_pos(self) -> None: self.header_pos = -1 self.separator_pos = -1 self.message_size = 0 self.message_pos = -1 - def _put_message(self, raw_msg): + def _put_message(self, raw_msg) -> None: self.log.debug("QUEUE - _put_message:") msg = t.cast(dict[str, t.Any], jsonapi.loads(raw_msg)) if msg["type"] == "event": @@ -141,7 +141,7 @@ def _put_message(self, raw_msg): self.log.debug(msg) self.message_queue.put_nowait(msg) - def put_tcp_frame(self, frame): + def put_tcp_frame(self, frame) -> None: """Put a tcp frame in the queue.""" self.tcp_buffer += frame @@ -196,7 +196,7 @@ async def get_message(self): class DebugpyClient: """A client for debugpy.""" - def __init__(self, log, debugpy_stream, event_callback): + def __init__(self, log, debugpy_stream, event_callback) -> None: """Initialize the client.""" self.log = log self.debugpy_stream = debugpy_stream @@ -213,13 +213,13 @@ def _get_endpoint(self): host, port = self.get_host_port() return "tcp://" + host + ":" + str(port) - def _forward_event(self, msg): + def _forward_event(self, msg) -> None: if msg["event"] == "initialized": self.init_event.set() self.init_event_seq = msg["seq"] self.event_callback(msg) - def _send_request(self, msg): + def _send_request(self, msg) -> None: if self.routing_id is None: self.routing_id = self.debugpy_stream.socket.getsockopt(ROUTING_ID) content = jsonapi.dumps( @@ -273,12 +273,12 @@ def get_host_port(self): self.debugpy_port = self.endpoint[index + 1 :] return self.debugpy_host, self.debugpy_port - def connect_tcp_socket(self): + def connect_tcp_socket(self) -> None: """Connect to the tcp socket.""" self.debugpy_stream.socket.connect(self._get_endpoint()) self.routing_id = self.debugpy_stream.socket.getsockopt(ROUTING_ID) - def disconnect_tcp_socket(self): + def disconnect_tcp_socket(self) -> None: """Disconnect from the tcp socket.""" self.debugpy_stream.socket.disconnect(self._get_endpoint()) self.routing_id = None @@ -286,7 +286,7 @@ def disconnect_tcp_socket(self): self.init_event_seq = -1 self.wait_for_attach = True - def receive_dap_frame(self, frame): + def receive_dap_frame(self, frame) -> None: """Receive a dap frame.""" self.message_queue.put_tcp_frame(frame) @@ -337,7 +337,7 @@ def __init__( kernel_modules, just_my_code=False, filter_internal_frames=True, - ): + ) -> None: """Initialize the debugger.""" self.log = log self.debugpy_client = DebugpyClient(log, debugpy_stream, self._handle_event) @@ -370,7 +370,7 @@ def __init__( self.variable_explorer = VariableExplorer() - def _handle_event(self, msg): + def _handle_event(self, msg) -> None: if msg["event"] == "stopped": if msg["body"]["allThreadsStopped"]: self.stopped_queue.put_nowait(msg) @@ -401,13 +401,13 @@ def _build_variables_response(self, request, variables): "body": {"variables": var_list}, } - def _accept_stopped_thread(self, thread_name): + def _accept_stopped_thread(self, thread_name) -> bool: # TODO: identify Thread-2, Thread-3 and Thread-4. These are NOT # Control, IOPub or Heartbeat threads forbid_list = ["IPythonHistorySavingThread", "Thread-2", "Thread-3", "Thread-4"] return thread_name not in forbid_list - async def handle_stopped_event(self): + async def handle_stopped_event(self) -> None: """Handle a stopped event.""" # Wait for a stopped event message in the stopped queue # This message is used for triggering the 'threads' request @@ -454,7 +454,7 @@ def start(self): self.debugpy_client.connect_tcp_socket() return self.debugpy_initialized - def stop(self): + def stop(self) -> None: """Stop the debugger.""" self.debugpy_client.disconnect_tcp_socket() diff --git a/ipykernel/displayhook.py b/ipykernel/displayhook.py index 3b80e9a80..bfc469ec8 100644 --- a/ipykernel/displayhook.py +++ b/ipykernel/displayhook.py @@ -23,7 +23,7 @@ class ZMQDisplayHook: topic = b"execute_result" - def __init__(self, session, pub_socket): + def __init__(self, session, pub_socket) -> None: """Initialize the hook.""" self.session = session self.pub_socket = pub_socket @@ -32,11 +32,11 @@ def __init__(self, session, pub_socket): self._parent_header.set({}) self._parent_header_global = {} - def get_execution_count(self): + def get_execution_count(self) -> int: """This method is replaced in kernelapp""" return 0 - def __call__(self, obj): + def __call__(self, obj) -> None: """Handle a hook call.""" if obj is None: return @@ -65,7 +65,7 @@ def parent_header(self): return self._parent_header_global @parent_header.setter - def parent_header(self, value): + def parent_header(self, value) -> None: self._parent_header.set(value) self._parent_header_global = value @@ -73,11 +73,11 @@ def set_thread_parent(self, parent): """Set the parent header for the calling thread only. Returns a reset token that can be used with reset_thread_parent.""" return self._parent_header.set(extract_header(parent)) - def reset_thread_parent(self, token): + def reset_thread_parent(self, token) -> None: """Reset the parent header to undo the set_thread_parent call that returned the token.""" self._parent_header.reset(token) - def set_parent(self, parent): + def set_parent(self, parent) -> None: """Set the global and thread parent header.""" self.parent_header = extract_header(parent) @@ -95,7 +95,7 @@ class ZMQShellDisplayHook(DisplayHook): _thread_local = Any() msg: dict[str, t.Any] | None - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self._parent_header = ContextVar("parent_header") self._parent_header.set({}) @@ -111,7 +111,7 @@ def _hooks(self): self._thread_local.hooks = [] return self._thread_local.hooks - def register_hook(self, hook): + def register_hook(self, hook) -> None: """Register a transform hook on the execute_result message. Mirrors ``ZMQDisplayPublisher.register_hook``. Each hook receives the @@ -120,7 +120,7 @@ def register_hook(self, hook): """ self._hooks.append(hook) - def unregister_hook(self, hook): + def unregister_hook(self, hook) -> bool: """Remove a previously registered hook. Returns True on success.""" try: self._hooks.remove(hook) @@ -136,7 +136,7 @@ def parent_header(self): return self._parent_header_global @parent_header.setter - def parent_header(self, value): + def parent_header(self, value) -> None: self._parent_header.set(value) self._parent_header_global = value @@ -144,15 +144,15 @@ def set_thread_parent(self, parent): """Set the parent header for the calling thread only. Returns a reset token that can be used with reset_thread_parent.""" return self._parent_header.set(extract_header(parent)) - def reset_thread_parent(self, token): + def reset_thread_parent(self, token) -> None: """Reset the parent header to undo the set_thread_parent call that returned the token.""" self._parent_header.reset(token) - def set_parent(self, parent): + def set_parent(self, parent) -> None: """Set the global and thread parent header.""" self.parent_header = extract_header(parent) - def start_displayhook(self): + def start_displayhook(self) -> None: """Start the display hook.""" if self.session: self.msg = self.session.msg( @@ -164,18 +164,18 @@ def start_displayhook(self): parent=self.parent_header, ) - def write_output_prompt(self): + def write_output_prompt(self) -> None: """Write the output prompt.""" if self.msg: self.msg["content"]["execution_count"] = self.prompt_count - def write_format_data(self, format_dict, md_dict=None): + def write_format_data(self, format_dict, md_dict=None) -> None: """Write format data to the message.""" if self.msg: self.msg["content"]["data"] = json_clean(encode_images(format_dict)) self.msg["content"]["metadata"] = md_dict - def finish_displayhook(self): + def finish_displayhook(self) -> None: """Finish up all displayhook activities. Runs the registered hook chain before ``session.send``. Each hook diff --git a/ipykernel/embed.py b/ipykernel/embed.py index 5078f8ace..984665c92 100644 --- a/ipykernel/embed.py +++ b/ipykernel/embed.py @@ -14,7 +14,7 @@ # ----------------------------------------------------------------------------- -def embed_kernel(module=None, local_ns=None, **kwargs): +def embed_kernel(module=None, local_ns=None, **kwargs) -> None: """Embed and start an IPython kernel in a given scope. Parameters diff --git a/ipykernel/eventloops.py b/ipykernel/eventloops.py index 69965ca71..1cbf850d0 100644 --- a/ipykernel/eventloops.py +++ b/ipykernel/eventloops.py @@ -78,7 +78,7 @@ def get_shell_stream(kernel): return kernel.shell_stream -def _notify_stream_qt(kernel): +def _notify_stream_qt(kernel) -> None: import operator from functools import lru_cache @@ -92,12 +92,12 @@ def _notify_stream_qt(kernel): def enum_helper(name): return operator.attrgetter(name.rpartition(".")[0])(sys.modules[QtCore.__package__]) - def exit_loop(): + def exit_loop() -> None: """fall back to main loop""" kernel._qt_notifier.setEnabled(False) kernel.app.qt_event_loop.quit() - def process_stream_events_wrap(shell_stream, *args, **kwargs): + def process_stream_events_wrap(shell_stream, *args, **kwargs) -> None: """fall back to main loop when there's a socket event""" # call flush to ensure that the stream doesn't lose events # due to our consuming of the edge-triggered FD @@ -120,7 +120,7 @@ def process_stream_events_wrap(shell_stream, *args, **kwargs): # allow for scheduling exits from the loop in case a timeout needs to # be set from the kernel level - def _schedule_exit(delay): + def _schedule_exit(delay) -> None: """schedule fall back to main loop in [delay] seconds""" # The signatures of QtCore.QTimer.singleShot are inconsistent between PySide and PyQt # if setting the TimerType, so we create a timer explicitly and store it @@ -146,7 +146,7 @@ def _schedule_exit(delay): @register_integration("qt", "qt5", "qt6") -def loop_qt(kernel): +def loop_qt(kernel) -> None: """Event loop for all supported versions of Qt.""" _notify_stream_qt(kernel) # install hook to stop event loop. @@ -165,11 +165,11 @@ def loop_qt(kernel): # exit and watch are the same for qt 4 and 5 @loop_qt.exit -def loop_qt_exit(kernel): +def loop_qt_exit(kernel) -> None: kernel.app.exit() -def _loop_wx(app): +def _loop_wx(app) -> None: """Inner-loop for running the Wx eventloop Pulled from guisupport.start_event_loop in IPython < 5.2, @@ -182,14 +182,14 @@ def _loop_wx(app): @register_integration("wx") -def loop_wx(kernel): +def loop_wx(kernel) -> None: """Start a kernel with wx event loop support.""" import wx # We have to put the wx.Timer in a wx.Frame for it to fire properly. # We make the Frame hidden when we create it in the main app below. class TimerFrame(wx.Frame): # type:ignore[misc] - def __init__(self, kernel): + def __init__(self, kernel) -> None: self.kernel = kernel self.shell_stream = get_shell_stream(kernel) @@ -202,7 +202,7 @@ def __init__(self, kernel): # Units for the timer are in milliseconds self.timer.Start(int(1000 * self.kernel._poll_interval)) - def wake(self): + def wake(self) -> None: """wake from wx""" try: if self.shell_stream.flush(limit=1): @@ -210,10 +210,10 @@ def wake(self): except Exception: # noqa: S110 pass - def on_timer(self, event): + def on_timer(self, event) -> None: self.wake() - def on_exit(self, event): + def on_exit(self, event) -> None: self.timer.Stop() self.wake() self.Destroy() @@ -221,7 +221,7 @@ def on_exit(self, event): # We need a custom wx.App to create our Frame subclass that has the # wx.Timer to defer back to the tornado event loop. class IPWxApp(wx.App): # type:ignore[misc] - def OnInit(self): + def OnInit(self) -> bool: self.frame = TimerFrame(kernel) self.frame.Show(False) return True @@ -243,7 +243,7 @@ def OnInit(self): @loop_wx.exit -def loop_wx_exit(kernel): +def loop_wx_exit(kernel) -> None: """Exit the wx loop.""" import wx @@ -251,7 +251,7 @@ def loop_wx_exit(kernel): @register_integration("tk") -def loop_tk(kernel): +def loop_tk(kernel) -> None: """Start a kernel with the Tk event loop.""" from tkinter import READABLE, Tk @@ -263,25 +263,25 @@ def loop_tk(kernel): if hasattr(app, "createfilehandler"): # A basic wrapper for structural similarity with the Windows version class BasicAppWrapper: - def __init__(self, app): + def __init__(self, app) -> None: self.app = app self.app.withdraw() - def exit_loop(): + def exit_loop() -> None: """fall back to main loop""" app.tk.deletefilehandler(shell_stream.getsockopt(zmq.FD)) app.quit() app.destroy() del kernel.app_wrapper - def process_stream_events_wrap(shell_stream, *a, **kw): + def process_stream_events_wrap(shell_stream, *a, **kw) -> None: """fall back to main loop when there's a socket event""" if shell_stream.flush(limit=1): exit_loop() # allow for scheduling exits from the loop in case a timeout needs to # be set from the kernel level - def _schedule_exit(delay): + def _schedule_exit(delay) -> None: """schedule fall back to main loop in [delay] seconds""" app.after(int(1000 * delay), exit_loop) @@ -311,15 +311,15 @@ def _schedule_exit(delay): shell_stream = get_shell_stream(kernel) class TimedAppWrapper: - def __init__(self, app, shell_stream): + def __init__(self, app, shell_stream) -> None: self.app = app self.shell_stream = shell_stream self.app.withdraw() - async def func(self): + async def func(self) -> None: self.shell_stream.flush(limit=1) - def on_timer(self): + def on_timer(self) -> None: loop = asyncio.get_event_loop() try: loop.run_until_complete(self.func()) @@ -327,7 +327,7 @@ def on_timer(self): kernel.log.exception("Error in message handler") self.app.after(poll_interval, self.on_timer) - def start(self): + def start(self) -> None: self.on_timer() # Call it once to get things going. self.app.mainloop() @@ -336,7 +336,7 @@ def start(self): @loop_tk.exit -def loop_tk_exit(kernel): +def loop_tk_exit(kernel) -> None: """Exit the tk loop.""" try: kernel.app_wrapper.app.quit() @@ -348,7 +348,7 @@ def loop_tk_exit(kernel): @register_integration("gtk") -def loop_gtk(kernel): +def loop_gtk(kernel) -> None: """Start the kernel, coordinating with the GTK event loop""" from .gui.gtkembed import GTKEmbed @@ -358,13 +358,13 @@ def loop_gtk(kernel): @loop_gtk.exit -def loop_gtk_exit(kernel): +def loop_gtk_exit(kernel) -> None: """Exit the gtk loop.""" kernel._gtk.stop() @register_integration("gtk3") -def loop_gtk3(kernel): +def loop_gtk3(kernel) -> None: """Start the kernel, coordinating with the GTK event loop""" from .gui.gtk3embed import GTKEmbed @@ -374,7 +374,7 @@ def loop_gtk3(kernel): @loop_gtk3.exit -def loop_gtk3_exit(kernel): +def loop_gtk3_exit(kernel) -> None: """Exit the gtk3 loop.""" kernel._gtk.stop() @@ -389,7 +389,7 @@ def loop_cocoa(kernel): real_excepthook = sys.excepthook shell_stream = get_shell_stream(kernel) - def handle_int(etype, value, tb): + def handle_int(etype, value, tb) -> None: """don't let KeyboardInterrupts look like crashes""" # wake the eventloop when we get a signal stop() @@ -420,7 +420,7 @@ def handle_int(etype, value, tb): @loop_cocoa.exit -def loop_cocoa_exit(kernel): +def loop_cocoa_exit(kernel) -> None: """Exit the cocoa loop.""" from ._eventloop_macos import stop @@ -444,7 +444,7 @@ def loop_asyncio(kernel): loop._should_close = False # type:ignore[attr-defined] # pause eventloop when there's an event on a zmq socket - def process_stream_events(shell_stream): + def process_stream_events(shell_stream) -> None: """fall back to main loop when there's a socket event""" if shell_stream.flush(limit=1): loop.stop() @@ -470,7 +470,7 @@ def process_stream_events(shell_stream): @loop_asyncio.exit -def loop_asyncio_exit(kernel): +def loop_asyncio_exit(kernel) -> None: """Exit hook for asyncio""" import asyncio @@ -490,7 +490,7 @@ async def close_loop(): loop.close() -def set_qt_api_env_from_gui(gui): +def set_qt_api_env_from_gui(gui) -> None: """ Sets the QT_API environment variable by trying to import PyQtx or PySidex. @@ -582,7 +582,7 @@ def set_qt_api_env_from_gui(gui): return -def make_qt_app_for_kernel(gui, kernel): +def make_qt_app_for_kernel(gui, kernel) -> None: """Sets the `QT_API` environment variable if it isn't already set.""" if hasattr(kernel, "app"): # Kernel is already running a Qt event loop, so there's no need to diff --git a/ipykernel/gui/gtk3embed.py b/ipykernel/gui/gtk3embed.py index 91b5b4942..94309b056 100644 --- a/ipykernel/gui/gtk3embed.py +++ b/ipykernel/gui/gtk3embed.py @@ -32,20 +32,20 @@ class GTKEmbed: """A class to embed a kernel into the GTK main event loop.""" - def __init__(self, kernel): + def __init__(self, kernel) -> None: """Initialize the embed.""" self.kernel = kernel # These two will later store the real gtk functions when we hijack them self.gtk_main = None self.gtk_main_quit = None - def start(self): + def start(self) -> None: """Starts the GTK main event loop and sets our kernel startup routine.""" # Register our function to initiate the kernel and start gtk GObject.idle_add(self._wire_kernel) Gtk.main() - def _wire_kernel(self): + def _wire_kernel(self) -> bool: """Initializes the kernel inside GTK. This is meant to run only once at startup, so it does its job and @@ -55,7 +55,7 @@ def _wire_kernel(self): GObject.timeout_add(int(1000 * self.kernel._poll_interval), self.iterate_kernel) return False - def iterate_kernel(self): + def iterate_kernel(self) -> bool: """Run one iteration of the kernel and return True. GTK timer functions must return True to be called again, so we make the @@ -64,7 +64,7 @@ def iterate_kernel(self): self.kernel.do_one_iteration() return True - def stop(self): + def stop(self) -> None: """Stop the embed.""" # FIXME: this one isn't getting called because we have no reliable # kernel shutdown. We need to fix that: once the kernel has a @@ -88,7 +88,7 @@ def _hijack_gtk(self): - Gtk.main_quit """ - def dummy(*args, **kw): + def dummy(*args, **kw) -> None: """No-op.""" # save and trap main and main_quit from gtk diff --git a/ipykernel/gui/gtkembed.py b/ipykernel/gui/gtkembed.py index 6f3b6d166..23e6b4509 100644 --- a/ipykernel/gui/gtkembed.py +++ b/ipykernel/gui/gtkembed.py @@ -29,20 +29,20 @@ class GTKEmbed: """A class to embed a kernel into the GTK main event loop.""" - def __init__(self, kernel): + def __init__(self, kernel) -> None: """Initialize the embed.""" self.kernel = kernel # These two will later store the real gtk functions when we hijack them self.gtk_main = None self.gtk_main_quit = None - def start(self): + def start(self) -> None: """Starts the GTK main event loop and sets our kernel startup routine.""" # Register our function to initiate the kernel and start gtk gobject.idle_add(self._wire_kernel) gtk.main() - def _wire_kernel(self): + def _wire_kernel(self) -> bool: """Initializes the kernel inside GTK. This is meant to run only once at startup, so it does its job and @@ -52,7 +52,7 @@ def _wire_kernel(self): gobject.timeout_add(int(1000 * self.kernel._poll_interval), self.iterate_kernel) return False - def iterate_kernel(self): + def iterate_kernel(self) -> bool: """Run one iteration of the kernel and return True. GTK timer functions must return True to be called again, so we make the @@ -61,7 +61,7 @@ def iterate_kernel(self): self.kernel.do_one_iteration() return True - def stop(self): + def stop(self) -> None: """Stop the embed.""" # FIXME: this one isn't getting called because we have no reliable # kernel shutdown. We need to fix that: once the kernel has a @@ -85,7 +85,7 @@ def _hijack_gtk(self): - gtk.main_quit """ - def dummy(*args, **kw): + def dummy(*args, **kw) -> None: """No-op.""" # save and trap main and main_quit from gtk diff --git a/ipykernel/heartbeat.py b/ipykernel/heartbeat.py index 3f0de81f4..1183b20ff 100644 --- a/ipykernel/heartbeat.py +++ b/ipykernel/heartbeat.py @@ -27,7 +27,7 @@ class Heartbeat(Thread): """A simple ping-pong style heartbeat that runs in a thread.""" - def __init__(self, context, addr=None, *, curve_publickey=None, curve_secretkey=None): + def __init__(self, context, addr=None, *, curve_publickey=None, curve_secretkey=None) -> None: """Initialize the heartbeat thread. Parameters diff --git a/ipykernel/inprocess/blocking.py b/ipykernel/inprocess/blocking.py index 3c2991990..aa26c81f9 100644 --- a/ipykernel/inprocess/blocking.py +++ b/ipykernel/inprocess/blocking.py @@ -24,12 +24,12 @@ class BlockingInProcessChannel(InProcessChannel): """A blocking in-process channel.""" - def __init__(self, *args, **kwds): + def __init__(self, *args, **kwds) -> None: """Initialize the channel.""" super().__init__(*args, **kwds) self._in_queue: Queue[object] = Queue() - def call_handlers(self, msg): + def call_handlers(self, msg) -> None: """Call the handlers for a message.""" self._in_queue.put(msg) @@ -51,7 +51,7 @@ def get_msgs(self): break return msgs - def msg_ready(self): + def msg_ready(self) -> bool: """Is there a message that has been received?""" return not self._in_queue.empty() @@ -59,7 +59,7 @@ def msg_ready(self): class BlockingInProcessStdInChannel(BlockingInProcessChannel): """A blocking in-process stdin channel.""" - def call_handlers(self, msg): + def call_handlers(self, msg) -> None: """Overridden for the in-process channel. This methods simply calls raw_input directly. @@ -82,7 +82,7 @@ class BlockingInProcessKernelClient(InProcessKernelClient): iopub_channel_class = Type(BlockingInProcessChannel) stdin_channel_class = Type(BlockingInProcessStdInChannel) - def wait_for_ready(self): + def wait_for_ready(self) -> None: """Wait for kernel info reply on shell channel.""" while True: self.kernel_info() diff --git a/ipykernel/inprocess/channels.py b/ipykernel/inprocess/channels.py index 4c01c5bcb..40dbbbbec 100644 --- a/ipykernel/inprocess/channels.py +++ b/ipykernel/inprocess/channels.py @@ -15,7 +15,7 @@ class InProcessChannel: proxy_methods: list[object] = [] - def __init__(self, client=None): + def __init__(self, client=None) -> None: """Initialize the channel.""" super().__init__() self.client = client @@ -25,11 +25,11 @@ def is_alive(self): """Test if the channel is alive.""" return self._is_alive - def start(self): + def start(self) -> None: """Start the channel.""" self._is_alive = True - def stop(self): + def stop(self) -> None: """Stop the channel.""" self._is_alive = False @@ -41,10 +41,10 @@ def call_handlers(self, msg): msg = "call_handlers must be defined in a subclass." raise NotImplementedError(msg) - def flush(self, timeout=1.0): + def flush(self, timeout=1.0) -> None: """Flush the channel.""" - def call_handlers_later(self, *args, **kwds): + def call_handlers_later(self, *args, **kwds) -> None: """Call the message handlers later. The default implementation just calls the handlers immediately, but this @@ -72,7 +72,7 @@ class InProcessHBChannel: time_to_dead = 3.0 - def __init__(self, client=None): + def __init__(self, client=None) -> None: """Initialize the channel.""" super().__init__() self.client = client @@ -83,23 +83,23 @@ def is_alive(self): """Test if the channel is alive.""" return self._is_alive - def start(self): + def start(self) -> None: """Start the channel.""" self._is_alive = True - def stop(self): + def stop(self) -> None: """Stop the channel.""" self._is_alive = False - def pause(self): + def pause(self) -> None: """Pause the channel.""" self._pause = True - def unpause(self): + def unpause(self) -> None: """Unpause the channel.""" self._pause = False - def is_beating(self): + def is_beating(self) -> bool: """Test if the channel is beating.""" return not self._pause diff --git a/ipykernel/inprocess/client.py b/ipykernel/inprocess/client.py index f43951ec6..36aff2343 100644 --- a/ipykernel/inprocess/client.py +++ b/ipykernel/inprocess/client.py @@ -66,7 +66,7 @@ def get_connection_info(self, session: bool = False) -> KernelConnectionInfo: d["kernel"] = self.kernel # type: ignore[typeddict-unknown-key] return d - def start_channels(self, *args, **kwargs): + def start_channels(self, *args, **kwargs) -> None: """Start the channels on the client.""" super().start_channels() if self.kernel: diff --git a/ipykernel/inprocess/ipkernel.py b/ipykernel/inprocess/ipkernel.py index ebefd16e1..a7311b11a 100644 --- a/ipykernel/inprocess/ipkernel.py +++ b/ipykernel/inprocess/ipkernel.py @@ -68,7 +68,7 @@ def _default_iopub_socket(self): stdin_socket = Instance(DummySocket, ()) - def __init__(self, **traits): + def __init__(self, **traits) -> None: """Initialize the kernel.""" super().__init__(**traits) @@ -76,17 +76,17 @@ def __init__(self, **traits): if self.shell: self.shell.kernel = self - async def execute_request(self, stream, ident, parent): + async def execute_request(self, stream, ident, parent) -> None: """Override for temporary IO redirection.""" with self._redirected_io(): await super().execute_request(stream, ident, parent) - def start(self): + def start(self) -> None: """Override registration of dispatchers for streams.""" if self.shell: self.shell.exit_now = False - def _abort_queues(self, subshell_id: str | None = ...): + def _abort_queues(self, subshell_id: str | None = ...) -> None: """The in-process kernel doesn't abort requests.""" def _input_request(self, prompt, ident, parent, password=False): @@ -131,7 +131,7 @@ def _redirected_io(self): # ------ Trait change handlers -------------------------------------------- - def _io_dispatch(self, change): + def _io_dispatch(self, change) -> None: """Called when a message is sent to the IO socket.""" assert self.iopub_socket.io_thread is not None assert self.session is not None @@ -181,7 +181,7 @@ class InProcessInteractiveShell(ZMQInteractiveShell): # InteractiveShell interface # ------------------------------------------------------------------------- - def enable_gui(self, gui=None): + def enable_gui(self, gui=None) -> None: """Enable GUI integration for the kernel.""" if not gui: gui = self.kernel.gui diff --git a/ipykernel/inprocess/manager.py b/ipykernel/inprocess/manager.py index 3a3f92c37..d36525904 100644 --- a/ipykernel/inprocess/manager.py +++ b/ipykernel/inprocess/manager.py @@ -41,28 +41,28 @@ def _default_session(self): # Kernel management methods # -------------------------------------------------------------------------- - def start_kernel(self, **kwds): + def start_kernel(self, **kwds) -> None: """Start the kernel.""" from ipykernel.inprocess.ipkernel import InProcessKernel self.kernel = InProcessKernel(parent=self, session=self.session) - def shutdown_kernel(self): + def shutdown_kernel(self) -> None: """Shutdown the kernel.""" if self.kernel: self.kernel.iopub_thread.stop() self._kill_kernel() - def restart_kernel(self, now=False, **kwds): + def restart_kernel(self, now=False, **kwds) -> None: """Restart the kernel.""" self.shutdown_kernel() self.start_kernel(**kwds) @property - def has_kernel(self): + def has_kernel(self) -> bool: return self.kernel is not None - def _kill_kernel(self): + def _kill_kernel(self) -> None: self.kernel = None def interrupt_kernel(self): @@ -75,7 +75,7 @@ def signal_kernel(self, signum): msg = "Cannot signal in-process kernel." raise NotImplementedError(msg) - def is_alive(self): + def is_alive(self) -> bool: """Test if the kernel is alive.""" return self.kernel is not None diff --git a/ipykernel/inprocess/socket.py b/ipykernel/inprocess/socket.py index 2a2866cb5..59dd84bb6 100644 --- a/ipykernel/inprocess/socket.py +++ b/ipykernel/inprocess/socket.py @@ -31,11 +31,11 @@ def recv_multipart(self, flags=0, copy=True, track=False): """Recv a multipart message.""" return self.queue.get_nowait() - def send_multipart(self, msg_parts, flags=0, copy=True, track=False): + def send_multipart(self, msg_parts, flags=0, copy=True, track=False) -> None: """Send a multipart message.""" msg_parts = list(map(zmq.Message, msg_parts)) self.queue.put_nowait(msg_parts) self.message_sent += 1 - def flush(self, timeout=1.0): + def flush(self, timeout=1.0) -> None: """no-op to comply with stream API""" diff --git a/ipykernel/iostream.py b/ipykernel/iostream.py index ef6aa1994..52bba7ffa 100644 --- a/ipykernel/iostream.py +++ b/ipykernel/iostream.py @@ -51,7 +51,7 @@ class IOPubThread: whose IO is always run in a thread. """ - def __init__(self, socket, pipe=False, session=False): + def __init__(self, socket, pipe=False, session=False) -> None: """Create IOPub thread Parameters @@ -85,7 +85,7 @@ def __init__(self, socket, pipe=False, session=False): self.thread.is_pydev_daemon_thread = True # type:ignore[attr-defined] self.thread.name = "IOPub" - def _setup_xpub_listener(self): + def _setup_xpub_listener(self) -> None: """Setup listener for XPUB subscription events""" # Checks the socket is not a DummySocket @@ -97,7 +97,7 @@ def _setup_xpub_listener(self): self._xpub_stream = ZMQStream(self.socket, self.io_loop) self._xpub_stream.on_recv(self._handle_subscription) - def _handle_subscription(self, frames): + def _handle_subscription(self, frames) -> None: """Handle subscription/unsubscription events from XPUB socket XPUB sockets receive: @@ -115,7 +115,7 @@ def _handle_subscription(self, frames): continue self._send_welcome_message(subscription_str) - def _send_welcome_message(self, subscription): + def _send_welcome_message(self, subscription) -> None: """Send iopub_welcome message for new subscription Parameters @@ -154,10 +154,10 @@ def _send_welcome_message(self, subscription): # Send directly on socket (we're already in IO thread context) self.socket.send_multipart(full_msg) - def _thread_main(self): + def _thread_main(self) -> None: """The inner loop that's actually run in a thread""" - def _start_event_gc(): + def _start_event_gc() -> None: self._event_pipe_gc_task = asyncio.ensure_future(self._run_event_pipe_gc()) self.io_loop.run_sync(_start_event_gc) @@ -169,7 +169,7 @@ def _start_event_gc(): if self._event_pipe_gc_task is not None: # cancel gc task to avoid pending task warnings - async def _cancel(): + async def _cancel() -> None: self._event_pipe_gc_task.cancel() # type:ignore[union-attr] if not self._stopped: @@ -179,7 +179,7 @@ async def _cancel(): self.io_loop.close(all_fds=True) - def _setup_event_pipe(self): + def _setup_event_pipe(self) -> None: """Create the PULL socket listening for events that should fire in this thread.""" ctx = self.socket.context pipe_in = ctx.socket(zmq.PULL) @@ -191,7 +191,7 @@ def _setup_event_pipe(self): self._event_puller = ZMQStream(pipe_in, self.io_loop) self._event_puller.on_recv(self._handle_event) - async def _run_event_pipe_gc(self): + async def _run_event_pipe_gc(self) -> None: """Task to run event pipe gc continuously""" while True: await asyncio.sleep(self._event_pipe_gc_seconds) @@ -200,7 +200,7 @@ async def _run_event_pipe_gc(self): except Exception as e: print(f"Exception in IOPubThread._event_pipe_gc: {e}", file=sys.__stderr__) - async def _event_pipe_gc(self): + async def _event_pipe_gc(self) -> None: """run a single garbage collection on event pipes""" if not self._event_pipes: # don't acquire the lock if there's nothing to do @@ -230,7 +230,7 @@ def _event_pipe(self): self._event_pipes[threading.current_thread()] = event_pipe return event_pipe - def _handle_event(self, msg): + def _handle_event(self, msg) -> None: """Handle an event on the event pipe Content of the message is ignored. @@ -245,7 +245,7 @@ def _handle_event(self, msg): event_f = self._events.popleft() event_f() - def _setup_pipe_in(self): + def _setup_pipe_in(self) -> None: """setup listening pipe for IOPub from forked subprocesses""" ctx = self.socket.context @@ -269,7 +269,7 @@ def _setup_pipe_in(self): self._pipe_in = ZMQStream(pipe_in, self.io_loop) self._pipe_in.on_recv(self._handle_pipe_msg) - def _handle_pipe_msg(self, msg): + def _handle_pipe_msg(self, msg) -> None: """handle a pipe message from a subprocess""" if not self._pipe_flag or not self._is_master_process(): return @@ -295,7 +295,7 @@ def _check_mp_mode(self): return MASTER return CHILD - def start(self): + def start(self) -> None: """Start the IOPub thread""" self.thread.name = "IOPub" self.thread.start() @@ -321,7 +321,7 @@ def stop(self): for event_pipe in self._event_pipes.values(): event_pipe.close() - def close(self): + def close(self) -> None: """Close the IOPub thread.""" if self.closed: return @@ -329,10 +329,10 @@ def close(self): self.socket = None @property - def closed(self): + def closed(self) -> bool: return self.socket is None - def schedule(self, f): + def schedule(self, f) -> None: """Schedule a function to be called in our IO thread. If the thread is not running, call immediately. @@ -344,7 +344,7 @@ def schedule(self, f): else: f() - def send_multipart(self, *args, **kwargs): + def send_multipart(self, *args, **kwargs) -> None: """send_multipart schedules actual zmq send in my thread. If my thread isn't running (e.g. forked process), send immediately. @@ -388,7 +388,7 @@ class BackgroundSocket: io_thread = None - def __init__(self, io_thread): + def __init__(self, io_thread) -> None: """Initialize the socket.""" self.io_thread = io_thread @@ -409,7 +409,7 @@ def __getattr__(self, attr): return getattr(self.io_thread.socket, attr) return super().__getattr__(attr) # type:ignore[misc] - def __setattr__(self, attr, value): + def __setattr__(self, attr, value) -> None: """Set an attribute on the socket.""" if attr == "io_thread" or (attr.startswith("__") and attr.endswith("__")): super().__setattr__(attr, value) @@ -458,7 +458,7 @@ def fileno(self): msg = "fileno" raise io.UnsupportedOperation(msg) - def _watch_pipe_fd(self): + def _watch_pipe_fd(self) -> None: """ We've redirected standards streams 0 and 1 into a pipe. @@ -493,7 +493,7 @@ def __init__( *, watchfd=True, isatty=False, - ): + ) -> None: """ Parameters ---------- @@ -604,7 +604,7 @@ def parent_header(self): return self._parent_header_global @parent_header.setter - def parent_header(self, value): + def parent_header(self, value) -> None: self._parent_header.set(value) self._parent_header_global = value @@ -616,7 +616,7 @@ def isatty(self): """ return self._isatty - def _setup_stream_redirects(self, name): + def _setup_stream_redirects(self, name) -> None: pr, pw = os.pipe() fno = self._original_stdstream_fd = getattr(sys, name).fileno() self._original_stdstream_copy = os.dup(fno) @@ -636,15 +636,15 @@ def set_thread_parent(self, parent): """Set the parent header for the calling thread only. Returns a reset token that can be used with reset_thread_parent.""" return self._parent_header.set(extract_header(parent)) - def reset_thread_parent(self, token): + def reset_thread_parent(self, token) -> None: """Reset the parent header to undo the set_thread_parent call that returned the token.""" self._parent_header.reset(token) - def set_parent(self, parent): + def set_parent(self, parent) -> None: """Set the global and thread parent header.""" self.parent_header = extract_header(parent) - def close(self): + def close(self) -> None: """Close the stream.""" if self._should_watch: self._should_watch = False @@ -661,10 +661,10 @@ def close(self): self.pub_thread = None @property - def closed(self): + def closed(self) -> bool: return self.pub_thread is None - def _schedule_flush(self): + def _schedule_flush(self) -> None: """schedule a flush in the IO thread call this on write, to indicate that flush should be called soon. @@ -674,12 +674,12 @@ def _schedule_flush(self): self._flush_pending = True # add_timeout has to be handed to the io thread via event pipe - def _schedule_in_thread(): + def _schedule_in_thread() -> None: self._io_loop.call_later(self.flush_interval, self._flush) self.pub_thread.schedule(_schedule_in_thread) - def flush(self): + def flush(self) -> None: """trigger actual zmq send send will happen in the background thread @@ -703,7 +703,7 @@ def flush(self): else: self._flush() - def _flush(self): + def _flush(self) -> None: """This is where the actual send happens. _flush should generally be called in the IO thread, @@ -793,7 +793,7 @@ def writelines(self, sequence): for string in sequence: self.write(string) - def writable(self): + def writable(self) -> bool: """Test whether the stream is writable.""" return True @@ -819,7 +819,7 @@ def _hooks(self): self._local.hooks = [] return self._local.hooks - def register_hook(self, hook): + def register_hook(self, hook) -> None: """ Registers a hook with the thread-local storage. @@ -838,7 +838,7 @@ def register_hook(self, hook): """ self._hooks.append(hook) - def unregister_hook(self, hook): + def unregister_hook(self, hook) -> bool: """ Un-registers a hook with the thread-local storage. diff --git a/ipykernel/ipkernel.py b/ipykernel/ipkernel.py index 71b387fab..936b71043 100644 --- a/ipykernel/ipkernel.py +++ b/ipykernel/ipkernel.py @@ -91,7 +91,7 @@ class IPythonKernel(KernelBase): @observe("user_module") @observe_compat - def _user_module_changed(self, change): + def _user_module_changed(self, change) -> None: if self.shell is not None: self.shell.user_module = change["new"] @@ -103,7 +103,7 @@ def _default_user_ns(self): @observe("user_ns") @observe_compat - def _user_ns_changed(self, change): + def _user_ns_changed(self, change) -> None: if self.shell is not None: self.shell.user_ns = change["new"] self.shell.init_user_ns() @@ -113,7 +113,7 @@ def _user_ns_changed(self, change): _sys_raw_input = Any() _sys_eval_input = Any() - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: """Initialize the kernel.""" super().__init__(**kwargs) @@ -216,7 +216,7 @@ def __init__(self, **kwargs): "file_extension": ".py", } - def dispatch_debugpy(self, msg): + def dispatch_debugpy(self, msg) -> None: from .debugger import _is_debugpy_available if _is_debugpy_available: @@ -231,12 +231,12 @@ def banner(self): # type:ignore[override] return self.shell.banner return None - async def poll_stopped_queue(self): + async def poll_stopped_queue(self) -> None: """Poll the stopped queue.""" while True: await self.debugger.handle_stopped_event() - def start(self): + def start(self) -> None: """Start the kernel.""" if self.shell: self.shell.exit_now = False @@ -250,7 +250,7 @@ def start(self): self.poll_stopped_queue(), self.control_thread.io_loop.asyncio_loop ) - def set_parent(self, ident, parent, channel="shell"): + def set_parent(self, ident, parent, channel="shell") -> None: """Overridden from parent to tell the display hook and output streams about the parent message. """ @@ -287,7 +287,7 @@ def finish_metadata(self, parent, metadata, reply_content): return metadata - def _forward_input(self, allow_stdin=False): + def _forward_input(self, allow_stdin=False) -> None: """Forward raw_input and getpass to the current frontend. via input_request @@ -300,7 +300,7 @@ def _forward_input(self, allow_stdin=False): self._save_getpass = getpass.getpass getpass.getpass = self.getpass - def _restore_input(self): + def _restore_input(self) -> None: """Restore raw_input, getpass""" builtins.input = self._sys_raw_input @@ -313,7 +313,7 @@ def execution_count(self): return None @execution_count.setter - def execution_count(self, value): + def execution_count(self, value) -> None: # Ignore the incrementing done by KernelBase, in favour of our shell's # execution counter. pass @@ -333,7 +333,7 @@ def _cancel_on_sigint(self, future): # whichever future finishes first, # cancel the other one - def cancel_unless_done(f, _ignored): + def cancel_unless_done(f, _ignored) -> None: if f.cancelled() or f.done(): return f.cancel() @@ -345,8 +345,8 @@ def cancel_unless_done(f, _ignored): # stop watching for SIGINT events future.add_done_callback(partial(cancel_unless_done, sigint_future)) - def handle_sigint(*args): - def set_sigint_result(): + def handle_sigint(*args) -> None: + def set_sigint_result() -> None: if sigint_future.cancelled() or sigint_future.done(): return sigint_future.set_result(1) @@ -367,7 +367,7 @@ def _dummy_context_manager(self, *args): # Signals only work in main thread, so cannot use _cancel_on_sigint in subshells. yield - async def execute_request(self, stream, ident, parent): + async def execute_request(self, stream, ident, parent) -> None: """Override for cell output - cell reconciliation.""" await super().execute_request(stream, ident, parent) @@ -743,7 +743,7 @@ def do_clear(self): class Kernel(IPythonKernel): """DEPRECATED. An alias for the IPython kernel class.""" - def __init__(self, *args, **kwargs): # pragma: no cover + def __init__(self, *args, **kwargs) -> None: # pragma: no cover """DEPRECATED.""" import warnings diff --git a/ipykernel/kernelapp.py b/ipykernel/kernelapp.py index 1c36022e1..12abc3bda 100644 --- a/ipykernel/kernelapp.py +++ b/ipykernel/kernelapp.py @@ -208,11 +208,11 @@ def abs_connection_file(self): """, ).tag(config=True) - def init_crash_handler(self): + def init_crash_handler(self) -> None: """Initialize the crash handler.""" sys.excepthook = self.excepthook - def excepthook(self, etype, evalue, tb): + def excepthook(self, etype, evalue, tb) -> None: """Handle an exception.""" # write uncaught traceback to 'real' stderr, not zmq-forwarder traceback.print_exception(etype, evalue, tb, file=sys.__stderr__) @@ -236,7 +236,7 @@ def _apply_curve_client_options(self, socket: zmq.Socket[t.Any]) -> None: socket.curve_secretkey = self.curve_secretkey socket.curve_publickey = self.curve_publickey - def init_poller(self): + def init_poller(self) -> None: """Initialize the poller.""" if sys.platform == "win32": if self.interrupt or self.parent_handle: @@ -317,7 +317,7 @@ def write_connection_file(self, **kwargs: Any) -> None: write_connection_file(cf, **connection_info) - def cleanup_connection_file(self): + def cleanup_connection_file(self) -> None: """Clean up our connection file.""" cf = self.abs_connection_file self.log.debug("Cleaning up connection file: %s", cf) @@ -328,7 +328,7 @@ def cleanup_connection_file(self): self.cleanup_ipc_files() - def init_connection_file(self): + def init_connection_file(self) -> None: """Initialize our connection file.""" if not self.connection_file: self.connection_file = "kernel-%s.json" % os.getpid() @@ -349,7 +349,7 @@ def init_connection_file(self): ) self.exit(1) - def init_sockets(self): + def init_sockets(self) -> None: """Create a context, a session, and the kernel sockets.""" self.log.info("Starting the kernel at pid: %i", os.getpid()) assert self.context is None, "init_sockets cannot be called twice!" @@ -388,7 +388,7 @@ def init_sockets(self): self.init_control(context) self.init_iopub(context) - def init_control(self, context): + def init_control(self, context) -> None: """Initialize the control channel.""" self.control_socket = context.socket(zmq.ROUTER) self.control_socket.linger = 1000 @@ -414,7 +414,7 @@ def init_control(self, context): self.control_thread = ControlThread(daemon=True) self.shell_channel_thread = ShellChannelThread(context, daemon=True) - def init_iopub(self, context): + def init_iopub(self, context) -> None: """Initialize the iopub channel.""" self.iopub_socket = context.socket(zmq.XPUB) self.iopub_socket.linger = 1000 @@ -427,7 +427,7 @@ def init_iopub(self, context): # backward-compat: wrap iopub socket API in background thread self.iopub_socket = self.iopub_thread.background_socket - def init_heartbeat(self): + def init_heartbeat(self) -> None: """start the heart beating""" # heartbeat doesn't share context, because it mustn't be blocked # by the GIL, which is accessed by libzmq when freeing zero-copy messages @@ -442,7 +442,7 @@ def init_heartbeat(self): self.log.debug("Heartbeat REP Channel on port: %i", self.hb_port) self.heartbeat.start() - def close(self): + def close(self) -> None: """Close zmq sockets in an orderly fashion""" # un-capture IO before we start closing channels self.reset_io() @@ -478,7 +478,7 @@ def close(self): self.context.term() self.log.debug("Terminated zmq context") - def log_connection_info(self): + def log_connection_info(self) -> None: """display connection info, and store ports""" basename = Path(self.connection_file).name if ( @@ -514,7 +514,7 @@ def log_connection_info(self): control=self.control_port, ) - def init_blackhole(self): + def init_blackhole(self) -> None: """redirects stdout/stderr to devnull if necessary""" if self.no_stdout or self.no_stderr: blackhole = open(os.devnull, "w") # noqa: SIM115 @@ -523,7 +523,7 @@ def init_blackhole(self): if self.no_stderr: sys.stderr = sys.__stderr__ = blackhole # type:ignore[misc] - def init_io(self): + def init_io(self) -> None: """Redirect input streams and set a display hook.""" if self.outstream_class: outstream_factory = import_item(str(self.outstream_class)) @@ -558,7 +558,7 @@ def init_io(self): self.patch_io() - def reset_io(self): + def reset_io(self) -> None: """restore original io restores state after init_io @@ -567,7 +567,7 @@ def reset_io(self): sys.stderr = sys.__stderr__ sys.displayhook = sys.__displayhook__ - def patch_io(self): + def patch_io(self) -> None: """Patch important libraries that can't handle sys.stdout forwarding""" try: import faulthandler @@ -596,11 +596,11 @@ def register(signum, file=sys.__stderr__, all_threads=True, chain=False, **kwarg faulthandler.register = register - def init_signal(self): + def init_signal(self) -> None: """Initialize the signal handler.""" signal.signal(signal.SIGINT, signal.SIG_IGN) - def init_kernel(self): + def init_kernel(self) -> None: """Create the Kernel object itself""" if self.shell_channel_thread: shell_stream = ZMQStream(self.shell_socket, self.shell_channel_thread.io_loop) @@ -640,7 +640,7 @@ def init_kernel(self): # Allow the displayhook to get the execution count self.displayhook.get_execution_count = lambda: kernel.execution_count - def init_gui_pylab(self): + def init_gui_pylab(self) -> None: """Enable GUI event loop integration, taking pylab into account.""" # Register inline backend as default @@ -661,7 +661,7 @@ def init_gui_pylab(self): _showtraceback = shell._showtraceback try: # replace error-sending traceback with stderr - def print_tb(etype, evalue, stb): + def print_tb(etype, evalue, stb) -> None: print("GUI event loop or pylab initialization failed", file=sys.stderr) assert shell is not None print(shell.InteractiveTB.stb2text(stb), file=sys.stderr) @@ -671,13 +671,13 @@ def print_tb(etype, evalue, stb): finally: shell._showtraceback = _showtraceback - def init_shell(self): + def init_shell(self) -> None: """Initialize the shell channel.""" self.shell = getattr(self.kernel, "shell", None) if self.shell: self.shell.configurables.append(self) - def configure_tornado_logger(self): + def configure_tornado_logger(self) -> None: """Configure the tornado logging.Logger. Must set up the tornado logger or else tornado will call @@ -691,7 +691,7 @@ def configure_tornado_logger(self): handler.setFormatter(formatter) logger.addHandler(handler) - def init_pdb(self): + def init_pdb(self) -> None: """Replace pdb with IPython's version that is interruptible. With the non-interruptible version, stopping pdb() locks up the kernel in a @@ -708,7 +708,7 @@ def init_pdb(self): pdb.set_trace = debugger.set_trace @catch_config_error - def initialize(self, argv=None): + def initialize(self, argv=None) -> None: """Initialize the application.""" super().initialize(argv) if self.subapp is not None: @@ -773,7 +773,7 @@ def start(self): launch_new_instance = IPKernelApp.launch_instance -def main(): # pragma: no cover +def main() -> None: # pragma: no cover """Run an IPKernel as an application""" app = IPKernelApp.instance() app.initialize() diff --git a/ipykernel/kernelbase.py b/ipykernel/kernelbase.py index 7460cbce0..a5fea8435 100644 --- a/ipykernel/kernelbase.py +++ b/ipykernel/kernelbase.py @@ -123,7 +123,7 @@ class Kernel(SingletonConfigurable): processes: dict[int, t.Any] = {} @observe("eventloop") - def _update_eventloop(self, change): + def _update_eventloop(self, change) -> None: """schedule call to eventloop from IOLoop""" loop = ioloop.IOLoop.current() if change.new is not None: @@ -157,7 +157,7 @@ def _shell_streams_default(self): # pragma: no cover return [] @observe("shell_streams") - def _shell_streams_changed(self, change): # pragma: no cover + def _shell_streams_changed(self, change) -> None: # pragma: no cover warnings.warn( "Kernel.shell_streams is deprecated in ipykernel 6.0. Use Kernel.shell_stream", DeprecationWarning, @@ -320,7 +320,7 @@ def _parent_header(self): "list_subshell_request", ] - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: """Initialize the kernel.""" super().__init__(**kwargs) @@ -364,13 +364,13 @@ def __init__(self, **kwargs): self._main_asyncio_lock = asyncio.Lock() - async def dispatch_control(self, msg): + async def dispatch_control(self, msg) -> None: """Dispatch a control request, ensuring only one message is processed at a time.""" # Ensure only one control message is processed at a time async with self._control_lock: await self.process_control(msg) - async def process_control(self, msg): + async def process_control(self, msg) -> None: """dispatch control requests""" if not self.session: return @@ -407,7 +407,7 @@ async def process_control(self, msg): sys.stderr.flush() self._publish_status_and_flush("idle", "control", self.control_stream) - def should_handle(self, stream, msg, idents): + def should_handle(self, stream, msg, idents) -> bool: """Check whether a shell-channel message should be handled Allows subclasses to prevent handling of certain messages (e.g. aborted requests). @@ -418,7 +418,7 @@ def should_handle(self, stream, msg, idents): """ return True - async def dispatch_shell(self, msg, /, subshell_id: str | None = None): + async def dispatch_shell(self, msg, /, subshell_id: str | None = None) -> None: """dispatch shell requests""" if len(msg) == 1 and msg[0].buffer == b"stop aborting": # Dummy "stop aborting" message to stop aborting execute requests on this subshell. @@ -516,16 +516,16 @@ async def dispatch_shell(self, msg, /, subshell_id: str | None = None): sys.stderr.flush() self._publish_status_and_flush("idle", "shell", stream) - def pre_handler_hook(self): + def pre_handler_hook(self) -> None: """Hook to execute before calling message handler""" # ensure default_int_handler during handler call self.saved_sigint_handler = signal(SIGINT, default_int_handler) - def post_handler_hook(self): + def post_handler_hook(self) -> None: """Hook to execute after calling message handler""" signal(SIGINT, self.saved_sigint_handler) - def enter_eventloop(self): + def enter_eventloop(self) -> None: """enter eventloop""" self.log.info("Entering eventloop %s", self.eventloop) # record handle, so we can check when this changes @@ -534,7 +534,7 @@ def enter_eventloop(self): self.log.info("Exiting as there is no eventloop") return - async def advance_eventloop(): + async def advance_eventloop() -> None: # check if eventloop changed: if self.eventloop is not eventloop: self.log.info("exiting eventloop %s", eventloop) @@ -549,7 +549,7 @@ async def advance_eventloop(): # schedule advance again schedule_next() - def schedule_next(): + def schedule_next() -> None: """Schedule the next advance of the eventloop""" # call_later allows the io_loop to process other events if needed. # Going through schedule_dispatch ensures all other dispatches on msg_queue @@ -562,7 +562,7 @@ def schedule_next(): # begin polling the eventloop schedule_next() - def start(self): + def start(self) -> None: """register dispatchers for streams""" self.io_loop = ioloop.IOLoop.current() @@ -584,7 +584,7 @@ def start(self): # publish idle status self._publish_status("starting", "shell") - async def shell_channel_thread_main(self, msg): + async def shell_channel_thread_main(self, msg) -> None: """Handler for shell messages received on shell_channel_thread""" assert threading.current_thread() == self.shell_channel_thread @@ -607,7 +607,7 @@ async def shell_channel_thread_main(self, msg): except Exception: self.log.error("Invalid message", exc_info=True) # noqa: G201 - async def shell_main(self, subshell_id: str | None, msg): + async def shell_main(self, subshell_id: str | None, msg) -> None: """Handler of shell messages for a single subshell""" if self._supports_kernel_subshells: if subshell_id is None: @@ -633,7 +633,7 @@ async def shell_main(self, subshell_id: str | None, msg): async with asyncio_lock: await self.dispatch_shell(msg, subshell_id=subshell_id) - def record_ports(self, ports): + def record_ports(self, ports) -> None: """Record the ports that this kernel is using. The creator of the Kernel instance must call this methods if they @@ -645,7 +645,7 @@ def record_ports(self, ports): # Kernel request handlers # --------------------------------------------------------------------------- - def _publish_execute_input(self, code, parent, execution_count): + def _publish_execute_input(self, code, parent, execution_count) -> None: """Publish the code request on the iopub stream.""" if not self.session: return @@ -657,7 +657,7 @@ def _publish_execute_input(self, code, parent, execution_count): ident=self._topic("execute_input"), ) - def _publish_status(self, status, channel, parent=None): + def _publish_status(self, status, channel, parent=None) -> None: """send status (busy/idle) on IOPub""" if not self.session: return @@ -669,13 +669,13 @@ def _publish_status(self, status, channel, parent=None): ident=self._topic("status"), ) - def _publish_status_and_flush(self, status, channel, stream, parent=None): + def _publish_status_and_flush(self, status, channel, stream, parent=None) -> None: """send status on IOPub and flush specified stream to ensure reply is sent before handling the next reply""" self._publish_status(status, channel, parent) if stream and hasattr(stream, "flush") and not self._supports_kernel_subshells: stream.flush(zmq.POLLOUT) - def _publish_debug_event(self, event): + def _publish_debug_event(self, event) -> None: if not self.session: return self.session.send( @@ -686,7 +686,7 @@ def _publish_debug_event(self, event): ident=self._topic("debug_event"), ) - def set_parent(self, ident, parent, channel="shell"): + def set_parent(self, ident, parent, channel="shell") -> None: """Set the current parent request Side effects (IOPub messages) and replies are associated with @@ -796,7 +796,7 @@ def finish_metadata(self, parent, metadata, reply_content): """ return metadata - async def execute_request(self, stream, ident, parent): + async def execute_request(self, stream, ident, parent) -> None: """handle an execute_request""" if not self.session: return @@ -896,7 +896,7 @@ async def do_execute( """Execute user code. Must be overridden by subclasses.""" raise NotImplementedError - async def complete_request(self, stream, ident, parent): + async def complete_request(self, stream, ident, parent) -> None: """Handle a completion request.""" if not self.session: return @@ -927,7 +927,7 @@ async def do_complete(self, code, cursor_pos): "status": "ok", } - async def inspect_request(self, stream, ident, parent): + async def inspect_request(self, stream, ident, parent) -> None: """Handle an inspect request.""" if not self.session: return @@ -957,7 +957,7 @@ async def do_inspect(self, code, cursor_pos, detail_level=0, omit_sections=()): """Override in subclasses to allow introspection.""" return {"status": "ok", "data": {}, "metadata": {}, "found": False} - async def history_request(self, stream, ident, parent): + async def history_request(self, stream, ident, parent) -> None: """Handle a history request.""" if not self.session: return @@ -992,7 +992,7 @@ async def do_history( """Override in subclasses to access history.""" return {"status": "ok", "history": []} - async def connect_request(self, stream, ident, parent): + async def connect_request(self, stream, ident, parent) -> None: """Handle a connect request.""" if not self.session: return @@ -1021,7 +1021,7 @@ def kernel_info(self): "supported_features": supported_features, } - async def kernel_info_request(self, stream, ident, parent): + async def kernel_info_request(self, stream, ident, parent) -> None: """Handle a kernel info request.""" if not self.session: return @@ -1030,7 +1030,7 @@ async def kernel_info_request(self, stream, ident, parent): msg = self.session.send(stream, "kernel_info_reply", content, parent, ident) self.log.debug("%s", msg) - async def comm_info_request(self, stream, ident, parent): + async def comm_info_request(self, stream, ident, parent) -> None: """Handle a comm info request.""" if not self.session: return @@ -1067,7 +1067,7 @@ def _send_interrupt_children(self): else: os.kill(pid, SIGINT) - async def interrupt_request(self, stream, ident, parent): + async def interrupt_request(self, stream, ident, parent) -> None: """Handle an interrupt request.""" if not self.session: return @@ -1087,7 +1087,7 @@ async def interrupt_request(self, stream, ident, parent): self.session.send(stream, "interrupt_reply", content, parent, ident=ident) return - async def shutdown_request(self, stream, ident, parent): + async def shutdown_request(self, stream, ident, parent) -> None: """Handle a shutdown request.""" if not self.session: return @@ -1123,7 +1123,7 @@ async def do_shutdown(self, restart): """ return {"status": "ok", "restart": restart} - async def is_complete_request(self, stream, ident, parent): + async def is_complete_request(self, stream, ident, parent) -> None: """Handle an is_complete request.""" if not self.session: return @@ -1147,7 +1147,7 @@ async def do_is_complete(self, code): """Override in subclasses to find completions.""" return {"status": "unknown"} - async def debug_request(self, stream, ident, parent): + async def debug_request(self, stream, ident, parent) -> None: """Handle a debug request.""" if not self.session: return @@ -1180,7 +1180,7 @@ def get_process_metric_value(self, process, name, attribute=None): except BaseException: return 0 - async def usage_request(self, stream, ident, parent): + async def usage_request(self, stream, ident, parent) -> None: """Handle a usage request.""" if not self.session: return @@ -1317,7 +1317,7 @@ def _post_dummy_stop_aborting_message(self, subshell_id: str | None) -> None: msg = b"stop aborting" # Magic string for dummy message. socket.send(msg, copy=False) - def _abort_queues(self, subshell_id: str | None = None): + def _abort_queues(self, subshell_id: str | None = None) -> None: # while this flag is true, # execute requests will be aborted @@ -1341,7 +1341,7 @@ def _abort_queues(self, subshell_id: str | None = None): # Callback to signal that we are done aborting # dispatch functions _must_ be async - async def stop_aborting(): + async def stop_aborting() -> None: self.log.info("Finishing abort") self._aborting = False @@ -1358,7 +1358,7 @@ async def stop_aborting(): else: self.io_loop.add_callback(stop_aborting) - def _send_abort_reply(self, stream, msg, idents): + def _send_abort_reply(self, stream, msg, idents) -> None: """Send a reply to an aborted request""" if not self.session: return @@ -1490,7 +1490,7 @@ def _input_request(self, prompt, ident, parent, password=False) -> str: raise EOFError return value - def _signal_children(self, signum): + def _signal_children(self, signum) -> None: """ Send a signal to all our children @@ -1537,7 +1537,7 @@ def _process_children(self): process_group_children.append(child) return process_group_children - async def _progressively_terminate_all_children(self): + async def _progressively_terminate_all_children(self) -> None: sleeps = (0.01, 0.03, 0.1, 0.3, 1, 3, 10) if not self._process_children(): self.log.debug("Kernel has no children.") @@ -1558,7 +1558,7 @@ async def _progressively_terminate_all_children(self): ) await asyncio.sleep(delay) - async def _at_shutdown(self): + async def _at_shutdown(self) -> None: """Actions taken at shutdown by the kernel, called by python's atexit.""" try: await self._progressively_terminate_all_children() @@ -1577,5 +1577,5 @@ async def _at_shutdown(self): self.control_stream.flush(zmq.POLLOUT) @property - def _supports_kernel_subshells(self): + def _supports_kernel_subshells(self) -> bool: return self.shell_channel_thread is not None diff --git a/ipykernel/log.py b/ipykernel/log.py index c230065e8..fac53e3aa 100644 --- a/ipykernel/log.py +++ b/ipykernel/log.py @@ -16,13 +16,13 @@ class EnginePUBHandler(PUBHandler): engine = None - def __init__(self, engine, *args, **kwargs): + def __init__(self, engine, *args, **kwargs) -> None: """Initialize the handler.""" PUBHandler.__init__(self, *args, **kwargs) self.engine = engine @property # type:ignore[misc] - def root_topic(self): + def root_topic(self) -> str: """this is a property, in case the handler is created before the engine gets registered with an id""" if isinstance(getattr(self.engine, "id", None), int): diff --git a/ipykernel/parentpoller.py b/ipykernel/parentpoller.py index 941e8d12b..cad7e6fb2 100644 --- a/ipykernel/parentpoller.py +++ b/ipykernel/parentpoller.py @@ -22,7 +22,7 @@ class ParentPollerUnix(Thread): when the parent process no longer exists. """ - def __init__(self, parent_pid=0): + def __init__(self, parent_pid=0) -> None: """Initialize the poller. Parameters @@ -72,7 +72,7 @@ class ParentPollerWindows(Thread): when the parent process no longer exists. """ - def __init__(self, interrupt_handle=None, parent_handle=None): + def __init__(self, interrupt_handle=None, parent_handle=None) -> None: """Create the poller. At least one of the optional parameters must be provided. @@ -94,7 +94,7 @@ def __init__(self, interrupt_handle=None, parent_handle=None): self.interrupt_handle = interrupt_handle self.parent_handle = parent_handle - def run(self): + def run(self) -> None: """Run the poll loop. This method never returns.""" try: from _winapi import INFINITE, WAIT_OBJECT_0 # type:ignore[attr-defined] diff --git a/ipykernel/shellchannel.py b/ipykernel/shellchannel.py index ff2cdee6e..f188d5e31 100644 --- a/ipykernel/shellchannel.py +++ b/ipykernel/shellchannel.py @@ -23,7 +23,7 @@ def __init__( self, context: zmq.Context[Any], **kwargs, - ): + ) -> None: """Initialize the thread.""" super().__init__(name=SHELL_CHANNEL_THREAD_NAME, **kwargs) self._manager: SubshellManager | None = None diff --git a/ipykernel/socket_pair.py b/ipykernel/socket_pair.py index f31dd3b92..d70981b89 100644 --- a/ipykernel/socket_pair.py +++ b/ipykernel/socket_pair.py @@ -22,7 +22,7 @@ class SocketPair: to_socket: zmq.Socket[Any] to_stream: ZMQStream | None = None - def __init__(self, context: zmq.Context[Any], name: str): + def __init__(self, context: zmq.Context[Any], name: str) -> None: """Initialize the inproc socker pair.""" self.from_socket = context.socket(zmq.PAIR) self.to_socket = context.socket(zmq.PAIR) @@ -30,7 +30,7 @@ def __init__(self, context: zmq.Context[Any], name: str): self.from_socket.bind(address) self.to_socket.connect(address) # Or do I need to do this in another thread? - def close(self): + def close(self) -> None: """Close the inproc socker pair.""" self.from_socket.close() @@ -38,7 +38,7 @@ def close(self): self.to_stream.close() self.to_socket.close() - def on_recv(self, io_loop: IOLoop, on_recv_callback, copy: bool = False): + def on_recv(self, io_loop: IOLoop, on_recv_callback, copy: bool = False) -> None: """Set the callback used when a message is received on the to stream.""" # io_loop is that of the 'to' thread. if self.to_stream is None: diff --git a/ipykernel/subshell.py b/ipykernel/subshell.py index ec1c7cc88..466b0330f 100644 --- a/ipykernel/subshell.py +++ b/ipykernel/subshell.py @@ -20,7 +20,7 @@ def __init__( subshell_id: str, context: zmq.Context[Any], **kwargs, - ): + ) -> None: """Initialize the thread.""" super().__init__(name=f"subshell-{subshell_id}", **kwargs) diff --git a/ipykernel/subshell_manager.py b/ipykernel/subshell_manager.py index 1f23085ae..d907c4d59 100644 --- a/ipykernel/subshell_manager.py +++ b/ipykernel/subshell_manager.py @@ -41,7 +41,7 @@ def __init__( context: zmq.Context[t.Any], shell_channel_io_loop: IOLoop, shell_stream: ZMQStream, - ): + ) -> None: """Initialize the subshell manager.""" self._parent_thread = current_thread() @@ -128,7 +128,7 @@ def list_subshell(self) -> list[str]: with self._lock_cache: return list(self._cache) - def set_on_recv_callback(self, on_recv_callback): + def set_on_recv_callback(self, on_recv_callback) -> None: """Set the callback used by the main shell and all subshells to receive messages sent from the shell channel thread. """ diff --git a/ipykernel/thread.py b/ipykernel/thread.py index 283ba9175..f7687dcbd 100644 --- a/ipykernel/thread.py +++ b/ipykernel/thread.py @@ -35,7 +35,7 @@ def make_selector_io_loop() -> IOLoop: class BaseThread(Thread): """Base class for threads.""" - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: """Initialize the thread.""" super().__init__(**kwargs) self.io_loop = make_selector_io_loop() diff --git a/ipykernel/trio_runner.py b/ipykernel/trio_runner.py index fefd73034..6f54fb9f0 100644 --- a/ipykernel/trio_runner.py +++ b/ipykernel/trio_runner.py @@ -13,12 +13,12 @@ class TrioRunner: """A trio loop runner.""" - def __init__(self): + def __init__(self) -> None: """Initialize the runner.""" self._cell_cancel_scope = None self._trio_token = None - def initialize(self, kernel, io_loop): + def initialize(self, kernel, io_loop) -> None: """Initialize the runner.""" kernel.shell.set_trio_runner(self) kernel.shell.run_line_magic("autoawait", "trio") @@ -37,15 +37,15 @@ def interrupt(self, signum, frame): msg = "Kernel interrupted but no cell is running" raise Exception(msg) # noqa: TRY002 - def run(self): + def run(self) -> None: """Run the loop.""" old_sig = signal.signal(signal.SIGINT, self.interrupt) - def log_nursery_exc(exc): + def log_nursery_exc(exc) -> None: exc = "\n".join(traceback.format_exception(type(exc), exc, exc.__traceback__)) logging.error("An exception occurred in a global nursery task.\n%s", exc) # noqa: LOG015 - async def trio_main(): + async def trio_main() -> None: """Run the main loop.""" self._trio_token = trio.lowlevel.current_trio_token() async with trio.open_nursery() as nursery: diff --git a/ipykernel/utils.py b/ipykernel/utils.py index ab7006161..3fcc4e16e 100644 --- a/ipykernel/utils.py +++ b/ipykernel/utils.py @@ -21,14 +21,14 @@ class LazyDict(Mapping[str, t.Any]): read. """ - def __init__(self, dict): + def __init__(self, dict) -> None: self._dict = dict def __getitem__(self, key): item = self._dict.get(key) return item() if callable(item) else item - def __len__(self): + def __len__(self) -> int: return len(self._dict) def __iter__(self): diff --git a/ipykernel/zmqshell.py b/ipykernel/zmqshell.py index dd5216246..3b0f633b1 100644 --- a/ipykernel/zmqshell.py +++ b/ipykernel/zmqshell.py @@ -70,7 +70,7 @@ class ZMQDisplayPublisher(DisplayPublisher): # is processed. See ipykernel Issue 113 for a discussion. _thread_local = Any() - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self._parent_header = contextvars.ContextVar("parent_header") self._parent_header.set({}) @@ -84,7 +84,7 @@ def parent_header(self): return self._parent_header_global @parent_header.setter - def parent_header(self, value): + def parent_header(self, value) -> None: self._parent_header.set(value) self._parent_header_global = value @@ -92,15 +92,15 @@ def set_thread_parent(self, parent): """Set the parent header for the calling thread only. Returns a reset token that can be used with reset_thread_parent.""" return self._parent_header.set(extract_header(parent)) - def reset_thread_parent(self, token): + def reset_thread_parent(self, token) -> None: """Reset the parent header to undo the set_thread_parent call that returned the token.""" self._parent_header.reset(token) - def set_parent(self, parent): + def set_parent(self, parent) -> None: """Set the global and thread parent header.""" self.parent_header = extract_header(parent) - def _flush_streams(self): + def _flush_streams(self) -> None: """flush IO Streams prior to display""" sys.stdout.flush() sys.stderr.flush() @@ -127,7 +127,7 @@ def publish( # type:ignore[override] transient=None, update=False, **kwargs, - ): + ) -> None: """Publish a display-data message Parameters @@ -191,7 +191,7 @@ def publish( # type:ignore[override] ident=self.topic, ) - def clear_output(self, wait=False): + def clear_output(self, wait=False) -> None: """Clear output associated with the current execution (cell). Parameters @@ -219,7 +219,7 @@ def clear_output(self, wait=False): ident=self.topic, ) - def register_hook(self, hook): + def register_hook(self, hook) -> None: """ Registers a hook with the thread-local storage. @@ -238,7 +238,7 @@ def register_hook(self, hook): """ self._hooks.append(hook) - def unregister_hook(self, hook): + def unregister_hook(self, hook) -> bool: """ Un-registers a hook with the thread-local storage. @@ -272,7 +272,7 @@ class KernelMagics(Magics): # class, or that are unique to it. @line_magic - def edit(self, parameter_s="", last_call=None): + def edit(self, parameter_s="", last_call=None) -> None: """Bring up an editor and execute the resulting code. Usage: @@ -370,7 +370,7 @@ def edit(self, parameter_s="", last_call=None): # remote terminal @line_magic - def clear(self, arg_s): + def clear(self, arg_s) -> None: """Clear the terminal.""" assert self.shell is not None if os.name == "posix": @@ -407,13 +407,13 @@ def less(self, arg_s): if os.name == "posix": @line_magic - def man(self, arg_s): + def man(self, arg_s) -> None: """Find the man page for the given command and display in pager.""" assert self.shell is not None page.page(self.shell.getoutput("man %s | col -b" % arg_s, split=False)) @line_magic - def connect_info(self, arg_s): + def connect_info(self, arg_s) -> None: """Print information for connecting other clients to this kernel It will print the contents of this session's connection file, as well as @@ -450,7 +450,7 @@ def connect_info(self, arg_s): ) @line_magic - def qtconsole(self, arg_s): + def qtconsole(self, arg_s) -> None: """Open a qtconsole connected to this kernel. Useful for connecting a qtconsole to running notebooks, for better @@ -526,7 +526,7 @@ def subshell(self, arg_s): class ZMQInteractiveShell(InteractiveShell): """A subclass of InteractiveShell for ZMQ.""" - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) # Suppress Trio's signal handling warning on Windows with ProactorEventLoop @@ -576,7 +576,7 @@ def _default_exiter(self): return ZMQExitAutocall(self) @observe("exit_now") - def _update_exit_now(self, change): + def _update_exit_now(self, change) -> None: """stop eventloop when exit_now fires""" if change["new"]: if hasattr(self.kernel, "io_loop"): @@ -601,7 +601,7 @@ def enable_gui(self, gui: typing.Any = None) -> None: except ValueError as e: raise UsageError("%s" % e) from e - def init_environment(self): + def init_environment(self) -> None: """Configure the user's environment.""" env = os.environ # These two ensure 'ls' produces nice coloring on BSD-derived systems @@ -616,7 +616,7 @@ def init_environment(self): env["PAGER"] = "cat" env["GIT_PAGER"] = "cat" - def payloadpage_page(self, strg, start=0, screen_lines=0, pager_cmd=None): + def payloadpage_page(self, strg, start=0, screen_lines=0, pager_cmd=None) -> None: """Print a string, piping through a pager. This version ignores the screen_lines and pager_cmd arguments and uses @@ -644,12 +644,12 @@ def payloadpage_page(self, strg, start=0, screen_lines=0, pager_cmd=None): assert self.payload_manager is not None self.payload_manager.write_payload(payload) - def init_hooks(self): + def init_hooks(self) -> None: """Initialize hooks.""" super().init_hooks() self.set_hook("show_in_pager", page.as_hook(self.payloadpage_page), 99) - def init_data_pub(self): + def init_data_pub(self) -> None: """Delay datapub init until request, for deprecation warnings""" @property @@ -667,10 +667,10 @@ def data_pub(self): return self._data_pub @data_pub.setter - def data_pub(self, pub): + def data_pub(self, pub) -> None: self._data_pub = pub - def ask_exit(self): + def ask_exit(self) -> None: """Engage the exit actions.""" self.exit_now = not self.keepkernel_on_exit payload = dict( @@ -685,7 +685,7 @@ def run_cell(self, *args, **kwargs): self._last_traceback_during_displayhook = False return super().run_cell(*args, **kwargs) - def _showtraceback(self, etype, evalue, stb): + def _showtraceback(self, etype, evalue, stb) -> None: # try to preserve ordering of tracebacks and print statements sys.stdout.flush() sys.stderr.flush() @@ -719,7 +719,7 @@ def _showtraceback(self, etype, evalue, stb): # exception object, so we shouldn't need to store it here. self._last_traceback = stb - def set_next_input(self, text, replace=False): + def set_next_input(self, text, replace=False) -> None: """Send the specified text to the frontend to be presented at the next input cell.""" payload = dict( @@ -737,11 +737,11 @@ def parent_header(self): return self._parent_header_global @parent_header.setter - def parent_header(self, value): + def parent_header(self, value) -> None: self._parent_header.set(value) self._parent_header_global = value - def set_parent(self, parent): + def set_parent(self, parent) -> None: """Set the global and thread parent header for associating output with its triggering input.""" self.parent_header = parent self.displayhook.set_parent(parent) # type:ignore[attr-defined] @@ -775,18 +775,18 @@ def set_thread_parent(self, parent): tokens.append((reset_thread, set_thread(parent))) return tuple(tokens) - def reset_thread_parent(self, tokens): + def reset_thread_parent(self, tokens) -> None: """Reset the parent header to undo the set_thread_parent call that returned the token.""" for reset, token in reversed(tokens): reset(token) - def init_magics(self): + def init_magics(self) -> None: """Initialize magics.""" super().init_magics() self.register_magics(KernelMagics) self.magics_manager.register_alias("ed", "edit") - def init_virtualenv(self): + def init_virtualenv(self) -> None: """Initialize virtual environment.""" # Overridden not to do virtualenv detection, because it's probably # not appropriate in a kernel. To use a kernel in a virtualenv, install From 72e89d177fed389972fc6389205bd13a9ed05f76 Mon Sep 17 00:00:00 2001 From: M Bussonnier Date: Mon, 14 Sep 2026 13:44:27 +0200 Subject: [PATCH 2/2] Annotate the news items that are trigered by autotyping. And move most `__init__` declaration to class level + default value when immutable. --- ipykernel/debugger.py | 7 ++++++- ipykernel/displayhook.py | 6 +++++- ipykernel/gui/gtk3embed.py | 9 ++++++--- ipykernel/gui/gtkembed.py | 9 ++++++--- ipykernel/iostream.py | 7 ++++--- ipykernel/trio_runner.py | 6 ++---- ipykernel/zmqshell.py | 8 +++++--- pyproject.toml | 2 +- 8 files changed, 35 insertions(+), 19 deletions(-) diff --git a/ipykernel/debugger.py b/ipykernel/debugger.py index 781d8fece..0b568f8c8 100644 --- a/ipykernel/debugger.py +++ b/ipykernel/debugger.py @@ -81,12 +81,13 @@ def __init__(self) -> None: class VariableExplorer: """A variable explorer.""" + frame: _FakeFrame | None = None + def __init__(self) -> None: """Initialize the explorer.""" self.suspended_frame_manager = SuspendedFramesManager() self.py_db = _DummyPyDB() self.tracker = _FramesTracker(self.suspended_frame_manager, self.py_db) - self.frame = None def track(self) -> None: """Start tracking.""" @@ -307,6 +308,10 @@ async def send_dap_request(self, msg): class Debugger: """The debugger class.""" + breakpoint_list: dict[str, t.Any] + stopped_threads: set[int] + _removed_cleanup: dict[int, t.Any] + # Requests that requires that the debugger has started started_debug_msg_types = [ "dumpCell", diff --git a/ipykernel/displayhook.py b/ipykernel/displayhook.py index bfc469ec8..593a0cd7e 100644 --- a/ipykernel/displayhook.py +++ b/ipykernel/displayhook.py @@ -23,12 +23,15 @@ class ZMQDisplayHook: topic = b"execute_result" + _parent_header: ContextVar[dict[str, Any]] + _parent_header_global: dict[str, t.Any] + def __init__(self, session, pub_socket) -> None: """Initialize the hook.""" self.session = session self.pub_socket = pub_socket - self._parent_header: ContextVar[dict[str, Any]] = ContextVar("parent_header") + self._parent_header = ContextVar("parent_header") self._parent_header.set({}) self._parent_header_global = {} @@ -92,6 +95,7 @@ class ZMQShellDisplayHook(DisplayHook): session = Instance(Session, allow_none=True) pub_socket = Any(allow_none=True) _parent_header: ContextVar[dict[str, Any]] + _parent_header_global: dict[str, t.Any] _thread_local = Any() msg: dict[str, t.Any] | None diff --git a/ipykernel/gui/gtk3embed.py b/ipykernel/gui/gtk3embed.py index 94309b056..5d545cae2 100644 --- a/ipykernel/gui/gtk3embed.py +++ b/ipykernel/gui/gtk3embed.py @@ -12,6 +12,8 @@ # stdlib import sys import warnings +from collections.abc import Callable +from typing import Any # Third-party import gi @@ -32,12 +34,13 @@ class GTKEmbed: """A class to embed a kernel into the GTK main event loop.""" + # These two will later store the real gtk functions when we hijack them + gtk_main = None + gtk_main_quit: Callable[..., Any] | None = None + def __init__(self, kernel) -> None: """Initialize the embed.""" self.kernel = kernel - # These two will later store the real gtk functions when we hijack them - self.gtk_main = None - self.gtk_main_quit = None def start(self) -> None: """Starts the GTK main event loop and sets our kernel startup routine.""" diff --git a/ipykernel/gui/gtkembed.py b/ipykernel/gui/gtkembed.py index 23e6b4509..381784252 100644 --- a/ipykernel/gui/gtkembed.py +++ b/ipykernel/gui/gtkembed.py @@ -12,6 +12,8 @@ # stdlib import sys import warnings +from collections.abc import Callable +from typing import Any # Third-party import gobject @@ -29,12 +31,13 @@ class GTKEmbed: """A class to embed a kernel into the GTK main event loop.""" + # These two will later store the real gtk functions when we hijack them + gtk_main = None + gtk_main_quit: Callable[..., Any] | None = None + def __init__(self, kernel) -> None: """Initialize the embed.""" self.kernel = kernel - # These two will later store the real gtk functions when we hijack them - self.gtk_main = None - self.gtk_main_quit = None def start(self) -> None: """Starts the GTK main event loop and sets our kernel startup routine.""" diff --git a/ipykernel/iostream.py b/ipykernel/iostream.py index 52bba7ffa..bd21e157e 100644 --- a/ipykernel/iostream.py +++ b/ipykernel/iostream.py @@ -448,6 +448,9 @@ class OutStream(TextIOBase): topic = None encoding = "UTF-8" _exc: Any | None = None + _parent_header: contextvars.ContextVar[dict[str, Any]] + _parent_header_global: dict[str, Any] + _buffers: defaultdict[frozenset[tuple[str, Any]], StringIO] def fileno(self): """ @@ -539,9 +542,7 @@ def __init__( self.pub_thread = pub_thread self.name = name self.topic = b"stream." + name.encode() - self._parent_header: contextvars.ContextVar[dict[str, Any]] = contextvars.ContextVar( - "parent_header" - ) + self._parent_header = contextvars.ContextVar("parent_header") self._parent_header.set({}) self._parent_header_global = {} self._master_pid = os.getpid() diff --git a/ipykernel/trio_runner.py b/ipykernel/trio_runner.py index 6f54fb9f0..a71aec4a2 100644 --- a/ipykernel/trio_runner.py +++ b/ipykernel/trio_runner.py @@ -13,10 +13,8 @@ class TrioRunner: """A trio loop runner.""" - def __init__(self) -> None: - """Initialize the runner.""" - self._cell_cancel_scope = None - self._trio_token = None + _cell_cancel_scope: trio.CancelScope | None = None + _trio_token: trio.lowlevel.TrioToken | None = None def initialize(self, kernel, io_loop) -> None: """Initialize the runner.""" diff --git a/ipykernel/zmqshell.py b/ipykernel/zmqshell.py index 3b0f633b1..48b091f35 100644 --- a/ipykernel/zmqshell.py +++ b/ipykernel/zmqshell.py @@ -58,6 +58,7 @@ class ZMQDisplayPublisher(DisplayPublisher): session = Instance(Session, allow_none=True) pub_socket = Any(allow_none=True) _parent_header: contextvars.ContextVar[dict[str, Any]] + _parent_header_global: dict[str, Any] topic = CBytes(b"display_data") store_display_history = Bool( @@ -526,6 +527,9 @@ def subshell(self, arg_s): class ZMQInteractiveShell(InteractiveShell): """A subclass of InteractiveShell for ZMQ.""" + _parent_header: contextvars.ContextVar[dict[str, typing.Any]] + _parent_header_global: dict[str, typing.Any] + def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) @@ -546,9 +550,7 @@ def __init__(self, *args, **kwargs) -> None: if "IPKernelApp" not in self.config: self.config.IPKernelApp.tqdm = "dummy value for https://github.com/tqdm/tqdm/pull/1628" - self._parent_header: contextvars.ContextVar[dict[str, typing.Any]] = contextvars.ContextVar( - "parent_header" - ) + self._parent_header = contextvars.ContextVar("parent_header") self._parent_header.set({}) self._parent_header_global = {} diff --git a/pyproject.toml b/pyproject.toml index 8cbd12bbd..6b98c5603 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -128,7 +128,7 @@ build = [ [tool.mypy] files = "ipykernel" strict = true -disable_error_code = ["no-untyped-def", "no-untyped-call", "import-not-found"] +disable_error_code = ["no-untyped-def", "no-untyped-call", "import-not-found", "untyped-decorator"] enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"] follow_imports = "normal" pretty = true