DebugClients/Python/DebugBase.py

branch
debugger speed
changeset 5007
e2fa12bb0f53
parent 5005
684f5ba04f0b
child 5012
be693f11da53
equal deleted inserted replaced
5006:82e91d2f59a1 5007:e2fa12bb0f53
52 # on Windows 52 # on Windows
53 lib = os.path.dirname(bdb.__file__) 53 lib = os.path.dirname(bdb.__file__)
54 # tuple required because it's accessed a lot of times by startswith method 54 # tuple required because it's accessed a lot of times by startswith method
55 pathsToSkip = ('<', os.path.dirname(__file__), bdb.__file__[:-1]) 55 pathsToSkip = ('<', os.path.dirname(__file__), bdb.__file__[:-1])
56 filesToSkip = {} 56 filesToSkip = {}
57
58 # cache for fixed file names
59 _fnCache = {}
57 60
58 def __init__(self, dbgClient): 61 def __init__(self, dbgClient):
59 """ 62 """
60 Constructor 63 Constructor
61 64
355 this can break debugging as the .pyc will refer to the .py 358 this can break debugging as the .pyc will refer to the .py
356 on the original machine. Another case might be sharing 359 on the original machine. Another case might be sharing
357 code over a network... This logic deals with that. 360 code over a network... This logic deals with that.
358 361
359 @param frame the frame object 362 @param frame the frame object
360 @return fixed up file name (string) 363 @type frame object
364 @return fixed up file name
365 @rtype str
361 """ 366 """
362 # get module name from __file__ 367 # get module name from __file__
363 if '__file__' in frame.f_globals and \ 368 fn = frame.f_globals.get('__file__')
364 frame.f_globals['__file__'] and \ 369 try:
365 frame.f_globals['__file__'] == frame.f_code.co_filename: 370 return self._fnCache[fn]
366 root, ext = os.path.splitext(frame.f_globals['__file__']) 371 except KeyError:
367 if ext == '.pyc' or ext == '.py' or ext == '.pyo': 372 if fn and fn != frame.f_code.co_filename:
368 fixedName = root + '.py' 373 absFilename = os.path.abspath(fn)
369 if os.path.exists(fixedName): 374 if absFilename.endswith(('.pyc', '.pyo')):
370 return fixedName 375 fixedName = absFilename[:-1]
371 376 if not os.path.exists(fixedName):
372 return frame.f_code.co_filename 377 fixedName = absFilename
378 else:
379 fixedName = absFilename
380 else:
381 fixedName = frame.f_code.co_filename
382 # update cache
383 self._fnCache[fn] = fixedName
384 return fixedName
373 385
374 def set_watch(self, cond, temporary=0): 386 def set_watch(self, cond, temporary=0):
375 """ 387 """
376 Public method to set a watch expression. 388 Public method to set a watch expression.
377 389
493 See fix_frame_filename for more info. 505 See fix_frame_filename for more info.
494 506
495 @param frame the frame object 507 @param frame the frame object
496 @return flag indicating the break status (boolean) 508 @return flag indicating the break status (boolean)
497 """ 509 """
498 filename = self.canonic(self.fix_frame_filename(frame)) 510 filename = self.fix_frame_filename(frame)
499 if filename not in self.breaks and "Watch" not in self.breaks: 511 if filename not in self.breaks and "Watch" not in self.breaks:
500 return 0 512 return 0
501 513
502 if filename in self.breaks: 514 if filename in self.breaks:
503 lineno = frame.f_lineno 515 lineno = frame.f_lineno
530 542
531 @param frame the frame object 543 @param frame the frame object
532 @return flag indicating the break status (boolean) 544 @return flag indicating the break status (boolean)
533 """ 545 """
534 return \ 546 return \
535 self.canonic(self.fix_frame_filename(frame)) in self.breaks or \ 547 self.fix_frame_filename(frame) in self.breaks or \
536 ("Watch" in self.breaks and self.breaks["Watch"]) 548 ("Watch" in self.breaks and self.breaks["Watch"])
549
550 def set_break(self, filename, lineno, temporary=0, cond=None,
551 funcname=None):
552 """
553 Public method reimplemented from bdb.py to normalize the filename and
554 set as a breakpoint.
555
556 @param filename the filename where a breakpoint is set
557 @type str
558 @param lineno the line number of the breakpoint
559 @type int
560 @keyparam temporary flag to indicate a temporary breakpoint
561 @type int
562 @keyparam cond Python expression which dynamically enables this bp
563 @type str
564 @keyparam funcname name of the function (unused)
565 @type str or None
566 """
567 filename = os.path.abspath(filename)
568 list = self.breaks.setdefault(filename, [])
569 if lineno not in list:
570 list.append(lineno)
571 bdb.Breakpoint(filename, lineno, temporary, cond, funcname)
537 572
538 def get_break(self, filename, lineno): 573 def get_break(self, filename, lineno):
539 """ 574 """
540 Public method reimplemented from bdb.py to get the first breakpoint of 575 Public method reimplemented from bdb.py to get the first breakpoint of
541 a particular line. 576 a particular line.
542 577
543 Because eric6 supports only one breakpoint per line, this overwritten 578 Because eric6 supports only one breakpoint per line, this overwritten
544 method will return this one and only breakpoint. 579 method will return this one and only breakpoint.
545 580
546 @param filename the filename of the bp to retrieve (string) 581 @param filename the filename of the bp to retrieve
547 @param lineno the linenumber of the bp to retrieve (integer) 582 @type str
583 @param lineno the linenumber of the bp to retrieve
584 @type int
548 @return breakpoint or None, if there is no bp 585 @return breakpoint or None, if there is no bp
549 """ 586 @rtype breakpoint object or None
550 filename = self.canonic(filename) 587 """
551 return filename in self.breaks and \ 588 return (lineno in self.breaks.get(filename, []) and
552 lineno in self.breaks[filename] and \ 589 bdb.Breakpoint.bplist[filename, lineno][0] or None)
553 bdb.Breakpoint.bplist[filename, lineno][0] or None 590
554 591 def clear_break(self, filename, lineno):
592 """
593 Public method reimplemented from bdb.py to clear a breakpoint.
594
595 @param filename the filename of the bp to retrieve
596 @type str
597 @param lineno the linenumber of the bp to retrieve
598 @type int
599 """
600 if (filename, lineno) not in bdb.Breakpoint.bplist:
601 return
602 # If there's only one bp in the list for that file,line
603 # pair, then remove the breaks entry
604 for bp in bdb.Breakpoint.bplist[filename, lineno][:]:
605 bp.deleteMe()
606 self._prune_breaks(filename, lineno)
607
555 def __do_clear(self, filename, lineno): 608 def __do_clear(self, filename, lineno):
556 """ 609 """
557 Private method called to clear a temporary breakpoint. 610 Private method called to clear a temporary breakpoint.
558 611
559 @param filename name of the file the bp belongs to 612 @param filename name of the file the bp belongs to
810 return 0 863 return 0
811 return bdb.Bdb.stop_here(self, frame) 864 return bdb.Bdb.stop_here(self, frame)
812 865
813 def tracePythonLibs(self, enable): 866 def tracePythonLibs(self, enable):
814 """ 867 """
815 Public methode to update the settings to trace into Python libraries. 868 Public method to update the settings to trace into Python libraries.
816 869
817 @param enable let's debug into Python libraries (int) 870 @param enable flag to debug into Python libraries
871 @type int
818 """ 872 """
819 pathsToSkip = list(self.pathsToSkip) 873 pathsToSkip = list(self.pathsToSkip)
820 # don't trace into Python library? 874 # don't trace into Python library?
821 if enable: 875 if enable:
822 pathsToSkip = [x for x in pathsToSkip if not x.endswith( 876 pathsToSkip = [x for x in pathsToSkip if not x.endswith(
835 889
836 Tracing is turned off for files that are part of the 890 Tracing is turned off for files that are part of the
837 debugger that are called from the application being debugged. 891 debugger that are called from the application being debugged.
838 892
839 @param frame the frame object 893 @param frame the frame object
894 @type frame object
840 @return flag indicating whether the debugger should skip this frame 895 @return flag indicating whether the debugger should skip this frame
896 @rtype bool
841 """ 897 """
842 try: 898 try:
843 return self.filesToSkip[frame.f_code.co_filename] 899 return self.filesToSkip[frame.f_code.co_filename]
844 except KeyError: 900 except KeyError:
845 ret = frame.f_code.co_filename.startswith(self.pathsToSkip) 901 ret = frame.f_code.co_filename.startswith(self.pathsToSkip)

eric ide

mercurial