Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
debugger.py1106 linesDownload Raw Back to debugger
1# debugger.py2 3# A debugger for Pythonwin.  Built from pdb.4 5# Mark Hammond (MHammond@skippinet.com.au) - Dec 94.6 7# usage:8# >>> import pywin.debugger9# >>> pywin.debugger.GetDebugger().run("command")10 11import bdb12import os13import pdb14import string15import sys16import traceback17import types18 19import commctrl20import pywin.docking.DockingBar21import win32api22import win32con23import win32ui24from pywin.framework import app, editor, interact, scriptutils25from pywin.framework.editor.color.coloreditor import MARKER_BREAKPOINT, MARKER_CURRENT26from pywin.mfc import afxres, dialog, object, window27from pywin.tools import browser, hierlist28 29# import win32traceutil30if win32ui.UNICODE:31    LVN_ENDLABELEDIT = commctrl.LVN_ENDLABELEDITW32else:33    LVN_ENDLABELEDIT = commctrl.LVN_ENDLABELEDITA34 35from .dbgcon import *36 37error = "pywin.debugger.error"38 39 40def SetInteractiveContext(globs, locs):41    if interact.edit is not None and interact.edit.currentView is not None:42        interact.edit.currentView.SetContext(globs, locs)43 44 45def _LineStateToMarker(ls):46    if ls == LINESTATE_CURRENT:47        return MARKER_CURRENT48    # 	elif ls == LINESTATE_CALLSTACK:49    # 		return MARKER_CALLSTACK50    return MARKER_BREAKPOINT51 52 53class HierListItem(browser.HLIPythonObject):54    pass55 56 57class HierFrameItem(HierListItem):58    def __init__(self, frame, debugger):59        HierListItem.__init__(self, frame, repr(frame))60        self.debugger = debugger61 62    def GetText(self):63        name = self.myobject.f_code.co_name64        if not name or name == "?":65            # See if locals has a '__name__' (ie, a module)66            if "__name__" in self.myobject.f_locals:67                name = str(self.myobject.f_locals["__name__"]) + " module"68            else:69                name = "<Debugger Context>"70 71        return "%s   (%s:%d)" % (72            name,73            os.path.split(self.myobject.f_code.co_filename)[1],74            self.myobject.f_lineno,75        )76 77    def GetBitmapColumn(self):78        if self.debugger.curframe is self.myobject:79            return 780        else:81            return 882 83    def GetSubList(self):84        ret = []85        ret.append(HierFrameDict(self.myobject.f_locals, "Locals", 2))86        ret.append(HierFrameDict(self.myobject.f_globals, "Globals", 1))87        return ret88 89    def IsExpandable(self):90        return 191 92    def TakeDefaultAction(self):93        # Set the default frame to be this frame.94        self.debugger.set_cur_frame(self.myobject)95        return 196 97 98class HierFrameDict(browser.HLIDict):99    def __init__(self, dict, name, bitmapColumn):100        self.bitmapColumn = bitmapColumn101        browser.HLIDict.__init__(self, dict, name)102 103    def GetBitmapColumn(self):104        return self.bitmapColumn105 106 107class NoStackAvailableItem(HierListItem):108    def __init__(self, why):109        HierListItem.__init__(self, None, why)110 111    def IsExpandable(self):112        return 0113 114    def GetText(self):115        return self.name116 117    def GetBitmapColumn(self):118        return 8119 120 121class HierStackRoot(HierListItem):122    def __init__(self, debugger):123        HierListItem.__init__(self, debugger, None)124        self.last_stack = []125 126    ##	def __del__(self):127    ##		print "HierStackRoot dieing"128    def GetSubList(self):129        debugger = self.myobject130        # 		print self.debugger.stack, self.debugger.curframe131        ret = []132        if debugger.debuggerState == DBGSTATE_BREAK:133            stackUse = debugger.stack[:]134            stackUse.reverse()135            self.last_stack = []136            for frame, lineno in stackUse:137                self.last_stack.append((frame, lineno))138                if (139                    frame is debugger.userbotframe140                ):  # Dont bother showing frames below our bottom frame.141                    break142        for frame, lineno in self.last_stack:143            ret.append(HierFrameItem(frame, debugger))144        ##		elif debugger.debuggerState==DBGSTATE_NOT_DEBUGGING:145        ##			ret.append(NoStackAvailableItem('<nothing is being debugged>'))146        ##		else:147        ##			ret.append(NoStackAvailableItem('<stack not available while running>'))148        return ret149 150    def GetText(self):151        return "root item"152 153    def IsExpandable(self):154        return 1155 156 157class HierListDebugger(hierlist.HierListWithItems):158    """Hier List of stack frames, breakpoints, whatever"""159 160    def __init__(self):161        hierlist.HierListWithItems.__init__(162            self, None, win32ui.IDB_DEBUGGER_HIER, None, win32api.RGB(255, 0, 0)163        )164 165    def Setup(self, debugger):166        root = HierStackRoot(debugger)167        self.AcceptRoot(root)168 169 170# 	def Refresh(self):171# 		self.Setup()172 173 174class DebuggerWindow(window.Wnd):175    def __init__(self, ob):176        window.Wnd.__init__(self, ob)177        self.debugger = None178 179    def Init(self, debugger):180        self.debugger = debugger181 182    def GetDefRect(self):183        defRect = app.LoadWindowSize("Debugger Windows\\" + self.title)184        if defRect[2] - defRect[0] == 0:185            defRect = 0, 0, 150, 150186        return defRect187 188    def OnDestroy(self, msg):189        newSize = self.GetWindowPlacement()[4]190        pywin.framework.app.SaveWindowSize("Debugger Windows\\" + self.title, newSize)191        return window.Wnd.OnDestroy(self, msg)192 193    def OnKeyDown(self, msg):194        key = msg[2]195        if key in (13, 27, 32):196            return 1197        if key in (46, 8):  # delete/BS key198            self.DeleteSelected()199            return 0200        view = scriptutils.GetActiveView()201        try:202            firer = view.bindings.fire_key_event203        except AttributeError:204            firer = None205        if firer is not None:206            return firer(msg)207        else:208            return 1209 210    def DeleteSelected(self):211        win32api.MessageBeep()212 213    def EditSelected(self):214        win32api.MessageBeep()215 216 217class DebuggerStackWindow(DebuggerWindow):218    title = "Stack"219 220    def __init__(self):221        DebuggerWindow.__init__(self, win32ui.CreateTreeCtrl())222        self.list = HierListDebugger()223        self.listOK = 0224 225    def SaveState(self):226        self.list.DeleteAllItems()227        self.listOK = 0228        win32ui.WriteProfileVal(229            "Debugger Windows\\" + self.title, "Visible", self.IsWindowVisible()230        )231 232    def CreateWindow(self, parent):233        style = (234            win32con.WS_CHILD235            | win32con.WS_VISIBLE236            | win32con.WS_BORDER237            | commctrl.TVS_HASLINES238            | commctrl.TVS_LINESATROOT239            | commctrl.TVS_HASBUTTONS240        )241        self._obj_.CreateWindow(style, self.GetDefRect(), parent, win32ui.IDC_LIST1)242        self.HookMessage(self.OnKeyDown, win32con.WM_KEYDOWN)243        self.HookMessage(self.OnKeyDown, win32con.WM_SYSKEYDOWN)244        self.list.HierInit(parent, self)245        self.listOK = 0  # delayed setup246        # self.list.Setup()247 248    def RespondDebuggerState(self, state):249        assert self.debugger is not None, "Init not called"250        if not self.listOK:251            self.listOK = 1252            self.list.Setup(self.debugger)253        else:254            self.list.Refresh()255 256    def RespondDebuggerData(self):257        try:258            handle = self.GetChildItem(0)259        except win32ui.error:260            return  # No items261        while 1:262            item = self.list.ItemFromHandle(handle)263            col = self.list.GetBitmapColumn(item)264            selCol = self.list.GetSelectedBitmapColumn(item)265            if selCol is None:266                selCol = col267            if self.list.GetItemImage(handle) != (col, selCol):268                self.list.SetItemImage(handle, col, selCol)269            try:270                handle = self.GetNextSiblingItem(handle)271            except win32ui.error:272                break273 274 275class DebuggerListViewWindow(DebuggerWindow):276    def __init__(self):277        DebuggerWindow.__init__(self, win32ui.CreateListCtrl())278 279    def CreateWindow(self, parent):280        list = self281        style = (282            win32con.WS_CHILD283            | win32con.WS_VISIBLE284            | win32con.WS_BORDER285            | commctrl.LVS_EDITLABELS286            | commctrl.LVS_REPORT287        )288        self._obj_.CreateWindow(style, self.GetDefRect(), parent, win32ui.IDC_LIST1)289        self.HookMessage(self.OnKeyDown, win32con.WM_KEYDOWN)290        self.HookMessage(self.OnKeyDown, win32con.WM_SYSKEYDOWN)291        list = self292        title, width = self.columns[0]293        itemDetails = (commctrl.LVCFMT_LEFT, width, title, 0)294        list.InsertColumn(0, itemDetails)295        col = 1296        for title, width in self.columns[1:]:297            col = col + 1298            itemDetails = (commctrl.LVCFMT_LEFT, width, title, 0)299            list.InsertColumn(col, itemDetails)300        parent.HookNotify(self.OnListEndLabelEdit, LVN_ENDLABELEDIT)301        parent.HookNotify(self.OnItemRightClick, commctrl.NM_RCLICK)302        parent.HookNotify(self.OnItemDoubleClick, commctrl.NM_DBLCLK)303 304    def RespondDebuggerData(self):305        pass306 307    def RespondDebuggerState(self, state):308        pass309 310    def EditSelected(self):311        try:312            sel = self.GetNextItem(-1, commctrl.LVNI_SELECTED)313        except win32ui.error:314            return315        self.EditLabel(sel)316 317    def OnKeyDown(self, msg):318        key = msg[2]319        # If someone starts typing, they probably are trying to edit the text!320        if chr(key) in string.ascii_uppercase:321            self.EditSelected()322            return 0323        return DebuggerWindow.OnKeyDown(self, msg)324 325    def OnItemDoubleClick(self, notify_data, extra):326        self.EditSelected()327 328    def OnItemRightClick(self, notify_data, extra):329        # First select the item we right-clicked on.330        pt = self.ScreenToClient(win32api.GetCursorPos())331        flags, hItem, subitem = self.HitTest(pt)332        if hItem == -1 or commctrl.TVHT_ONITEM & flags == 0:333            return None334        self.SetItemState(hItem, commctrl.LVIS_SELECTED, commctrl.LVIS_SELECTED)335 336        menu = win32ui.CreatePopupMenu()337        menu.AppendMenu(win32con.MF_STRING | win32con.MF_ENABLED, 1000, "Edit item")338        menu.AppendMenu(win32con.MF_STRING | win32con.MF_ENABLED, 1001, "Delete item")339        dockbar = self.GetParent()340        if dockbar.IsFloating():341            hook_parent = win32ui.GetMainFrame()342        else:343            hook_parent = self.GetParentFrame()344        hook_parent.HookCommand(self.OnEditItem, 1000)345        hook_parent.HookCommand(self.OnDeleteItem, 1001)346        menu.TrackPopupMenu(win32api.GetCursorPos())  # track at mouse position.347        return None348 349    def OnDeleteItem(self, command, code):350        self.DeleteSelected()351 352    def OnEditItem(self, command, code):353        self.EditSelected()354 355 356class DebuggerBreakpointsWindow(DebuggerListViewWindow):357    title = "Breakpoints"358    columns = [("Condition", 70), ("Location", 1024)]359 360    def SaveState(self):361        items = []362        for i in range(self.GetItemCount()):363            items.append(self.GetItemText(i, 0))364            items.append(self.GetItemText(i, 1))365        win32ui.WriteProfileVal(366            "Debugger Windows\\" + self.title, "BreakpointList", "\t".join(items)367        )368        win32ui.WriteProfileVal(369            "Debugger Windows\\" + self.title, "Visible", self.IsWindowVisible()370        )371        return 1372 373    def OnListEndLabelEdit(self, std, extra):374        item = extra[0]375        text = item[4]376        if text is None:377            return378 379        item_id = self.GetItem(item[0])[6]380 381        from bdb import Breakpoint382 383        for bplist in Breakpoint.bplist.values():384            for bp in bplist:385                if id(bp) == item_id:386                    if text.strip().lower() == "none":387                        text = None388                    bp.cond = text389                    break390        self.RespondDebuggerData()391 392    def DeleteSelected(self):393        try:394            num = self.GetNextItem(-1, commctrl.LVNI_SELECTED)395            item_id = self.GetItem(num)[6]396            from bdb import Breakpoint397 398            for bplist in list(Breakpoint.bplist.values()):399                for bp in bplist:400                    if id(bp) == item_id:401                        self.debugger.clear_break(bp.file, bp.line)402                        break403        except win32ui.error:404            win32api.MessageBeep()405        self.RespondDebuggerData()406 407    def RespondDebuggerData(self):408        l = self409        l.DeleteAllItems()410        index = -1411        from bdb import Breakpoint412 413        for bplist in Breakpoint.bplist.values():414            for bp in bplist:415                baseName = os.path.split(bp.file)[1]416                cond = bp.cond417                item = index + 1, 0, 0, 0, str(cond), 0, id(bp)418                index = l.InsertItem(item)419                l.SetItemText(index, 1, "%s: %s" % (baseName, bp.line))420 421 422class DebuggerWatchWindow(DebuggerListViewWindow):423    title = "Watch"424    columns = [("Expression", 70), ("Value", 1024)]425 426    def CreateWindow(self, parent):427        DebuggerListViewWindow.CreateWindow(self, parent)428        items = win32ui.GetProfileVal(429            "Debugger Windows\\" + self.title, "Items", ""430        ).split("\t")431        index = -1432        for item in items:433            if item:434                index = self.InsertItem(index + 1, item)435        self.InsertItem(index + 1, "<New Item>")436 437    def SaveState(self):438        items = []439        for i in range(self.GetItemCount() - 1):440            items.append(self.GetItemText(i, 0))441        win32ui.WriteProfileVal(442            "Debugger Windows\\" + self.title, "Items", "\t".join(items)443        )444        win32ui.WriteProfileVal(445            "Debugger Windows\\" + self.title, "Visible", self.IsWindowVisible()446        )447        return 1448 449    def OnListEndLabelEdit(self, std, extra):450        item = extra[0]451        itemno = item[0]452        text = item[4]453        if text is None:454            return455        self.SetItemText(itemno, 0, text)456        if itemno == self.GetItemCount() - 1:457            self.InsertItem(itemno + 1, "<New Item>")458        self.RespondDebuggerState(self.debugger.debuggerState)459 460    def DeleteSelected(self):461        try:462            num = self.GetNextItem(-1, commctrl.LVNI_SELECTED)463            if num < self.GetItemCount() - 1:  # We cant delete the last464                self.DeleteItem(num)465        except win32ui.error:466            win32api.MessageBeep()467 468    def RespondDebuggerState(self, state):469        globs = locs = None470        if state == DBGSTATE_BREAK:471            if self.debugger.curframe:472                globs = self.debugger.curframe.f_globals473                locs = self.debugger.curframe.f_locals474        elif state == DBGSTATE_NOT_DEBUGGING:475            import __main__476 477            globs = locs = __main__.__dict__478        for i in range(self.GetItemCount() - 1):479            text = self.GetItemText(i, 0)480            if globs is None:481                val = ""482            else:483                try:484                    val = repr(eval(text, globs, locs))485                except SyntaxError:486                    val = "Syntax Error"487                except:488                    t, v, tb = sys.exc_info()489                    val = traceback.format_exception_only(t, v)[0].strip()490                    tb = None  # prevent a cycle.491            self.SetItemText(i, 1, val)492 493 494def CreateDebuggerDialog(parent, klass):495    control = klass()496    control.CreateWindow(parent)497    return control498 499 500DebuggerDialogInfos = (501    (0xE810, DebuggerStackWindow, None),502    (0xE811, DebuggerBreakpointsWindow, (10, 10)),503    (0xE812, DebuggerWatchWindow, None),504)505 506 507# Prepare all the "control bars" for this package.508# If control bars are not all loaded when the toolbar-state functions are509# called, things go horribly wrong.510def PrepareControlBars(frame):511    style = (512        win32con.WS_CHILD513        | afxres.CBRS_SIZE_DYNAMIC514        | afxres.CBRS_TOP515        | afxres.CBRS_TOOLTIPS516        | afxres.CBRS_FLYBY517    )518    tbd = win32ui.CreateToolBar(frame, style, win32ui.ID_VIEW_TOOLBAR_DBG)519    tbd.ModifyStyle(0, commctrl.TBSTYLE_FLAT)520    tbd.LoadToolBar(win32ui.IDR_DEBUGGER)521    tbd.EnableDocking(afxres.CBRS_ALIGN_ANY)522    tbd.SetWindowText("Debugger")523    frame.DockControlBar(tbd)524 525    # and the other windows.526    for id, klass, float in DebuggerDialogInfos:527        try:528            frame.GetControlBar(id)529            exists = 1530        except win32ui.error:531            exists = 0532        if exists:533            continue534        bar = pywin.docking.DockingBar.DockingBar()535        style = win32con.WS_CHILD | afxres.CBRS_LEFT  # don't create visible.536        bar.CreateWindow(537            frame,538            CreateDebuggerDialog,539            klass.title,540            id,541            style,542            childCreatorArgs=(klass,),543        )544        bar.SetBarStyle(545            bar.GetBarStyle()546            | afxres.CBRS_TOOLTIPS547            | afxres.CBRS_FLYBY548            | afxres.CBRS_SIZE_DYNAMIC549        )550        bar.EnableDocking(afxres.CBRS_ALIGN_ANY)551        if float is None:552            frame.DockControlBar(bar)553        else:554            frame.FloatControlBar(bar, float, afxres.CBRS_ALIGN_ANY)555 556        ## frame.ShowControlBar(bar, 0, 1)557 558 559SKIP_NONE = 0560SKIP_STEP = 1561SKIP_RUN = 2562 563debugger_parent = pdb.Pdb564 565 566class Debugger(debugger_parent):567    def __init__(self):568        self.inited = 0569        self.skipBotFrame = SKIP_NONE570        self.userbotframe = None571        self.frameShutdown = 0572        self.pumping = 0573        self.debuggerState = DBGSTATE_NOT_DEBUGGING  # Assume so, anyway.574        self.shownLineCurrent = None  # The last filename I highlighted.575        self.shownLineCallstack = None  # The last filename I highlighted.576        self.last_cmd_debugged = ""577        self.abortClosed = 0578        self.isInitialBreakpoint = 0579        debugger_parent.__init__(self)580 581        # See if any break-points have been set in the editor582        for doc in editor.editorTemplate.GetDocumentList():583            lineNo = -1584            while 1:585                lineNo = doc.MarkerGetNext(lineNo + 1, MARKER_BREAKPOINT)586                if lineNo <= 0:587                    break588                self.set_break(doc.GetPathName(), lineNo)589 590        self.reset()591        self.inForcedGUI = win32ui.GetApp().IsInproc()592        self.options = LoadDebuggerOptions()593        self.bAtException = self.bAtPostMortem = 0594 595    def __del__(self):596        self.close()597 598    def close(self, frameShutdown=0):599        # abortClose indicates if we have total shutdown600        # (ie, main window is dieing)601        if self.pumping:602            # Can stop pump here, as it only posts a message, and603            # returns immediately.604            if not self.StopDebuggerPump():  # User cancelled close.605                return 0606            # NOTE - from this point on the close can not be607            # stopped - the WM_QUIT message is already in the queue.608        self.frameShutdown = frameShutdown609        if not self.inited:610            return 1611        self.inited = 0612 613        SetInteractiveContext(None, None)614 615        frame = win32ui.GetMainFrame()616        # Hide the debuger toolbars (as they wont normally form part of the main toolbar state.617        for id, klass, float in DebuggerDialogInfos:618            try:619                tb = frame.GetControlBar(id)620                if tb.dialog is not None:  # We may never have actually been shown.621                    tb.dialog.SaveState()622                    frame.ShowControlBar(tb, 0, 1)623            except win32ui.error:624                pass625 626        self._UnshowCurrentLine()627        self.set_quit()628        return 1629 630    def StopDebuggerPump(self):631        assert self.pumping, "Can't stop the debugger pump if Im not pumping!"632        # After stopping a pump, I may never return.633        if self.GUIAboutToFinishInteract():634            self.pumping = 0635            win32ui.StopDebuggerPump()  # Posts a message, so we do return.636            return 1637        return 0638 639    def get_option(self, option):640        """Public interface into debugger options"""641        try:642            return self.options[option]643        except KeyError:644            raise error("Option %s is not a valid option" % option)645 646    def prep_run(self, cmd):647        pass648 649    def done_run(self, cmd=None):650        self.RespondDebuggerState(DBGSTATE_NOT_DEBUGGING)651        self.close()652 653    def canonic(self, fname):654        return os.path.abspath(fname).lower()655 656    def reset(self):657        debugger_parent.reset(self)658        self.userbotframe = None659        self.UpdateAllLineStates()660        self._UnshowCurrentLine()661 662    def setup(self, f, t):663        debugger_parent.setup(self, f, t)664        self.bAtException = t is not None665 666    def set_break(self, filename, lineno, temporary=0, cond=None):667        filename = self.canonic(filename)668        self.SetLineState(filename, lineno, LINESTATE_BREAKPOINT)669        return debugger_parent.set_break(self, filename, lineno, temporary, cond)670 671    def clear_break(self, filename, lineno):672        filename = self.canonic(filename)673        self.ResetLineState(filename, lineno, LINESTATE_BREAKPOINT)674        return debugger_parent.clear_break(self, filename, lineno)675 676    def cmdloop(self):677        if self.frameShutdown:678            return  # App in the process of closing - never break in!679        self.GUIAboutToBreak()680 681    def print_stack_entry(self, frame):682        # We dont want a stack printed - our GUI is better :-)683        pass684 685    def user_return(self, frame, return_value):686        # Same as parent, just no "print"687        # This function is called when a return trap is set here688        frame.f_locals["__return__"] = return_value689        self.interaction(frame, None)690 691    def user_call(self, frame, args):692        # base class has an annoying 'print' that adds no value to us...693        if self.stop_here(frame):694            self.interaction(frame, None)695 696    def user_exception(self, frame, exc_info):697        # This function is called if an exception occurs,698        # but only if we are to stop at or just below this level699        (exc_type, exc_value, exc_traceback) = exc_info700        if self.get_option(OPT_STOP_EXCEPTIONS):701            frame.f_locals["__exception__"] = exc_type, exc_value702            print("Unhandled exception while debugging...")703            # on both py2k and py3k, we may be called with exc_value704            # being the args to the exception, or it may already be705            # instantiated (IOW, PyErr_Normalize() hasn't been706            # called on the args).  In py2k this is fine, but in707            # py3k, traceback.print_exception fails.  So on py3k708            # we instantiate an exception instance to print.709            if sys.version_info > (3,) and not isinstance(exc_value, BaseException):710                # they are args - may be a single item or already a tuple711                if not isinstance(exc_value, tuple):712                    exc_value = (exc_value,)713                exc_value = exc_type(*exc_value)714 715            traceback.print_exception(exc_type, exc_value, exc_traceback)716            self.interaction(frame, exc_traceback)717 718    def user_line(self, frame):719        if frame.f_lineno == 0:720            return721        debugger_parent.user_line(self, frame)722 723    def stop_here(self, frame):724        if self.isInitialBreakpoint:725            self.isInitialBreakpoint = 0726            self.set_continue()727            return 0728        if frame is self.botframe and self.skipBotFrame == SKIP_RUN:729            self.set_continue()730            return 0731        if frame is self.botframe and self.skipBotFrame == SKIP_STEP:732            self.set_step()733            return 0734        return debugger_parent.stop_here(self, frame)735 736    def run(self, cmd, globals=None, locals=None, start_stepping=1):737        if not isinstance(cmd, (str, types.CodeType)):738            raise TypeError("Only strings can be run")739        self.last_cmd_debugged = cmd740        if start_stepping:741            self.isInitialBreakpoint = 0742        else:743            self.isInitialBreakpoint = 1744        try:745            if globals is None:746                import __main__747 748                globals = __main__.__dict__749            if locals is None:750                locals = globals751            self.reset()752            self.prep_run(cmd)753            sys.settrace(self.trace_dispatch)754            if type(cmd) != types.CodeType:755                cmd = cmd + "\n"756            try:757                try:758                    if start_stepping:759                        self.skipBotFrame = SKIP_STEP760                    else:761                        self.skipBotFrame = SKIP_RUN762                    exec(cmd, globals, locals)763                except bdb.BdbQuit:764                    pass765            finally:766                self.skipBotFrame = SKIP_NONE767                self.quitting = 1768                sys.settrace(None)769 770        finally:771            self.done_run(cmd)772 773    def runeval(self, expr, globals=None, locals=None):774        self.prep_run(expr)775        try:776            debugger_parent.runeval(self, expr, globals, locals)777        finally:778            self.done_run(expr)779 780    def runexec(self, what, globs=None, locs=None):781        self.reset()782        sys.settrace(self.trace_dispatch)783        try:784            try:785                exec(what, globs, locs)786            except bdb.BdbQuit:787                pass788        finally:789            self.quitting = 1790            sys.settrace(None)791 792    def do_set_step(self):793        if self.GUIAboutToRun():794            self.set_step()795 796    def do_set_next(self):797        if self.GUIAboutToRun():798            self.set_next(self.curframe)799 800    def do_set_return(self):801        if self.GUIAboutToRun():802            self.set_return(self.curframe)803 804    def do_set_continue(self):805        if self.GUIAboutToRun():806            self.set_continue()807 808    def set_quit(self):809        ok = 1810        if self.pumping:811            ok = self.StopDebuggerPump()812        if ok:813            debugger_parent.set_quit(self)814 815    def _dump_frame_(self, frame, name=None):816        if name is None:817            name = ""818        if frame:819            if frame.f_code and frame.f_code.co_filename:820                fname = os.path.split(frame.f_code.co_filename)[1]821            else:822                fname = "??"823            print(repr(name), fname, frame.f_lineno, frame)824        else:825            print(repr(name), "None")826 827    def set_trace(self):828        # Start debugging from _2_ levels up!829        try:830            1 + ""831        except:832            frame = sys.exc_info()[2].tb_frame.f_back.f_back833        self.reset()834        self.userbotframe = None835        while frame:836            # scriptutils.py creates a local variable with name837            # '_debugger_stop_frame_', and we dont go past it838            # (everything above this is Pythonwin framework code)839            if "_debugger_stop_frame_" in frame.f_locals:840                self.userbotframe = frame841                break842 843            frame.f_trace = self.trace_dispatch844            self.botframe = frame845            frame = frame.f_back846        self.set_step()847        sys.settrace(self.trace_dispatch)848 849    def set_cur_frame(self, frame):850        # Sets the "current" frame - ie, the frame with focus.  This is the851        # frame on which "step out" etc actions are taken.852        # This may or may not be the top of the stack.853        assert frame is not None, "You must pass a valid frame"854        self.curframe = frame855        for f, index in self.stack:856            if f is frame:857                self.curindex = index858                break859        else:860            assert 0, "Can't find the frame in the stack."861        SetInteractiveContext(frame.f_globals, frame.f_locals)862        self.GUIRespondDebuggerData()863        self.ShowCurrentLine()864 865    def IsBreak(self):866        return self.debuggerState == DBGSTATE_BREAK867 868    def IsDebugging(self):869        return self.debuggerState != DBGSTATE_NOT_DEBUGGING870 871    def RespondDebuggerState(self, state):872        if state == self.debuggerState:873            return874        if state == DBGSTATE_NOT_DEBUGGING:  # Debugger exists, but not doing anything875            title = ""876        elif state == DBGSTATE_RUNNING:  # Code is running under the debugger.877            title = " - running"878        elif state == DBGSTATE_BREAK:  # We are at a breakpoint or stepping or whatever.879            if self.bAtException:880                if self.bAtPostMortem:881                    title = " - post mortem exception"882                else:883                    title = " - exception"884            else:885                title = " - break"886        else:887            raise error("Invalid debugger state passed!")888        win32ui.GetMainFrame().SetWindowText(889            win32ui.LoadString(win32ui.IDR_MAINFRAME) + title890        )891        if self.debuggerState == DBGSTATE_QUITTING and state != DBGSTATE_NOT_DEBUGGING:892            print("Ignoring state change cos Im trying to stop!", state)893            return894        self.debuggerState = state895        try:896            frame = win32ui.GetMainFrame()897        except win32ui.error:898            frame = None899        if frame is not None:900            for id, klass, float in DebuggerDialogInfos:901                cb = win32ui.GetMainFrame().GetControlBar(id).dialog902                cb.RespondDebuggerState(state)903        # Tell each open editor window about the state transition904        for doc in editor.editorTemplate.GetDocumentList():905            doc.OnDebuggerStateChange(state)906        self.ShowCurrentLine()907 908    #909    # GUI debugger interface.910    #911    def GUICheckInit(self):912        if self.inited:913            return914        self.inited = 1915        frame = win32ui.GetMainFrame()916 917        # Ensure the debugger windows are attached to the debugger.918        for id, klass, float in DebuggerDialogInfos:919            w = frame.GetControlBar(id)920            w.dialog.Init(self)921            # Show toolbar if it was visible during last debug session922            # This would be better done using a CDockState, but that class is not wrapped yet923            if win32ui.GetProfileVal(924                "Debugger Windows\\" + w.dialog.title, "Visible", 0925            ):926                frame.ShowControlBar(w, 1, 1)927 928        # ALWAYS show debugging toolbar, regardless of saved state929        tb = frame.GetControlBar(win32ui.ID_VIEW_TOOLBAR_DBG)930        frame.ShowControlBar(tb, 1, 1)931        self.GUIRespondDebuggerData()932 933    # 		frame.RecalcLayout()934 935    def GetDebuggerBar(self, barName):936        frame = win32ui.GetMainFrame()937        for id, klass, float in DebuggerDialogInfos:938            if klass.title == barName:939                return frame.GetControlBar(id)940        assert 0, "Can't find a bar of that name!"941 942    def GUIRespondDebuggerData(self):943        if not self.inited:  # GUI not inited - no toolbars etc.944            return945 946        for id, klass, float in DebuggerDialogInfos:947            cb = win32ui.GetMainFrame().GetControlBar(id).dialog948            cb.RespondDebuggerData()949 950    def GUIAboutToRun(self):951        if not self.StopDebuggerPump():952            return 0953        self._UnshowCurrentLine()954        self.RespondDebuggerState(DBGSTATE_RUNNING)955        SetInteractiveContext(None, None)956        return 1957 958    def GUIAboutToBreak(self):959        "Called as the GUI debugger is about to get context, and take control of the running program."960        self.GUICheckInit()961        self.RespondDebuggerState(DBGSTATE_BREAK)962        self.GUIAboutToInteract()963        if self.pumping:964            print("!!! Already pumping - outa here")965            return966        self.pumping = 1967        win32ui.StartDebuggerPump()  # NOTE - This will NOT return until the user is finished interacting968        assert not self.pumping, "Should not be pumping once the pump has finished"969        if self.frameShutdown:  # User shut down app while debugging970            win32ui.GetMainFrame().PostMessage(win32con.WM_CLOSE)971 972    def GUIAboutToInteract(self):973        "Called as the GUI is about to perform any interaction with the user"974        frame = win32ui.GetMainFrame()975        # Remember the enabled state of our main frame976        # may be disabled primarily if a modal dialog is displayed.977        # Only get at enabled via GetWindowLong.978        self.bFrameEnabled = frame.IsWindowEnabled()979        self.oldForeground = None980        fw = win32ui.GetForegroundWindow()981        if fw is not frame:982            self.oldForeground = fw983            # 			fw.EnableWindow(0) Leave enabled for now?984            self.oldFrameEnableState = frame.IsWindowEnabled()985            frame.EnableWindow(1)986        if self.inForcedGUI and not frame.IsWindowVisible():987            frame.ShowWindow(win32con.SW_SHOW)988            frame.UpdateWindow()989        if self.curframe:990            SetInteractiveContext(self.curframe.f_globals, self.curframe.f_locals)991        else:992            SetInteractiveContext(None, None)993        self.GUIRespondDebuggerData()994 995    def GUIAboutToFinishInteract(self):996        """Called as the GUI is about to finish any interaction with the user997        Returns non zero if we are allowed to stop interacting"""998        if self.oldForeground is not None:999            try:1000                win32ui.GetMainFrame().EnableWindow(self.oldFrameEnableState)1001                self.oldForeground.EnableWindow(1)1002            except win32ui.error:1003                # old window may be dead.1004                pass1005        # 			self.oldForeground.SetForegroundWindow() - fails??1006        if not self.inForcedGUI:1007            return 1  # Never a problem, and nothing else to do.1008        # If we are running a forced GUI, we may never get an opportunity1009        # to interact again.  Therefore we perform a "SaveAll", to makesure that1010        # any documents are saved before leaving.1011        for template in win32ui.GetApp().GetDocTemplateList():1012            for doc in template.GetDocumentList():1013                if not doc.SaveModified():1014                    return 01015        # All documents saved - now hide the app and debugger.1016        if self.get_option(OPT_HIDE):1017            frame = win32ui.GetMainFrame()1018            frame.ShowWindow(win32con.SW_HIDE)1019        return 11020 1021    #1022    # Pythonwin interface - all stuff to do with showing source files,1023    # changing line states etc.1024    #1025    def ShowLineState(self, fileName, lineNo, lineState):1026        # Set the state of a line, open if not already1027        self.ShowLineNo(fileName, lineNo)1028        self.SetLineState(fileName, lineNo, lineState)1029 1030    def SetLineState(self, fileName, lineNo, lineState):1031        # Set the state of a line if the document is open.1032        doc = editor.editorTemplate.FindOpenDocument(fileName)1033        if doc is not None:1034            marker = _LineStateToMarker(lineState)1035            if not doc.MarkerCheck(lineNo, marker):1036                doc.MarkerAdd(lineNo, marker)1037 1038    def ResetLineState(self, fileName, lineNo, lineState):1039        # Set the state of a line if the document is open.1040        doc = editor.editorTemplate.FindOpenDocument(fileName)1041        if doc is not None:1042            marker = _LineStateToMarker(lineState)1043            doc.MarkerDelete(lineNo, marker)1044 1045    def UpdateDocumentLineStates(self, doc):1046        # Show all lines in their special status color.  If the doc is open1047        # all line states are reset.1048        doc.MarkerDeleteAll(MARKER_BREAKPOINT)1049        doc.MarkerDeleteAll(MARKER_CURRENT)1050        fname = self.canonic(doc.GetPathName())1051        # Now loop over all break-points1052        for line in self.breaks.get(fname, []):1053            doc.MarkerAdd(line, MARKER_BREAKPOINT)1054        # And the current line if in this document.1055        if self.shownLineCurrent and fname == self.shownLineCurrent[0]:1056            lineNo = self.shownLineCurrent[1]1057            if not doc.MarkerCheck(lineNo, MARKER_CURRENT):1058                doc.MarkerAdd(lineNo, MARKER_CURRENT)1059 1060    # 		if self.shownLineCallstack and fname == self.shownLineCallstack[0]:1061    # 			doc.MarkerAdd(self.shownLineCallstack[1], MARKER_CURRENT)1062 1063    def UpdateAllLineStates(self):1064        for doc in editor.editorTemplate.GetDocumentList():1065            self.UpdateDocumentLineStates(doc)1066 1067    def ShowCurrentLine(self):1068        # Show the current line.  Only ever 1 current line - undoes last current1069        # The "Current Line" is self.curframe.1070        # The "Callstack Line" is the top of the stack.1071        # If current == callstack, only show as current.1072        self._UnshowCurrentLine()  # un-highlight the old one.1073        if self.curframe:1074            fileName = self.canonic(self.curframe.f_code.co_filename)1075            lineNo = self.curframe.f_lineno1076            self.shownLineCurrent = fileName, lineNo1077            self.ShowLineState(fileName, lineNo, LINESTATE_CURRENT)1078 1079    def _UnshowCurrentLine(self):1080        "Unshow the current line, and forget it"1081        if self.shownLineCurrent is not None:1082            fname, lineno = self.shownLineCurrent1083            self.ResetLineState(fname, lineno, LINESTATE_CURRENT)1084            self.shownLineCurrent = None1085 1086    def ShowLineNo(self, filename, lineno):1087        wasOpen = editor.editorTemplate.FindOpenDocument(filename) is not None1088        if os.path.isfile(filename) and scriptutils.JumpToDocument(filename, lineno):1089            if not wasOpen:1090                doc = editor.editorTemplate.FindOpenDocument(filename)1091                if doc is not None:1092                    self.UpdateDocumentLineStates(doc)1093                    return 11094                return 01095            return 11096        else:1097            # Can't find the source file - linecache may have it?1098            import linecache1099 1100            line = linecache.getline(filename, lineno)1101            print(1102                "%s(%d): %s"1103                % (os.path.basename(filename), lineno, line[:-1].expandtabs(4))1104            )1105            return 01106 
codekingpro/portable-devtools · Team Ai