Yet another updates and optimizations from PyDev.Debugger

This commit is contained in:
Elizaveta Shashkova
2015-08-28 12:27:52 +03:00
parent a397a00006
commit 3e62b1aee5
4 changed files with 59 additions and 44 deletions
+22 -28
View File
@@ -3,6 +3,7 @@ from __future__ import nested_scopes # Jython 2.1 support
import pydev_monkey_qt
from pydevd_utils import save_main_module
import pydevd_utils
pydev_monkey_qt.patch_qt()
@@ -28,7 +29,7 @@ from pydevd_comm import CMD_CHANGE_VARIABLE, \
CMD_STEP_OVER, \
CMD_STEP_RETURN, \
CMD_STEP_INTO_MY_CODE, \
CMD_THREAD_KILL, \
CMD_THREAD_KILL, \
CMD_THREAD_RUN, \
CMD_THREAD_SUSPEND, \
CMD_RUN_TO_LINE, \
@@ -51,7 +52,7 @@ from pydevd_comm import CMD_CHANGE_VARIABLE, \
InternalTerminateThread, \
InternalRunThread, \
InternalStepThread, \
NetCommandFactory, \
NetCommandFactory, \
PyDBDaemonThread, \
_queue, \
ReaderThread, \
@@ -63,15 +64,18 @@ from pydevd_comm import CMD_CHANGE_VARIABLE, \
StartServer, \
InternalSetNextStatementThread, \
ReloadCodeCommand, \
CMD_SET_PY_EXCEPTION, \
CMD_SET_PY_EXCEPTION, \
CMD_IGNORE_THROWN_EXCEPTION_AT,\
InternalGetBreakpointException, \
InternalSendCurrExceptionTrace,\
InternalSendCurrExceptionTraceProceeded,\
CMD_ENABLE_DONT_TRACE, \
CMD_GET_FILE_CONTENTS,\
CMD_SET_PROPERTY_TRACE, CMD_RUN_CUSTOM_OPERATION,\
InternalRunCustomOperation, CMD_EVALUATE_CONSOLE_EXPRESSION, InternalEvaluateConsoleExpression,\
CMD_SET_PROPERTY_TRACE, \
CMD_RUN_CUSTOM_OPERATION,\
InternalRunCustomOperation, \
CMD_EVALUATE_CONSOLE_EXPRESSION, \
InternalEvaluateConsoleExpression,\
InternalConsoleGetCompletions
from pydevd_file_utils import NormFileToServer, GetFilenameAndBase
@@ -194,14 +198,14 @@ if hasattr(_temp, '_is_stopped'): # Python 3.4 has this
return not t._is_stopped
except:
return t.isAlive()
elif hasattr(_temp, '_Thread__stopped'): # Python 2.7 has this
def isThreadAlive(t):
try:
return not t._Thread__stopped
except:
return t.isAlive()
else: # Haven't checked all other versions, so, let's use the regular isAlive call in this case.
def isThreadAlive(t):
return t.isAlive()
@@ -378,26 +382,16 @@ class PyDB:
self.mpl_in_use = False
self.mpl_hooks_in_debug_console = False
self.mpl_modules_for_patching = {}
self._filename_to_not_in_scope = {}
def get_plugin_lazy_init(self):
if self.plugin is None and SUPPORT_PLUGINS:
self.plugin = PluginManager(self)
return self.plugin
def get_project_roots(self):
if self.project_roots is None:
roots = os.getenv('IDE_PROJECT_ROOTS', '').split(os.pathsep)
pydev_log.debug("IDE_PROJECT_ROOTS %s\n" % roots)
self.project_roots = roots
def not_in_scope(self, filename):
self.get_project_roots()
filename = os.path.normcase(filename)
for root in self.project_roots:
root = os.path.normcase(root)
if filename.startswith(root):
return False
return True
return pydevd_utils.is_in_project_roots(filename)
def first_appearance_in_scope(self, trace):
if trace is None or self.not_in_scope(trace.tb_frame.f_code.co_filename):
@@ -1217,10 +1211,10 @@ class PyDB:
update_exception_hook(self)
else:
supported_type = False
# I.e.: no need to initialize lazy (if we didn't have it in the first place, we can't remove
# anything from it anyways).
plugin = self.plugin
plugin = self.plugin
if plugin is not None:
supported_type = plugin.remove_exception_breakpoint(self, type, exception)
@@ -2078,15 +2072,15 @@ def stoptrace():
from pydev_monkey import undo_patch_thread_modules
undo_patch_thread_modules()
debugger = GetGlobalDebugger()
if debugger:
debugger.SetTraceForFrameAndParents(
GetFrame(), also_add_to_passed_frame=True, overwrite_prev_trace=True, dispatch_func=lambda *args:None)
debugger.exiting()
killAllPydevThreads()
connected = False
@@ -2118,7 +2112,7 @@ class DispatchReader(ReaderThread):
dummy_thread = threading.currentThread()
dummy_thread.is_pydev_daemon_thread = False
return ReaderThread.OnRun(self)
def handleExcept(self):
ReaderThread.handleExcept(self)
@@ -2182,7 +2176,7 @@ class SetupHolder:
# main
#=======================================================================================================================
if __name__ == '__main__':
# parse the command line. --file is our last argument that is required
try:
sys.original_argv = sys.argv[:]
+4 -4
View File
@@ -96,19 +96,19 @@ def _excepthook(exctype, value, tb):
frames = []
debugger = GetGlobalDebugger()
user_frames = []
user_frame = None
while tb:
frame = tb.tb_frame
if exception_breakpoint.ignore_libraries and not debugger.not_in_scope(frame.f_code.co_filename):
user_frames.append(tb.tb_frame)
user_frame = tb.tb_frame
frames.append(tb.tb_frame)
tb = tb.tb_next
thread = threadingCurrentThread()
frames_byid = dict([(id(frame),frame) for frame in frames])
if exception_breakpoint.ignore_libraries:
frame = user_frames[-1]
if exception_breakpoint.ignore_libraries and user_frame is not None:
frame = user_frame
else:
frame = frames[-1]
thread.additionalInfo.exception = (exctype, value, tb)
+1 -9
View File
@@ -31,17 +31,9 @@ class Signature(object):
class SignatureFactory(object):
def __init__(self):
self._caller_cache = {}
self.project_roots = os.getenv('IDE_PROJECT_ROOTS', '').split(os.pathsep)
def is_in_scope(self, filename):
filename = os.path.normcase(filename)
for root in self.project_roots:
root = os.path.normcase(root)
if filename.startswith(root):
return True
return False
return pydevd_utils.is_in_project_roots(filename)
def create_signature(self, frame):
try:
+32 -3
View File
@@ -5,9 +5,10 @@ try:
except:
from urllib.parse import quote
import os
import pydevd_constants
import sys
import pydev_log
def save_main_module(file, module_name):
# patch provided by: Scott Schlesier - when script is run, it does not
@@ -113,7 +114,35 @@ def quote_smart(s, safe='/'):
s = s.encode('utf-8')
return quote(s, safe)
def _get_project_roots(project_roots_cache=[]):
# Note: the project_roots_cache is the same instance among the many calls to the method
if not project_roots_cache:
roots = os.getenv('IDE_PROJECT_ROOTS', '').split(os.pathsep)
pydev_log.debug("IDE_PROJECT_ROOTS %s\n" % roots)
new_roots = []
for root in roots:
new_roots.append(os.path.normcase(root))
project_roots_cache.append(new_roots)
return project_roots_cache[-1] # returns the project roots with case normalized
def is_in_project_roots(filename, filename_to_not_in_scope_cache={}):
# Note: the filename_to_not_in_scope_cache is the same instance among the many calls to the method
try:
return filename_to_not_in_scope_cache[filename]
except:
project_roots = _get_project_roots()
filename = os.path.normcase(filename)
for root in project_roots:
if filename.startswith(root):
filename_to_not_in_scope_cache[filename] = False
break
else: # for else (only called if the break wasn't reached).
filename_to_not_in_scope_cache[filename] = True
# at this point it must be loaded.
return filename_to_not_in_scope_cache[filename]