eric6/DebugClients/Python/coverage/plugin.py

changeset 7427
362cd1b6f81a
parent 6942
2602857055c5
child 7702
f8b97639deb5
diff -r dc171b1d8261 -r 362cd1b6f81a eric6/DebugClients/Python/coverage/plugin.py
--- a/eric6/DebugClients/Python/coverage/plugin.py	Wed Feb 19 19:38:36 2020 +0100
+++ b/eric6/DebugClients/Python/coverage/plugin.py	Sat Feb 22 14:27:42 2020 +0100
@@ -1,5 +1,5 @@
 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
-# For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
+# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
 
 """
 .. versionadded:: 4.0
@@ -14,6 +14,9 @@
 * Configurers add custom configuration, using Python code to change the
   configuration.
 
+* Dynamic context switchers decide when the dynamic context has changed, for
+  example, to record what test function produced the coverage.
+
 To write a coverage.py plug-in, create a module with a subclass of
 :class:`~coverage.CoveragePlugin`.  You will override methods in your class to
 participate in various aspects of coverage.py's processing.
@@ -54,6 +57,8 @@
     your importable Python package.
 
 
+.. _file_tracer_plugins:
+
 File Tracers
 ============
 
@@ -66,6 +71,8 @@
 register your file tracer.
 
 
+.. _configurer_plugins:
+
 Configurers
 ===========
 
@@ -78,6 +85,31 @@
 In your ``coverage_init`` function, use the ``add_configurer`` method to
 register your configurer.
 
+
+.. _dynamic_context_plugins:
+
+Dynamic Context Switchers
+=========================
+
+.. versionadded:: 5.0
+
+Dynamic context switcher plugins implement the
+:meth:`~coverage.CoveragePlugin.dynamic_context` method to dynamically compute
+the context label for each measured frame.
+
+Computed context labels are useful when you want to group measured data without
+modifying the source code.
+
+For example, you could write a plugin that checks `frame.f_code` to inspect
+the currently executed method, and set the context label to a fully qualified
+method name if it's an instance method of `unittest.TestCase` and the method
+name starts with 'test'.  Such a plugin would provide basic coverage grouping
+by test and could be used with test runners that have no built-in coveragepy
+support.
+
+In your ``coverage_init`` function, use the ``add_dynamic_context`` method to
+register your dynamic context switcher.
+
 """
 
 from coverage import files
@@ -94,13 +126,14 @@
 
         Every Python source file is offered to your plug-in to give it a chance
         to take responsibility for tracing the file.  If your plug-in can
-        handle the file, then return a :class:`FileTracer` object.  Otherwise
-        return None.
+        handle the file, it should return a :class:`FileTracer` object.
+        Otherwise return None.
 
         There is no way to register your plug-in for particular files.
-        Instead, this method is invoked for all files, and the plug-in decides
-        whether it can trace the file or not.  Be prepared for `filename` to
-        refer to all kinds of files that have nothing to do with your plug-in.
+        Instead, this method is invoked for all  files as they are executed,
+        and the plug-in decides whether it can trace the file or not.
+        Be prepared for `filename` to refer to all kinds of files that have
+        nothing to do with your plug-in.
 
         The file name will be a Python file being executed.  There are two
         broad categories of behavior for a plug-in, depending on the kind of
@@ -134,11 +167,28 @@
         This will only be invoked if `filename` returns non-None from
         :meth:`file_tracer`.  It's an error to return None from this method.
 
-        Returns a :class:`FileReporter` object to use to report on `filename`.
+        Returns a :class:`FileReporter` object to use to report on `filename`,
+        or the string `"python"` to have coverage.py treat the file as Python.
 
         """
         _needs_to_implement(self, "file_reporter")
 
+    def dynamic_context(self, frame):       # pylint: disable=unused-argument
+        """Get the dynamically computed context label for `frame`.
+
+        Plug-in type: dynamic context.
+
+        This method is invoked for each frame when outside of a dynamic
+        context, to see if a new dynamic context should be started.  If it
+        returns a string, a new context label is set for this and deeper
+        frames.  The dynamic context ends when this frame returns.
+
+        Returns a string to start a new dynamic context, or None if no new
+        context should be started.
+
+        """
+        return None
+
     def find_executable_files(self, src_dir):       # pylint: disable=unused-argument
         """Yield all of the executable files in `src_dir`, recursively.
 

eric ide

mercurial