DebugClients/Python/ThreadExtension.py

branch
maintenance
changeset 5680
b93cb6353cc0
parent 5598
0e59df936fb6
parent 5667
86554f131048
child 5948
6f958d5765f4
--- a/DebugClients/Python/ThreadExtension.py	Thu Mar 23 18:58:56 2017 +0100
+++ b/DebugClients/Python/ThreadExtension.py	Fri Apr 07 18:33:59 2017 +0200
@@ -39,6 +39,7 @@
         self._original_start_new_thread = None
         self.threadingAttached = False
         self.qtThreadAttached = False
+        self.greenlet = False
         
         self.clientLock = threading.RLock()
         
@@ -64,7 +65,7 @@
         
         sys.meta_path.insert(0, self)
 
-    def attachThread(self, target=None, args=None, kwargs={},
+    def attachThread(self, target=None, args=None, kwargs=None,
                      mainThread=False):
         """
         Public method to setup a standard thread for DebugClient to debug.
@@ -80,6 +81,9 @@
               started mainthread of the app
         @return identifier of the created thread
         """
+        if kwargs is None:
+            kwargs = {}
+        
         if mainThread:
             ident = _thread.get_ident()
             name = 'MainThread'
@@ -140,19 +144,19 @@
         except AssertionError:
             pass
     
-    def setCurrentThread(self, id):
+    def setCurrentThread(self, threadId):
         """
         Public method to set the current thread.
 
-        @param id the id the current thread should be set to.
+        @param threadId the id the current thread should be set to.
         @type int
         """
         try:
             self.lockClient()
-            if id is None:
+            if threadId is None:
                 self.currentThread = None
             else:
-                self.currentThread = self.threads.get(id)
+                self.currentThread = self.threads.get(threadId)
         finally:
             self.unlockClient()
     
@@ -167,10 +171,10 @@
             # update thread names set by user (threading.setName)
             threadNames = {t.ident: t.getName() for t in threading.enumerate()}
             
-            for id, thd in self.threads.items():
-                d = {"id": id}
+            for threadId, thd in self.threads.items():
+                d = {"id": threadId}
                 try:
-                    d["name"] = threadNames.get(id, thd.name)
+                    d["name"] = threadNames.get(threadId, thd.name)
                     d["broken"] = thd.isBroken
                 except Exception:
                     d["name"] = 'UnknownThread'
@@ -215,28 +219,28 @@
         Public method to update the list of running threads.
         """
         frames = sys._current_frames()
-        for id, frame in frames.items():
+        for threadId, frame in frames.items():
             # skip our own timer thread
             if frame.f_code.co_name == '__eventPollTimer':
                 continue
             
             # Unknown thread
-            if id not in self.threads:
+            if threadId not in self.threads:
                 newThread = DebugBase(self)
                 name = 'Thread-{0}'.format(self.threadNumber)
                 self.threadNumber += 1
                 
-                newThread.id = id
+                newThread.id = threadId
                 newThread.name = name
-                self.threads[id] = newThread
+                self.threads[threadId] = newThread
             
             # adjust current frame
             if "__pypy__" not in sys.builtin_module_names:
                 # Don't update with None
                 currentFrame = self.getExecutedFrame(frame)
                 if (currentFrame is not None and
-                        self.threads[id].isBroken is False):
-                    self.threads[id].currentFrame = currentFrame
+                        self.threads[threadId].isBroken is False):
+                    self.threads[threadId].currentFrame = currentFrame
         
         # Clean up obsolet because terminated threads
         self.threads = {id_: thrd for id_, thrd in self.threads.items()
@@ -257,7 +261,7 @@
             return None
         
         if fullname in [self.threadModName, 'PyQt4.QtCore', 'PyQt5.QtCore',
-                        'PySide.QtCore', 'PySide2.QtCore',
+                        'PySide.QtCore', 'PySide2.QtCore', 'greenlet',
                         'threading'] and self.enableImportHooks:
             # Disable hook to be able to import original module
             self.enableImportHooks = False
@@ -282,6 +286,14 @@
             self._original_start_new_thread = module.start_new_thread
             module.start_new_thread = self.attachThread
 
+        elif (fullname == 'greenlet' and self.greenlet is False):
+            # Check for greenlet.settrace
+            if hasattr(module, 'settrace'):
+                self.greenlet = True
+                DebugBase.pollTimerEnabled = False
+            
+            # TODO: Implement the debugger extension for greenlets
+        
         # Add hook for threading.run()
         elif (fullname == "threading" and self.threadingAttached is False):
             self.threadingAttached = True
@@ -297,7 +309,8 @@
                 @param run the run method of threading.Thread
                 @type method pointer
                 """
-                newThread = _debugClient.threads[self.ident]
+                newThread = DebugBase(_debugClient)
+                _debugClient.threads[self.ident] = newThread
                 newThread.name = self.name
                 # see DebugBase.bootstrap
                 sys.settrace(newThread.trace_dispatch)

eric ide

mercurial