MCPcopy Index your code
hub / github.com/python/mypy / LineCoverageVisitor

Class LineCoverageVisitor

mypy/report.py:315–403  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

313
314
315class LineCoverageVisitor(TraverserVisitor):
316 def __init__(self, source: list[str]) -> None:
317 self.source = source
318
319 # For each line of source, we maintain a pair of
320 # * the indentation level of the surrounding function
321 # (-1 if not inside a function), and
322 # * whether the surrounding function is typed.
323 # Initially, everything is covered at indentation level -1.
324 self.lines_covered = [(-1, True) for l in source]
325
326 # The Python AST has position information for the starts of
327 # elements, but not for their ends. Fortunately the
328 # indentation-based syntax makes it pretty easy to find where a
329 # block ends without doing any real parsing.
330
331 # TODO: Handle line continuations (explicit and implicit) and
332 # multi-line string literals. (But at least line continuations
333 # are normally more indented than their surrounding block anyways,
334 # by PEP 8.)
335
336 def indentation_level(self, line_number: int) -> int | None:
337 """Return the indentation of a line of the source (specified by
338 zero-indexed line number). Returns None for blank lines or comments."""
339 line = self.source[line_number]
340 indent = 0
341 for char in list(line):
342 if char == " ":
343 indent += 1
344 elif char == "\t":
345 indent = 8 * ((indent + 8) // 8)
346 elif char == "#":
347 # Line is a comment; ignore it
348 return None
349 elif char == "\n":
350 # Line is entirely whitespace; ignore it
351 return None
352 # TODO line continuation (\)
353 else:
354 # Found a non-whitespace character
355 return indent
356 # Line is entirely whitespace, and at end of file
357 # with no trailing newline; ignore it
358 return None
359
360 def visit_func_def(self, defn: FuncDef) -> None:
361 start_line = defn.line - 1
362 start_indent = None
363 # When a function is decorated, sometimes the start line will point to
364 # whitespace or comments between the decorator and the function, so
365 # we have to look for the start.
366 while start_line < len(self.source):
367 start_indent = self.indentation_level(start_line)
368 if start_indent is not None:
369 break
370 start_line += 1
371 # If we can't find the function give up and don't annotate anything.
372 # Our line numbers are not reliable enough to be asserting on.

Callers 1

on_fileMethod · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…