Commits

Ned Batchelder  committed 594017f Merge

Automated merge with ssh://bitbucket.org/ned/coveragepy

  • Participants
  • Parent commits 57f348c, 8649f08

Comments (0)

Files changed (3)

 
 - Improved the branch coverage mechanism, fixing `issue 175`_.
 
+- When running a threaded program under the Python tracer, coverage would issue
+  a spurious warning about the trace function changing: "Trace function
+  changed, measurement is likely wrong: None." This is now fixed.
+
+.. _issue 164: https://bitbucket.org/ned/coveragepy/issue/164/trace-function-changed-warning-when-using
 .. _issue 175: https://bitbucket.org/ned/coveragepy/issue/175/branch-coverage-gets-confused-in-certain
 
 

File coverage/collector.py

         self.last_exc_back = None
         self.last_exc_firstlineno = 0
         self.arcs = False
+        self.thread = None
 
     def _trace(self, frame, event, arg_unused):
         """The trace function passed to sys.settrace."""
         Return a Python function suitable for use with sys.settrace().
 
         """
+        self.thread = threading.currentThread()
         sys.settrace(self._trace)
         return self._trace
 
     def stop(self):
         """Stop this Tracer."""
+        if self.thread != threading.currentThread():
+            # Called on a different thread than started us: do nothing.
+            return
+
         if hasattr(sys, "gettrace") and self.warn:
             if sys.gettrace() != self._trace:
                 msg = "Trace function changed, measurement is likely wrong: %r"
                 self.warn(msg % (sys.gettrace(),))
-                #--debug
-                #from coverage.misc import short_stack
-                #self.warn(msg % (sys.gettrace()))#, short_stack()))
+        #print("Stopping tracer on %s" % threading.current_thread().ident)
         sys.settrace(None)
 
     def get_stats(self):

File tests/test_process.py

         self.assertNotIn("warning", out)
         self.assertNotIn("Exception", out)
 
+    def test_warnings_trace_function_changed_with_threads(self):
+        # https://bitbucket.org/ned/coveragepy/issue/164
+        self.make_file("bug164.py", """\
+            import threading
+            import time
+
+            class MyThread (threading.Thread):
+                def run(self):
+                    print("Hello")
+
+            thr = MyThread()
+            thr.start()
+            thr.join()
+            """)
+        out = self.run_command("coverage run --timid bug164.py")
+
+        self.assertIn("Hello\n", out)
+        self.assertNotIn("warning", out)
+
+    def test_warning_trace_function_changed(self):
+        self.make_file("settrace.py", """\
+            import sys
+            print("Hello")
+            sys.settrace(None)
+            print("Goodbye")
+            """)
+        out = self.run_command("coverage run --timid settrace.py")
+        self.assertIn("Hello\n", out)
+        self.assertIn("Goodbye\n", out)
+
+        if hasattr(sys, "gettrace"):
+            self.assertIn("Trace function changed", out)
+
     if sys.version_info >= (3, 0):   # This only works on 3.x for now.
         # It only works with the C tracer,
         c_tracer = os.getenv('COVERAGE_TEST_TRACER', 'c') == 'c'