This commit is contained in:
Sven Riwoldt
2024-04-01 20:30:24 +02:00
parent fd333f3514
commit c7bc862c6f
6804 changed files with 1065135 additions and 0 deletions

View File

@@ -0,0 +1,115 @@
# -*- coding: utf-8 -*-
# -----------------------------------------------------------------------------
# Copyright (c) 2009- Spyder Kernels Contributors
#
# Licensed under the terms of the MIT License
# (see spyder_kernels/__init__.py for details)
# -----------------------------------------------------------------------------
"""
Spyder shell for Jupyter kernels.
"""
# Standard library imports
import bdb
import sys
# Third-party imports
from ipykernel.zmqshell import ZMQInteractiveShell
class SpyderShell(ZMQInteractiveShell):
"""Spyder shell."""
def __init__(self, *args, **kwargs):
# Create _pdb_obj before __init__
self._pdb_obj = None
super(SpyderShell, self).__init__(*args, **kwargs)
# register post_execute
self.events.register('post_execute', self.do_post_execute)
# ---- Methods overriden by us.
def ask_exit(self):
"""Engage the exit actions."""
self.kernel.frontend_comm.close_thread()
return super(SpyderShell, self).ask_exit()
def _showtraceback(self, etype, evalue, stb):
"""
Don't show a traceback when exiting our debugger after entering
it through a `breakpoint()` call.
This is because calling `!exit` after `breakpoint()` raises
BdbQuit, which throws a long and useless traceback.
"""
if etype is bdb.BdbQuit:
stb = ['']
super(SpyderShell, self)._showtraceback(etype, evalue, stb)
# ---- For Pdb namespace integration
def get_local_scope(self, stack_depth):
"""Get local scope at given frame depth."""
frame = sys._getframe(stack_depth + 1)
if self._pdb_frame is frame:
# Avoid calling f_locals on _pdb_frame
return self._pdb_obj.curframe_locals
else:
return frame.f_locals
def get_global_scope(self, stack_depth):
"""Get global scope at given frame depth."""
frame = sys._getframe(stack_depth + 1)
return frame.f_globals
def is_debugging(self):
"""
Check if we are currently debugging.
"""
return bool(self._pdb_frame)
@property
def pdb_session(self):
"""Get current pdb session."""
return self._pdb_obj
@pdb_session.setter
def pdb_session(self, pdb_obj):
"""Register Pdb session to use it later"""
self._pdb_obj = pdb_obj
@property
def _pdb_frame(self):
"""Return current Pdb frame if there is any"""
if self.pdb_session is not None:
return self.pdb_session.curframe
@property
def _pdb_locals(self):
"""
Return current Pdb frame locals if available. Otherwise
return an empty dictionary
"""
if self._pdb_frame is not None:
return self._pdb_obj.curframe_locals
else:
return {}
@property
def user_ns(self):
"""Get the current namespace."""
if self._pdb_frame is not None:
return self._pdb_frame.f_globals
else:
return self.__user_ns
@user_ns.setter
def user_ns(self, namespace):
"""Set user_ns."""
self.__user_ns = namespace
def do_post_execute(self):
"""Flush __std*__ after execution."""
# Flush C standard streams.
sys.__stderr__.flush()
sys.__stdout__.flush()