eric6/DebugClients/Python/coverage/plugin.py

changeset 7427
362cd1b6f81a
parent 6942
2602857055c5
child 7702
f8b97639deb5
equal deleted inserted replaced
7426:dc171b1d8261 7427:362cd1b6f81a
1 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 1 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
2 # For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt 2 # For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
3 3
4 """ 4 """
5 .. versionadded:: 4.0 5 .. versionadded:: 4.0
6 6
7 Plug-in interfaces for coverage.py. 7 Plug-in interfaces for coverage.py.
11 11
12 * File tracers implement tracing of non-Python file types. 12 * File tracers implement tracing of non-Python file types.
13 13
14 * Configurers add custom configuration, using Python code to change the 14 * Configurers add custom configuration, using Python code to change the
15 configuration. 15 configuration.
16
17 * Dynamic context switchers decide when the dynamic context has changed, for
18 example, to record what test function produced the coverage.
16 19
17 To write a coverage.py plug-in, create a module with a subclass of 20 To write a coverage.py plug-in, create a module with a subclass of
18 :class:`~coverage.CoveragePlugin`. You will override methods in your class to 21 :class:`~coverage.CoveragePlugin`. You will override methods in your class to
19 participate in various aspects of coverage.py's processing. 22 participate in various aspects of coverage.py's processing.
20 Different types of plug-ins have to override different methods. 23 Different types of plug-ins have to override different methods.
52 55
53 One solution is to put your plugins in your project tree, but not in 56 One solution is to put your plugins in your project tree, but not in
54 your importable Python package. 57 your importable Python package.
55 58
56 59
60 .. _file_tracer_plugins:
61
57 File Tracers 62 File Tracers
58 ============ 63 ============
59 64
60 File tracers implement measurement support for non-Python files. File tracers 65 File tracers implement measurement support for non-Python files. File tracers
61 implement the :meth:`~coverage.CoveragePlugin.file_tracer` method to claim 66 implement the :meth:`~coverage.CoveragePlugin.file_tracer` method to claim
64 69
65 In your ``coverage_init`` function, use the ``add_file_tracer`` method to 70 In your ``coverage_init`` function, use the ``add_file_tracer`` method to
66 register your file tracer. 71 register your file tracer.
67 72
68 73
74 .. _configurer_plugins:
75
69 Configurers 76 Configurers
70 =========== 77 ===========
71 78
72 .. versionadded:: 4.5 79 .. versionadded:: 4.5
73 80
76 change the configuration. 83 change the configuration.
77 84
78 In your ``coverage_init`` function, use the ``add_configurer`` method to 85 In your ``coverage_init`` function, use the ``add_configurer`` method to
79 register your configurer. 86 register your configurer.
80 87
88
89 .. _dynamic_context_plugins:
90
91 Dynamic Context Switchers
92 =========================
93
94 .. versionadded:: 5.0
95
96 Dynamic context switcher plugins implement the
97 :meth:`~coverage.CoveragePlugin.dynamic_context` method to dynamically compute
98 the context label for each measured frame.
99
100 Computed context labels are useful when you want to group measured data without
101 modifying the source code.
102
103 For example, you could write a plugin that checks `frame.f_code` to inspect
104 the currently executed method, and set the context label to a fully qualified
105 method name if it's an instance method of `unittest.TestCase` and the method
106 name starts with 'test'. Such a plugin would provide basic coverage grouping
107 by test and could be used with test runners that have no built-in coveragepy
108 support.
109
110 In your ``coverage_init`` function, use the ``add_dynamic_context`` method to
111 register your dynamic context switcher.
112
81 """ 113 """
82 114
83 from coverage import files 115 from coverage import files
84 from coverage.misc import contract, _needs_to_implement 116 from coverage.misc import contract, _needs_to_implement
85 117
92 124
93 Plug-in type: file tracer. 125 Plug-in type: file tracer.
94 126
95 Every Python source file is offered to your plug-in to give it a chance 127 Every Python source file is offered to your plug-in to give it a chance
96 to take responsibility for tracing the file. If your plug-in can 128 to take responsibility for tracing the file. If your plug-in can
97 handle the file, then return a :class:`FileTracer` object. Otherwise 129 handle the file, it should return a :class:`FileTracer` object.
98 return None. 130 Otherwise return None.
99 131
100 There is no way to register your plug-in for particular files. 132 There is no way to register your plug-in for particular files.
101 Instead, this method is invoked for all files, and the plug-in decides 133 Instead, this method is invoked for all files as they are executed,
102 whether it can trace the file or not. Be prepared for `filename` to 134 and the plug-in decides whether it can trace the file or not.
103 refer to all kinds of files that have nothing to do with your plug-in. 135 Be prepared for `filename` to refer to all kinds of files that have
136 nothing to do with your plug-in.
104 137
105 The file name will be a Python file being executed. There are two 138 The file name will be a Python file being executed. There are two
106 broad categories of behavior for a plug-in, depending on the kind of 139 broad categories of behavior for a plug-in, depending on the kind of
107 files your plug-in supports: 140 files your plug-in supports:
108 141
132 Plug-in type: file tracer. 165 Plug-in type: file tracer.
133 166
134 This will only be invoked if `filename` returns non-None from 167 This will only be invoked if `filename` returns non-None from
135 :meth:`file_tracer`. It's an error to return None from this method. 168 :meth:`file_tracer`. It's an error to return None from this method.
136 169
137 Returns a :class:`FileReporter` object to use to report on `filename`. 170 Returns a :class:`FileReporter` object to use to report on `filename`,
171 or the string `"python"` to have coverage.py treat the file as Python.
138 172
139 """ 173 """
140 _needs_to_implement(self, "file_reporter") 174 _needs_to_implement(self, "file_reporter")
175
176 def dynamic_context(self, frame): # pylint: disable=unused-argument
177 """Get the dynamically computed context label for `frame`.
178
179 Plug-in type: dynamic context.
180
181 This method is invoked for each frame when outside of a dynamic
182 context, to see if a new dynamic context should be started. If it
183 returns a string, a new context label is set for this and deeper
184 frames. The dynamic context ends when this frame returns.
185
186 Returns a string to start a new dynamic context, or None if no new
187 context should be started.
188
189 """
190 return None
141 191
142 def find_executable_files(self, src_dir): # pylint: disable=unused-argument 192 def find_executable_files(self, src_dir): # pylint: disable=unused-argument
143 """Yield all of the executable files in `src_dir`, recursively. 193 """Yield all of the executable files in `src_dir`, recursively.
144 194
145 Plug-in type: file tracer. 195 Plug-in type: file tracer.

eric ide

mercurial