114 |
114 |
115 from coverage import files |
115 from coverage import files |
116 from coverage.misc import contract, _needs_to_implement |
116 from coverage.misc import contract, _needs_to_implement |
117 |
117 |
118 |
118 |
119 class CoveragePlugin(object): |
119 class CoveragePlugin: |
120 """Base class for coverage.py plug-ins.""" |
120 """Base class for coverage.py plug-ins.""" |
121 |
121 |
122 def file_tracer(self, filename): # pylint: disable=unused-argument |
122 def file_tracer(self, filename): # pylint: disable=unused-argument |
123 """Get a :class:`FileTracer` object for a file. |
123 """Get a :class:`FileTracer` object for a file. |
124 |
124 |
313 """ |
313 """ |
314 lineno = frame.f_lineno |
314 lineno = frame.f_lineno |
315 return lineno, lineno |
315 return lineno, lineno |
316 |
316 |
317 |
317 |
318 class FileReporter(object): |
318 class FileReporter: |
319 """Support needed for files during the analysis and reporting phases. |
319 """Support needed for files during the analysis and reporting phases. |
320 |
320 |
321 File tracer plug-ins implement a subclass of `FileReporter`, and return |
321 File tracer plug-ins implement a subclass of `FileReporter`, and return |
322 instances from their :meth:`CoveragePlugin.file_reporter` method. |
322 instances from their :meth:`CoveragePlugin.file_reporter` method. |
323 |
323 |
357 """Get the source for the file. |
357 """Get the source for the file. |
358 |
358 |
359 Returns a Unicode string. |
359 Returns a Unicode string. |
360 |
360 |
361 The base implementation simply reads the `self.filename` file and |
361 The base implementation simply reads the `self.filename` file and |
362 decodes it as UTF8. Override this method if your file isn't readable |
362 decodes it as UTF-8. Override this method if your file isn't readable |
363 as a text file, or if you need other encoding support. |
363 as a text file, or if you need other encoding support. |
364 |
364 |
365 """ |
365 """ |
366 with open(self.filename, "rb") as f: |
366 with open(self.filename, "rb") as f: |
367 return f.read().decode("utf8") |
367 return f.read().decode("utf-8") |
368 |
368 |
369 def lines(self): |
369 def lines(self): |
370 """Get the executable lines in this file. |
370 """Get the executable lines in this file. |
371 |
371 |
372 Your plug-in must determine which lines in the file were possibly |
372 Your plug-in must determine which lines in the file were possibly |
474 |
474 |
475 By default, this simply returns the string "Line {start} didn't jump |
475 By default, this simply returns the string "Line {start} didn't jump |
476 to {end}". |
476 to {end}". |
477 |
477 |
478 """ |
478 """ |
479 return "Line {start} didn't jump to line {end}".format(start=start, end=end) |
479 return f"Line {start} didn't jump to line {end}" |
480 |
480 |
481 def source_token_lines(self): |
481 def source_token_lines(self): |
482 """Generate a series of tokenized lines, one for each line in `source`. |
482 """Generate a series of tokenized lines, one for each line in `source`. |
483 |
483 |
484 These tokens are used for syntax-colored reports. |
484 These tokens are used for syntax-colored reports. |