mirror of
https://github.com/jdegenstein/jmwright-CQ-Editor.git
synced 2025-12-20 14:37:04 +01:00
add rand_color
This commit is contained in:
@@ -1,365 +1,386 @@
|
|||||||
import sys
|
import sys
|
||||||
from contextlib import ExitStack, contextmanager
|
from contextlib import ExitStack, contextmanager
|
||||||
from enum import Enum, auto
|
from enum import Enum, auto
|
||||||
from types import SimpleNamespace, FrameType, ModuleType
|
from types import SimpleNamespace, FrameType, ModuleType
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
import cadquery as cq
|
import cadquery as cq
|
||||||
from PyQt5 import QtCore
|
from PyQt5 import QtCore
|
||||||
from PyQt5.QtCore import Qt, QObject, pyqtSlot, pyqtSignal, QEventLoop, QAbstractTableModel
|
from PyQt5.QtCore import Qt, QObject, pyqtSlot, pyqtSignal, QEventLoop, QAbstractTableModel
|
||||||
from PyQt5.QtWidgets import (QAction,
|
from PyQt5.QtWidgets import (QAction,
|
||||||
QTableView)
|
QTableView)
|
||||||
from logbook import info
|
from logbook import info
|
||||||
from path import Path
|
from path import Path
|
||||||
from pyqtgraph.parametertree import Parameter
|
from pyqtgraph.parametertree import Parameter
|
||||||
from spyder.utils.icon_manager import icon
|
from spyder.utils.icon_manager import icon
|
||||||
|
from random import randrange as rrr, seed
|
||||||
from ..cq_utils import find_cq_objects, reload_cq
|
|
||||||
from ..mixins import ComponentMixin
|
from ..cq_utils import find_cq_objects, reload_cq
|
||||||
|
from ..mixins import ComponentMixin
|
||||||
DUMMY_FILE = '<string>'
|
|
||||||
|
DUMMY_FILE = '<string>'
|
||||||
|
|
||||||
class DbgState(Enum):
|
|
||||||
|
class DbgState(Enum):
|
||||||
STEP = auto()
|
|
||||||
CONT = auto()
|
STEP = auto()
|
||||||
STEP_IN = auto()
|
CONT = auto()
|
||||||
RETURN = auto()
|
STEP_IN = auto()
|
||||||
|
RETURN = auto()
|
||||||
class DbgEevent(object):
|
|
||||||
|
class DbgEevent(object):
|
||||||
LINE = 'line'
|
|
||||||
CALL = 'call'
|
LINE = 'line'
|
||||||
RETURN = 'return'
|
CALL = 'call'
|
||||||
|
RETURN = 'return'
|
||||||
class LocalsModel(QAbstractTableModel):
|
|
||||||
|
class LocalsModel(QAbstractTableModel):
|
||||||
HEADER = ('Name','Type', 'Value')
|
|
||||||
|
HEADER = ('Name','Type', 'Value')
|
||||||
def __init__(self,parent):
|
|
||||||
|
def __init__(self,parent):
|
||||||
super(LocalsModel,self).__init__(parent)
|
|
||||||
self.frame = None
|
super(LocalsModel,self).__init__(parent)
|
||||||
|
self.frame = None
|
||||||
def update_frame(self,frame):
|
|
||||||
|
def update_frame(self,frame):
|
||||||
self.frame = \
|
|
||||||
[(k,type(v).__name__, str(v)) for k,v in frame.items() if not k.startswith('_')]
|
self.frame = \
|
||||||
|
[(k,type(v).__name__, str(v)) for k,v in frame.items() if not k.startswith('_')]
|
||||||
|
|
||||||
def rowCount(self,parent=QtCore.QModelIndex()):
|
|
||||||
|
def rowCount(self,parent=QtCore.QModelIndex()):
|
||||||
if self.frame:
|
|
||||||
return len(self.frame)
|
if self.frame:
|
||||||
else:
|
return len(self.frame)
|
||||||
return 0
|
else:
|
||||||
|
return 0
|
||||||
def columnCount(self,parent=QtCore.QModelIndex()):
|
|
||||||
|
def columnCount(self,parent=QtCore.QModelIndex()):
|
||||||
return 3
|
|
||||||
|
return 3
|
||||||
def headerData(self, section, orientation, role=Qt.DisplayRole):
|
|
||||||
if role == Qt.DisplayRole and orientation == Qt.Horizontal:
|
def headerData(self, section, orientation, role=Qt.DisplayRole):
|
||||||
return self.HEADER[section]
|
if role == Qt.DisplayRole and orientation == Qt.Horizontal:
|
||||||
return QAbstractTableModel.headerData(self, section, orientation, role)
|
return self.HEADER[section]
|
||||||
|
return QAbstractTableModel.headerData(self, section, orientation, role)
|
||||||
def data(self, index, role):
|
|
||||||
if role == QtCore.Qt.DisplayRole:
|
def data(self, index, role):
|
||||||
i = index.row()
|
if role == QtCore.Qt.DisplayRole:
|
||||||
j = index.column()
|
i = index.row()
|
||||||
return self.frame[i][j]
|
j = index.column()
|
||||||
else:
|
return self.frame[i][j]
|
||||||
return QtCore.QVariant()
|
else:
|
||||||
|
return QtCore.QVariant()
|
||||||
|
|
||||||
class LocalsView(QTableView,ComponentMixin):
|
|
||||||
|
class LocalsView(QTableView,ComponentMixin):
|
||||||
name = 'Variables'
|
|
||||||
|
name = 'Variables'
|
||||||
def __init__(self,parent):
|
|
||||||
|
def __init__(self,parent):
|
||||||
super(LocalsView,self).__init__(parent)
|
|
||||||
ComponentMixin.__init__(self)
|
super(LocalsView,self).__init__(parent)
|
||||||
|
ComponentMixin.__init__(self)
|
||||||
header = self.horizontalHeader()
|
|
||||||
header.setStretchLastSection(True)
|
header = self.horizontalHeader()
|
||||||
|
header.setStretchLastSection(True)
|
||||||
vheader = self.verticalHeader()
|
|
||||||
vheader.setVisible(False)
|
vheader = self.verticalHeader()
|
||||||
|
vheader.setVisible(False)
|
||||||
@pyqtSlot(dict)
|
|
||||||
def update_frame(self,frame):
|
@pyqtSlot(dict)
|
||||||
|
def update_frame(self,frame):
|
||||||
model = LocalsModel(self)
|
|
||||||
model.update_frame(frame)
|
model = LocalsModel(self)
|
||||||
|
model.update_frame(frame)
|
||||||
self.setModel(model)
|
|
||||||
|
self.setModel(model)
|
||||||
class Debugger(QObject,ComponentMixin):
|
|
||||||
|
class Debugger(QObject,ComponentMixin):
|
||||||
name = 'Debugger'
|
|
||||||
|
name = 'Debugger'
|
||||||
preferences = Parameter.create(name='Preferences',children=[
|
|
||||||
{'name': 'Reload CQ', 'type': 'bool', 'value': False},
|
preferences = Parameter.create(name='Preferences',children=[
|
||||||
{'name': 'Add script dir to path','type': 'bool', 'value': True},
|
{'name': 'Reload CQ', 'type': 'bool', 'value': False},
|
||||||
{'name': 'Change working dir to script dir','type': 'bool', 'value': True},
|
{'name': 'Add script dir to path','type': 'bool', 'value': True},
|
||||||
{'name': 'Reload imported modules', 'type': 'bool', 'value': True},
|
{'name': 'Change working dir to script dir','type': 'bool', 'value': True},
|
||||||
])
|
{'name': 'Reload imported modules', 'type': 'bool', 'value': True},
|
||||||
|
])
|
||||||
|
|
||||||
sigRendered = pyqtSignal(dict)
|
|
||||||
sigLocals = pyqtSignal(dict)
|
sigRendered = pyqtSignal(dict)
|
||||||
sigTraceback = pyqtSignal(object,str)
|
sigLocals = pyqtSignal(dict)
|
||||||
|
sigTraceback = pyqtSignal(object,str)
|
||||||
sigFrameChanged = pyqtSignal(object)
|
|
||||||
sigLineChanged = pyqtSignal(int)
|
sigFrameChanged = pyqtSignal(object)
|
||||||
sigLocalsChanged = pyqtSignal(dict)
|
sigLineChanged = pyqtSignal(int)
|
||||||
sigCQChanged = pyqtSignal(dict,bool)
|
sigLocalsChanged = pyqtSignal(dict)
|
||||||
sigDebugging = pyqtSignal(bool)
|
sigCQChanged = pyqtSignal(dict,bool)
|
||||||
|
sigDebugging = pyqtSignal(bool)
|
||||||
_frames : List[FrameType]
|
|
||||||
|
_frames : List[FrameType]
|
||||||
def __init__(self,parent):
|
|
||||||
|
def __init__(self,parent):
|
||||||
super(Debugger,self).__init__(parent)
|
|
||||||
ComponentMixin.__init__(self)
|
super(Debugger,self).__init__(parent)
|
||||||
|
ComponentMixin.__init__(self)
|
||||||
self.inner_event_loop = QEventLoop(self)
|
|
||||||
|
self.inner_event_loop = QEventLoop(self)
|
||||||
self._actions = \
|
|
||||||
{'Run' : [QAction(icon('run'),
|
self._actions = \
|
||||||
'Render',
|
{'Run' : [QAction(icon('run'),
|
||||||
self,
|
'Render',
|
||||||
shortcut='F5',
|
self,
|
||||||
triggered=self.render),
|
shortcut='F5',
|
||||||
QAction(icon('debug'),
|
triggered=self.render),
|
||||||
'Debug',
|
QAction(icon('debug'),
|
||||||
self,
|
'Debug',
|
||||||
checkable=True,
|
self,
|
||||||
shortcut='ctrl+F5',
|
checkable=True,
|
||||||
triggered=self.debug),
|
shortcut='ctrl+F5',
|
||||||
QAction(icon('arrow-step-over'),
|
triggered=self.debug),
|
||||||
'Step',
|
QAction(icon('arrow-step-over'),
|
||||||
self,
|
'Step',
|
||||||
shortcut='ctrl+F10',
|
self,
|
||||||
triggered=lambda: self.debug_cmd(DbgState.STEP)),
|
shortcut='ctrl+F10',
|
||||||
QAction(icon('arrow-step-in'),
|
triggered=lambda: self.debug_cmd(DbgState.STEP)),
|
||||||
'Step in',
|
QAction(icon('arrow-step-in'),
|
||||||
self,
|
'Step in',
|
||||||
shortcut='ctrl+F11',
|
self,
|
||||||
triggered=lambda: self.debug_cmd(DbgState.STEP_IN)),
|
shortcut='ctrl+F11',
|
||||||
QAction(icon('arrow-continue'),
|
triggered=lambda: self.debug_cmd(DbgState.STEP_IN)),
|
||||||
'Continue',
|
QAction(icon('arrow-continue'),
|
||||||
self,
|
'Continue',
|
||||||
shortcut='ctrl+F12',
|
self,
|
||||||
triggered=lambda: self.debug_cmd(DbgState.CONT))
|
shortcut='ctrl+F12',
|
||||||
]}
|
triggered=lambda: self.debug_cmd(DbgState.CONT))
|
||||||
|
]}
|
||||||
self._frames = []
|
|
||||||
|
self._frames = []
|
||||||
def get_current_script(self):
|
|
||||||
|
def get_current_script(self):
|
||||||
return self.parent().components['editor'].get_text_with_eol()
|
|
||||||
|
return self.parent().components['editor'].get_text_with_eol()
|
||||||
def get_breakpoints(self):
|
|
||||||
|
def get_breakpoints(self):
|
||||||
return self.parent().components['editor'].debugger.get_breakpoints()
|
|
||||||
|
return self.parent().components['editor'].debugger.get_breakpoints()
|
||||||
def compile_code(self, cq_script):
|
|
||||||
|
def compile_code(self, cq_script):
|
||||||
try:
|
|
||||||
module = ModuleType('temp')
|
try:
|
||||||
cq_code = compile(cq_script, '<string>', 'exec')
|
module = ModuleType('temp')
|
||||||
return cq_code, module
|
cq_code = compile(cq_script, '<string>', 'exec')
|
||||||
except Exception:
|
return cq_code, module
|
||||||
self.sigTraceback.emit(sys.exc_info(), cq_script)
|
except Exception:
|
||||||
return None, None
|
self.sigTraceback.emit(sys.exc_info(), cq_script)
|
||||||
|
return None, None
|
||||||
def _exec(self, code, locals_dict, globals_dict):
|
|
||||||
|
def _exec(self, code, locals_dict, globals_dict):
|
||||||
with ExitStack() as stack:
|
|
||||||
fname = self.parent().components['editor'].filename
|
with ExitStack() as stack:
|
||||||
p = Path(fname if fname else '').abspath().dirname()
|
fname = self.parent().components['editor'].filename
|
||||||
|
p = Path(fname if fname else '').abspath().dirname()
|
||||||
if self.preferences['Add script dir to path'] and p.exists():
|
|
||||||
sys.path.insert(0,p)
|
if self.preferences['Add script dir to path'] and p.exists():
|
||||||
stack.callback(sys.path.remove, p)
|
sys.path.insert(0,p)
|
||||||
if self.preferences['Change working dir to script dir'] and p.exists():
|
stack.callback(sys.path.remove, p)
|
||||||
stack.enter_context(p)
|
if self.preferences['Change working dir to script dir'] and p.exists():
|
||||||
if self.preferences['Reload imported modules']:
|
stack.enter_context(p)
|
||||||
stack.enter_context(module_manager())
|
if self.preferences['Reload imported modules']:
|
||||||
|
stack.enter_context(module_manager())
|
||||||
exec(code, locals_dict, globals_dict)
|
|
||||||
|
exec(code, locals_dict, globals_dict)
|
||||||
def _inject_locals(self,module):
|
|
||||||
|
def _inject_locals(self,module):
|
||||||
cq_objects = {}
|
|
||||||
|
cq_objects = {}
|
||||||
def _show_object(obj,name=None, options={}):
|
|
||||||
|
def _show_object(obj,name=None, options={}):
|
||||||
if name:
|
|
||||||
cq_objects.update({name : SimpleNamespace(shape=obj,options=options)})
|
if name:
|
||||||
else:
|
cq_objects.update({name : SimpleNamespace(shape=obj,options=options)})
|
||||||
cq_objects.update({str(id(obj)) : SimpleNamespace(shape=obj,options=options)})
|
else:
|
||||||
|
cq_objects.update({str(id(obj)) : SimpleNamespace(shape=obj,options=options)})
|
||||||
def _debug(obj,name=None):
|
|
||||||
|
def _debug(obj,name=None):
|
||||||
_show_object(obj,name,options=dict(color='red',alpha=0.2))
|
|
||||||
|
_show_object(obj,name,options=dict(color='red',alpha=0.2))
|
||||||
module.__dict__['show_object'] = _show_object
|
|
||||||
module.__dict__['debug'] = _debug
|
def _rand_color(alpha = 0., cfloat=False):
|
||||||
module.__dict__['log'] = lambda x: info(str(x))
|
#helper function to generate a random color dict
|
||||||
module.__dict__['cq'] = cq
|
#for CQ-editor's show_object function
|
||||||
|
lower = 10
|
||||||
return cq_objects, set(module.__dict__)-{'cq'}
|
upper = 100 #not too high to keep color brightness in check
|
||||||
|
if cfloat: #for two output types depending on need
|
||||||
def _cleanup_locals(self,module,injected_names):
|
return (
|
||||||
|
(rrr(lower,upper)/255),
|
||||||
for name in injected_names: module.__dict__.pop(name)
|
(rrr(lower,upper)/255),
|
||||||
|
(rrr(lower,upper)/255),
|
||||||
@pyqtSlot(bool)
|
alpha,
|
||||||
def render(self):
|
)
|
||||||
|
return {"alpha": alpha,
|
||||||
if self.preferences['Reload CQ']:
|
"color": (
|
||||||
reload_cq()
|
rrr(lower,upper),
|
||||||
|
rrr(lower,upper),
|
||||||
cq_script = self.get_current_script()
|
rrr(lower,upper),
|
||||||
cq_code,module = self.compile_code(cq_script)
|
)}
|
||||||
|
|
||||||
if cq_code is None: return
|
module.__dict__['show_object'] = _show_object
|
||||||
|
module.__dict__['debug'] = _debug
|
||||||
cq_objects,injected_names = self._inject_locals(module)
|
module.__dict__['rand_color'] = _rand_color
|
||||||
|
module.__dict__['log'] = lambda x: info(str(x))
|
||||||
try:
|
module.__dict__['cq'] = cq
|
||||||
self._exec(cq_code, module.__dict__, module.__dict__)
|
|
||||||
|
return cq_objects, set(module.__dict__)-{'cq'}
|
||||||
#remove the special methods
|
|
||||||
self._cleanup_locals(module,injected_names)
|
def _cleanup_locals(self,module,injected_names):
|
||||||
|
|
||||||
#collect all CQ objects if no explicit show_object was called
|
for name in injected_names: module.__dict__.pop(name)
|
||||||
if len(cq_objects) == 0:
|
|
||||||
cq_objects = find_cq_objects(module.__dict__)
|
@pyqtSlot(bool)
|
||||||
self.sigRendered.emit(cq_objects)
|
def render(self):
|
||||||
self.sigTraceback.emit(None,
|
seed(371353) #reset the seed every time render is called (preserves colors run to run)
|
||||||
cq_script)
|
if self.preferences['Reload CQ']:
|
||||||
self.sigLocals.emit(module.__dict__)
|
reload_cq()
|
||||||
except Exception:
|
|
||||||
exc_info = sys.exc_info()
|
cq_script = self.get_current_script()
|
||||||
sys.last_traceback = exc_info[-1]
|
cq_code,module = self.compile_code(cq_script)
|
||||||
self.sigTraceback.emit(exc_info, cq_script)
|
|
||||||
|
if cq_code is None: return
|
||||||
@property
|
|
||||||
def breakpoints(self):
|
cq_objects,injected_names = self._inject_locals(module)
|
||||||
return [ el[0] for el in self.get_breakpoints()]
|
|
||||||
|
try:
|
||||||
@pyqtSlot(bool)
|
self._exec(cq_code, module.__dict__, module.__dict__)
|
||||||
def debug(self,value):
|
|
||||||
|
#remove the special methods
|
||||||
previous_trace = sys.gettrace()
|
self._cleanup_locals(module,injected_names)
|
||||||
|
|
||||||
if value:
|
#collect all CQ objects if no explicit show_object was called
|
||||||
self.sigDebugging.emit(True)
|
if len(cq_objects) == 0:
|
||||||
self.state = DbgState.STEP
|
cq_objects = find_cq_objects(module.__dict__)
|
||||||
|
self.sigRendered.emit(cq_objects)
|
||||||
self.script = self.get_current_script()
|
self.sigTraceback.emit(None,
|
||||||
code,module = self.compile_code(self.script)
|
cq_script)
|
||||||
|
self.sigLocals.emit(module.__dict__)
|
||||||
if code is None:
|
except Exception:
|
||||||
self.sigDebugging.emit(False)
|
exc_info = sys.exc_info()
|
||||||
self._actions['Run'][1].setChecked(False)
|
sys.last_traceback = exc_info[-1]
|
||||||
return
|
self.sigTraceback.emit(exc_info, cq_script)
|
||||||
|
|
||||||
cq_objects,injected_names = self._inject_locals(module)
|
@property
|
||||||
|
def breakpoints(self):
|
||||||
#clear possible traceback
|
return [ el[0] for el in self.get_breakpoints()]
|
||||||
self.sigTraceback.emit(None,
|
|
||||||
self.script)
|
@pyqtSlot(bool)
|
||||||
|
def debug(self,value):
|
||||||
try:
|
|
||||||
sys.settrace(self.trace_callback)
|
previous_trace = sys.gettrace()
|
||||||
exec(code,module.__dict__,module.__dict__)
|
|
||||||
except Exception:
|
if value:
|
||||||
exc_info = sys.exc_info()
|
self.sigDebugging.emit(True)
|
||||||
sys.last_traceback = exc_info[-1]
|
self.state = DbgState.STEP
|
||||||
self.sigTraceback.emit(exc_info,
|
|
||||||
self.script)
|
self.script = self.get_current_script()
|
||||||
finally:
|
code,module = self.compile_code(self.script)
|
||||||
sys.settrace(previous_trace)
|
|
||||||
self.sigDebugging.emit(False)
|
if code is None:
|
||||||
self._actions['Run'][1].setChecked(False)
|
self.sigDebugging.emit(False)
|
||||||
|
self._actions['Run'][1].setChecked(False)
|
||||||
if len(cq_objects) == 0:
|
return
|
||||||
cq_objects = find_cq_objects(module.__dict__)
|
|
||||||
self.sigRendered.emit(cq_objects)
|
cq_objects,injected_names = self._inject_locals(module)
|
||||||
|
|
||||||
self._cleanup_locals(module,injected_names)
|
#clear possible traceback
|
||||||
self.sigLocals.emit(module.__dict__)
|
self.sigTraceback.emit(None,
|
||||||
|
self.script)
|
||||||
self._frames = []
|
|
||||||
else:
|
try:
|
||||||
sys.settrace(previous_trace)
|
sys.settrace(self.trace_callback)
|
||||||
self.inner_event_loop.exit(0)
|
exec(code,module.__dict__,module.__dict__)
|
||||||
|
except Exception:
|
||||||
|
exc_info = sys.exc_info()
|
||||||
def debug_cmd(self,state=DbgState.STEP):
|
sys.last_traceback = exc_info[-1]
|
||||||
|
self.sigTraceback.emit(exc_info,
|
||||||
self.state = state
|
self.script)
|
||||||
self.inner_event_loop.exit(0)
|
finally:
|
||||||
|
sys.settrace(previous_trace)
|
||||||
|
self.sigDebugging.emit(False)
|
||||||
def trace_callback(self,frame,event,arg):
|
self._actions['Run'][1].setChecked(False)
|
||||||
|
|
||||||
filename = frame.f_code.co_filename
|
if len(cq_objects) == 0:
|
||||||
|
cq_objects = find_cq_objects(module.__dict__)
|
||||||
if filename==DUMMY_FILE:
|
self.sigRendered.emit(cq_objects)
|
||||||
if not self._frames:
|
|
||||||
self._frames.append(frame)
|
self._cleanup_locals(module,injected_names)
|
||||||
self.trace_local(frame,event,arg)
|
self.sigLocals.emit(module.__dict__)
|
||||||
return self.trace_callback
|
|
||||||
|
self._frames = []
|
||||||
else:
|
else:
|
||||||
return None
|
sys.settrace(previous_trace)
|
||||||
|
self.inner_event_loop.exit(0)
|
||||||
def trace_local(self,frame,event,arg):
|
|
||||||
|
|
||||||
lineno = frame.f_lineno
|
def debug_cmd(self,state=DbgState.STEP):
|
||||||
|
|
||||||
if event in (DbgEevent.LINE,):
|
self.state = state
|
||||||
if (self.state in (DbgState.STEP, DbgState.STEP_IN) and frame is self._frames[-1]) \
|
self.inner_event_loop.exit(0)
|
||||||
or (lineno in self.breakpoints):
|
|
||||||
|
|
||||||
if lineno in self.breakpoints:
|
def trace_callback(self,frame,event,arg):
|
||||||
self._frames.append(frame)
|
|
||||||
|
filename = frame.f_code.co_filename
|
||||||
self.sigLineChanged.emit(lineno)
|
|
||||||
self.sigFrameChanged.emit(frame)
|
if filename==DUMMY_FILE:
|
||||||
self.sigLocalsChanged.emit(frame.f_locals)
|
if not self._frames:
|
||||||
self.sigCQChanged.emit(find_cq_objects(frame.f_locals),True)
|
self._frames.append(frame)
|
||||||
|
self.trace_local(frame,event,arg)
|
||||||
self.inner_event_loop.exec_()
|
return self.trace_callback
|
||||||
|
|
||||||
elif event in (DbgEevent.RETURN):
|
else:
|
||||||
self.sigLocalsChanged.emit(frame.f_locals)
|
return None
|
||||||
self._frames.pop()
|
|
||||||
|
def trace_local(self,frame,event,arg):
|
||||||
elif event == DbgEevent.CALL:
|
|
||||||
func_filename = frame.f_code.co_filename
|
lineno = frame.f_lineno
|
||||||
if self.state == DbgState.STEP_IN and func_filename == DUMMY_FILE:
|
|
||||||
self.sigLineChanged.emit(lineno)
|
if event in (DbgEevent.LINE,):
|
||||||
self.sigFrameChanged.emit(frame)
|
if (self.state in (DbgState.STEP, DbgState.STEP_IN) and frame is self._frames[-1]) \
|
||||||
self.state = DbgState.STEP
|
or (lineno in self.breakpoints):
|
||||||
self._frames.append(frame)
|
|
||||||
|
if lineno in self.breakpoints:
|
||||||
|
self._frames.append(frame)
|
||||||
@contextmanager
|
|
||||||
def module_manager():
|
self.sigLineChanged.emit(lineno)
|
||||||
""" unloads any modules loaded while the context manager is active """
|
self.sigFrameChanged.emit(frame)
|
||||||
loaded_modules = set(sys.modules.keys())
|
self.sigLocalsChanged.emit(frame.f_locals)
|
||||||
|
self.sigCQChanged.emit(find_cq_objects(frame.f_locals),True)
|
||||||
try:
|
|
||||||
yield
|
self.inner_event_loop.exec_()
|
||||||
finally:
|
|
||||||
new_modules = set(sys.modules.keys()) - loaded_modules
|
elif event in (DbgEevent.RETURN):
|
||||||
for module_name in new_modules:
|
self.sigLocalsChanged.emit(frame.f_locals)
|
||||||
del sys.modules[module_name]
|
self._frames.pop()
|
||||||
|
|
||||||
|
elif event == DbgEevent.CALL:
|
||||||
|
func_filename = frame.f_code.co_filename
|
||||||
|
if self.state == DbgState.STEP_IN and func_filename == DUMMY_FILE:
|
||||||
|
self.sigLineChanged.emit(lineno)
|
||||||
|
self.sigFrameChanged.emit(frame)
|
||||||
|
self.state = DbgState.STEP
|
||||||
|
self._frames.append(frame)
|
||||||
|
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def module_manager():
|
||||||
|
""" unloads any modules loaded while the context manager is active """
|
||||||
|
loaded_modules = set(sys.modules.keys())
|
||||||
|
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
new_modules = set(sys.modules.keys()) - loaded_modules
|
||||||
|
for module_name in new_modules:
|
||||||
|
del sys.modules[module_name]
|
||||||
|
|||||||
Reference in New Issue
Block a user