Skip to content

Commit eeb87d1

Browse files
committed
cleanup code
1 parent 7aac75f commit eeb87d1

1 file changed

Lines changed: 40 additions & 42 deletions

File tree

ipykernel/ipkernel.py

Lines changed: 40 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ class IPythonKernel(KernelBase):
107107
# now costs nothing. See also the `debugger` property.
108108
debugger_class = LazyType("ipykernel.debugger.Debugger")
109109

110+
_debugger: Any | None = None
111+
_debugger_init_attempted: bool | None = None
112+
_stopped_queue_poll_started: bool = False
113+
110114
compiler_class = Type(XCachingCompiler)
111115

112116
use_experimental_completions = Bool(
@@ -150,18 +154,14 @@ def __init__(self, **kwargs):
150154
m.__file__ for m in sys.modules.copy().values() if hasattr(m, "__file__") and m.__file__
151155
]
152156

153-
# The debugger itself (and the debugpy import it requires) is
154-
# created lazily on first use, see the `debugger` property below.
155-
self._debugger = None
156-
self._debugger_init_attempted = False
157-
self._stopped_queue_poll_started = False
158-
159157
if "debugger_class" in self._trait_values:
160158
# Someone explicitly picked a debugger class, via kwargs or config.
161159
# The class is therefore already imported, so there is nothing left
162160
# to defer: build the debugger now, as pre-7.4 versions did. This
163161
# also keeps the failure mode of a bad `debugger_class` at
164162
# construction time rather than at the first debug request.
163+
# todo: maybe just delete that and move it to lazy at a future date
164+
# if we think is it ok
165165
_ = self.debugger
166166

167167
# Initialize the InteractiveShell subclass
@@ -251,44 +251,46 @@ def debugger(self):
251251
Importing debugpy is expensive, so we avoid it until a debug
252252
request actually comes in.
253253
"""
254-
if self._debugger is None and not self._debugger_init_attempted:
255-
from .debugger import _is_debugpy_available
254+
if self._debugger is not None or self._debugger_init_attempted:
255+
return self._debugger
256256

257-
if not _is_debugpy_available:
258-
# A module-level constant: it will not become True later, so
259-
# this is the one answer worth caching.
260-
self._debugger_init_attempted = True
261-
return None
257+
# keep lazy import because of side effects and slow import
258+
# or move to lazy import once python 3.15+
259+
from .debugger import _is_debugpy_available
262260

263-
debugger_class = self.debugger_class
264-
try:
265-
debugger = debugger_class(
266-
self.log,
267-
self.debugpy_stream,
268-
self._publish_debug_event,
269-
self.debug_shell_socket,
270-
self.session,
271-
self._kernel_modules,
272-
self.debug_just_my_code,
273-
self.filter_internal_frames,
274-
)
275-
except Exception:
276-
# Deliberately do not set `_debugger_init_attempted`: a
277-
# failure here must not silently turn every later debug
278-
# request into a `None` reply. Let it raise (so the request
279-
# gets a proper error reply) and retry next time.
280-
self.log.exception("Failed to initialize the debugger from %r", debugger_class)
281-
raise
282-
283-
self._debugger = debugger
261+
if not _is_debugpy_available:
262+
# A module-level constant: it will not become True later, so
263+
# this is the one answer worth caching.
284264
self._debugger_init_attempted = True
285-
self._ensure_stopped_queue_poll()
265+
return None
266+
267+
debugger_class = self.debugger_class
268+
try:
269+
debugger = debugger_class(
270+
self.log,
271+
self.debugpy_stream,
272+
self._publish_debug_event,
273+
self.debug_shell_socket,
274+
self.session,
275+
self._kernel_modules,
276+
self.debug_just_my_code,
277+
self.filter_internal_frames,
278+
)
279+
except Exception:
280+
# Deliberately do not set `_debugger_init_attempted`: a
281+
# failure here must not silently turn every later debug
282+
# request into a `None` reply. Let it raise (so the request
283+
# gets a proper error reply) and retry next time.
284+
self.log.exception("Failed to initialize the debugger from %r", debugger_class)
285+
raise
286+
287+
self._debugger = debugger
288+
self._debugger_init_attempted = True
289+
self._ensure_stopped_queue_poll()
286290
return self._debugger
287291

288292
@debugger.setter
289293
def debugger(self, value):
290-
# `debugger` used to be a plain instance attribute assigned in
291-
# __init__; keep it writable for subclasses that replace it.
292294
self._debugger = value
293295
self._debugger_init_attempted = True
294296
if value is not None:
@@ -297,7 +299,7 @@ def debugger(self, value):
297299
# picks it up.
298300
self._ensure_stopped_queue_poll()
299301

300-
def _ensure_stopped_queue_poll(self):
302+
def _ensure_stopped_queue_poll(self) -> None:
301303
"""Schedule `poll_stopped_queue` once, as soon as it can run.
302304
303305
Called both when the debugger is created (or assigned) and from
@@ -341,10 +343,6 @@ def start(self):
341343
else:
342344
self.debugpy_stream.on_recv(self.dispatch_debugpy, copy=False)
343345
super().start()
344-
# Deliberately checks `_debugger` rather than the `debugger` property:
345-
# a kernel that has not needed the debugger yet must not import debugpy
346-
# just to start. If the debugger appears later, its own setter/lazy
347-
# init schedules the poll.
348346
self._ensure_stopped_queue_poll()
349347

350348
def set_parent(self, ident, parent, channel="shell"):

0 commit comments

Comments
 (0)