DebugClients/Python3/DebugBase.py

branch
debugger speed
changeset 5007
e2fa12bb0f53
parent 5005
684f5ba04f0b
child 5012
be693f11da53
equal deleted inserted replaced
5006:82e91d2f59a1 5007:e2fa12bb0f53
53 # on Windows 53 # on Windows
54 lib = os.path.dirname(bdb.__file__) 54 lib = os.path.dirname(bdb.__file__)
55 # tuple required because it's accessed a lot of times by startswith method 55 # tuple required because it's accessed a lot of times by startswith method
56 pathsToSkip = ('<', os.path.dirname(__file__), bdb.__file__[:-1]) 56 pathsToSkip = ('<', os.path.dirname(__file__), bdb.__file__[:-1])
57 filesToSkip = {} 57 filesToSkip = {}
58
59 # cache for fixed file names
60 _fnCache = {}
58 61
59 def __init__(self, dbgClient): 62 def __init__(self, dbgClient):
60 """ 63 """
61 Constructor 64 Constructor
62 65
376 this can break debugging as the .pyc will refer to the .py 379 this can break debugging as the .pyc will refer to the .py
377 on the original machine. Another case might be sharing 380 on the original machine. Another case might be sharing
378 code over a network... This logic deals with that. 381 code over a network... This logic deals with that.
379 382
380 @param frame the frame object 383 @param frame the frame object
381 @return fixed up file name (string) 384 @type frame object
385 @return fixed up file name
386 @rtype str
382 """ 387 """
383 # get module name from __file__ 388 # get module name from __file__
384 if '__file__' in frame.f_globals and \ 389 fn = frame.f_globals.get('__file__')
385 frame.f_globals['__file__'] and \ 390 try:
386 frame.f_globals['__file__'] == frame.f_code.co_filename: 391 return self._fnCache[fn]
387 root, ext = os.path.splitext(frame.f_globals['__file__']) 392 except KeyError:
388 if ext in ['.pyc', '.py', '.py3', '.pyo']: 393 if fn and fn != frame.f_code.co_filename:
389 fixedName = root + '.py' 394 absFilename = os.path.abspath(fn)
390 if os.path.exists(fixedName): 395 if absFilename.endswith(('.pyc', '.pyo')):
391 return fixedName 396 fixedName = absFilename[:-1]
392 397 if not os.path.exists(fixedName):
393 fixedName = root + '.py3' 398 fixedName = absFilename
394 if os.path.exists(fixedName): 399 else:
395 return fixedName 400 fixedName = absFilename
396 401 else:
397 return frame.f_code.co_filename 402 fixedName = frame.f_code.co_filename
403 # update cache
404 self._fnCache[fn] = fixedName
405 return fixedName
398 406
399 def set_watch(self, cond, temporary=False): 407 def set_watch(self, cond, temporary=False):
400 """ 408 """
401 Public method to set a watch expression. 409 Public method to set a watch expression.
402 410
519 See fix_frame_filename for more info. 527 See fix_frame_filename for more info.
520 528
521 @param frame the frame object 529 @param frame the frame object
522 @return flag indicating the break status (boolean) 530 @return flag indicating the break status (boolean)
523 """ 531 """
524 filename = self.canonic(self.fix_frame_filename(frame)) 532 filename = self.fix_frame_filename(frame)
525 if filename not in self.breaks and "Watch" not in self.breaks: 533 if filename not in self.breaks and "Watch" not in self.breaks:
526 return False 534 return False
527 535
528 if filename in self.breaks: 536 if filename in self.breaks:
529 lineno = frame.f_lineno 537 lineno = frame.f_lineno
561 569
562 @param frame the frame object 570 @param frame the frame object
563 @return flag indicating the break status (boolean) 571 @return flag indicating the break status (boolean)
564 """ 572 """
565 return \ 573 return \
566 self.canonic(self.fix_frame_filename(frame)) in self.breaks or \ 574 self.fix_frame_filename(frame) in self.breaks or \
567 ("Watch" in self.breaks and self.breaks["Watch"]) 575 ("Watch" in self.breaks and self.breaks["Watch"])
576
577 def set_break(self, filename, lineno, temporary=0, cond=None,
578 funcname=None):
579 """
580 Public method reimplemented from bdb.py to normalize the filename and
581 set as a breakpoint.
582
583 @param filename the filename where a breakpoint is set
584 @type str
585 @param lineno the line number of the breakpoint
586 @type int
587 @keyparam temporary flag to indicate a temporary breakpoint
588 @type int
589 @keyparam cond Python expression which dynamically enables this bp
590 @type str
591 @keyparam funcname name of the function (unused)
592 @type str or None
593 """
594 filename = os.path.abspath(filename)
595 list = self.breaks.setdefault(filename, [])
596 if lineno not in list:
597 list.append(lineno)
598 bdb.Breakpoint(filename, lineno, temporary, cond, funcname)
568 599
569 def get_break(self, filename, lineno): 600 def get_break(self, filename, lineno):
570 """ 601 """
571 Public method reimplemented from bdb.py to get the first breakpoint of 602 Public method reimplemented from bdb.py to get the first breakpoint of
572 a particular line. 603 a particular line.
573 604
574 Because eric6 supports only one breakpoint per line, this overwritten 605 Because eric6 supports only one breakpoint per line, this overwritten
575 method will return this one and only breakpoint. 606 method will return this one and only breakpoint.
576 607
577 @param filename the filename of the bp to retrieve (string) 608 @param filename the filename of the bp to retrieve
578 @param lineno the linenumber of the bp to retrieve (integer) 609 @type str
610 @param lineno the linenumber of the bp to retrieve
611 @type int
579 @return breakpoint or None, if there is no bp 612 @return breakpoint or None, if there is no bp
580 """ 613 @rtype breakpoint object or None
581 filename = self.canonic(filename) 614 """
582 return filename in self.breaks and \ 615 return (lineno in self.breaks.get(filename, []) and
583 lineno in self.breaks[filename] and \ 616 bdb.Breakpoint.bplist[filename, lineno][0] or None)
584 bdb.Breakpoint.bplist[filename, lineno][0] or None 617
585 618 def clear_break(self, filename, lineno):
619 """
620 Public method reimplemented from bdb.py to clear a breakpoint.
621
622 @param filename the filename of the bp to retrieve
623 @type str
624 @param lineno the linenumber of the bp to retrieve
625 @type int
626 """
627 if (filename, lineno) not in bdb.Breakpoint.bplist:
628 return
629 # If there's only one bp in the list for that file,line
630 # pair, then remove the breaks entry
631 for bp in bdb.Breakpoint.bplist[filename, lineno][:]:
632 bp.deleteMe()
633 self._prune_breaks(filename, lineno)
634
586 def __do_clear(self, filename, lineno): 635 def __do_clear(self, filename, lineno):
587 """ 636 """
588 Private method called to clear a temporary breakpoint. 637 Private method called to clear a temporary breakpoint.
589 638
590 @param filename name of the file the bp belongs to 639 @param filename name of the file the bp belongs to
859 908
860 return bdb.Bdb.stop_here(self, frame) 909 return bdb.Bdb.stop_here(self, frame)
861 910
862 def tracePythonLibs(self, enable): 911 def tracePythonLibs(self, enable):
863 """ 912 """
864 Public methode to update the settings to trace into Python libraries. 913 Public method to update the settings to trace into Python libraries.
865 914
866 @param enable let's debug into Python libraries (int) 915 @param enable flag to debug into Python libraries
916 @type int
867 """ 917 """
868 pathsToSkip = list(self.pathsToSkip) 918 pathsToSkip = list(self.pathsToSkip)
869 # don't trace into Python library? 919 # don't trace into Python library?
870 if enable: 920 if enable:
871 pathsToSkip = [x for x in pathsToSkip if not x.endswith( 921 pathsToSkip = [x for x in pathsToSkip if not x.endswith(
884 934
885 Tracing is turned off for files that are part of the 935 Tracing is turned off for files that are part of the
886 debugger that are called from the application being debugged. 936 debugger that are called from the application being debugged.
887 937
888 @param frame the frame object 938 @param frame the frame object
939 @type frame object
889 @return flag indicating whether the debugger should skip this frame 940 @return flag indicating whether the debugger should skip this frame
941 @rtype bool
890 """ 942 """
891 try: 943 try:
892 return self.filesToSkip[frame.f_code.co_filename] 944 return self.filesToSkip[frame.f_code.co_filename]
893 except KeyError: 945 except KeyError:
894 ret = frame.f_code.co_filename.startswith(self.pathsToSkip) 946 ret = frame.f_code.co_filename.startswith(self.pathsToSkip)

eric ide

mercurial