File indexing completed on 2025-03-09 04:10:20
0001 """ 0002 SPDX-FileCopyrightText: 2017 Eliakin Costa <eliakim170@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 """ 0006 import bdb 0007 import multiprocessing 0008 import sys 0009 import asyncio 0010 from . import debuggerformatter 0011 0012 0013 class Debugger(bdb.Bdb): 0014 0015 def __init__(self, scripter, cmd): 0016 bdb.Bdb.__init__(self) 0017 0018 self.quit = False 0019 self.debugq = multiprocessing.Queue() 0020 self.scripter = scripter 0021 self.applicationq = multiprocessing.Queue() 0022 self.filePath = self.scripter.documentcontroller.activeDocument.filePath 0023 self.application_data = {} 0024 self.exception_data = {} 0025 self.debugprocess = multiprocessing.Process(target=self._run, args=(self.filePath,)) 0026 self.currentLine = 0 0027 0028 bdb.Bdb.reset(self) 0029 0030 def _run(self, filename): 0031 try: 0032 self.mainpyfile = self.canonic(filename) 0033 with open(filename, "rb") as fp: 0034 statement = "exec(compile(%r, %r, 'exec'))" % \ 0035 (fp.read(), self.mainpyfile) 0036 self.run(statement) 0037 except Exception as e: 0038 raise e 0039 0040 def user_call(self, frame, args): 0041 name = frame.f_code.co_name or "<unknown>" 0042 0043 def user_line(self, frame): 0044 """Handler that executes with every line of code""" 0045 co = frame.f_code 0046 0047 if self.filePath != co.co_filename: 0048 return 0049 0050 self.currentLine = frame.f_lineno 0051 self.applicationq.put({"code": {"file": co.co_filename, 0052 "name": co.co_name, 0053 "lineNumber": str(frame.f_lineno) 0054 }, 0055 "frame": {"firstLineNumber": co.co_firstlineno, 0056 "locals": debuggerformatter.format_data(frame.f_locals), 0057 "globals": debuggerformatter.format_data(frame.f_globals) 0058 }, 0059 "trace": "line" 0060 }) 0061 0062 if self.quit: 0063 return self.set_quit() 0064 if self.currentLine == 0: 0065 return 0066 else: 0067 cmd = self.debugq.get() 0068 0069 if cmd == "step": 0070 return 0071 if cmd == "stop": 0072 return self.set_quit() 0073 0074 def user_return(self, frame, value): 0075 name = frame.f_code.co_name or "<unknown>" 0076 0077 if name == '<module>': 0078 self.applicationq.put({"quit": True}) 0079 0080 def user_exception(self, frame, exception): 0081 self.applicationq.put({"exception": str(exception[1])}) 0082 0083 async def display(self): 0084 """Coroutine for updating the UI""" 0085 0086 while True: 0087 if self.applicationq.empty(): 0088 await asyncio.sleep(0.3) 0089 else: 0090 while not self.applicationq.empty(): 0091 self.application_data.update(self.applicationq.get()) 0092 self.scripter.uicontroller.repaintDebugArea() 0093 return 0094 0095 async def start(self): 0096 await self.display() 0097 0098 async def step(self): 0099 self.debugq.put("step") 0100 await self.display() 0101 0102 async def stop(self): 0103 self.debugq.put("stop") 0104 self.applicationq.put({"quit": True}) 0105 await self.display()