eric7/DebugClients/Python/coverage/parser.py

Thu, 30 Dec 2021 11:17:58 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Thu, 30 Dec 2021 11:17:58 +0100
branch
eric7
changeset 8881
54e42bc2437a
parent 8775
0802ae193343
child 8929
fcca2fa618bf
permissions
-rw-r--r--

Updated copyright for 2022.

4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
1 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6942
diff changeset
2 # For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
3
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
4 """Code parsing for coverage.py."""
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
5
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
6 import ast
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
7 import collections
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
8 import os
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
9 import re
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
10 import token
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
11 import tokenize
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
12
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
13 from coverage import env
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6942
diff changeset
14 from coverage.bytecode import code_objects
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
15 from coverage.debug import short_stack
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
16 from coverage.exceptions import NoSource, NotPython, StopEverything
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
17 from coverage.misc import contract, join_regex, new_contract, nice_pair, one_of
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
18 from coverage.phystokens import compile_unicode, generate_tokens, neuter_encoding_declaration
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
19
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
20
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
21 class PythonParser:
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
22 """Parse code to find executable lines, excluded lines, etc.
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
23
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
24 This information is all based on static analysis: no code execution is
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
25 involved.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
26
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
27 """
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
28 @contract(text='unicode|None')
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
29 def __init__(self, text=None, filename=None, exclude=None):
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
30 """
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
31 Source can be provided as `text`, the text itself, or `filename`, from
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
32 which the text will be read. Excluded lines are those that match
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
33 `exclude`, a regex.
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
34
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
35 """
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
36 assert text or filename, "PythonParser needs either text or filename"
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
37 self.filename = filename or "<code>"
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
38 self.text = text
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
39 if not self.text:
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
40 from coverage.python import get_python_source
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
41 try:
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
42 self.text = get_python_source(self.filename)
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
43 except OSError as err:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
44 raise NoSource(f"No source for code: '{self.filename}': {err}") from err
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
45
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
46 self.exclude = exclude
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
47
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
48 # The text lines of the parsed code.
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
49 self.lines = self.text.split('\n')
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
50
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
51 # The normalized line numbers of the statements in the code. Exclusions
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
52 # are taken into account, and statements are adjusted to their first
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
53 # lines.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
54 self.statements = set()
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
55
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
56 # The normalized line numbers of the excluded lines in the code,
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
57 # adjusted to their first lines.
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
58 self.excluded = set()
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
59
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
60 # The raw_* attributes are only used in this class, and in
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
61 # lab/parser.py to show how this class is working.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
62
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
63 # The line numbers that start statements, as reported by the line
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
64 # number table in the bytecode.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
65 self.raw_statements = set()
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
66
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
67 # The raw line numbers of excluded lines of code, as marked by pragmas.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
68 self.raw_excluded = set()
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
69
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
70 # The line numbers of class and function definitions.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
71 self.raw_classdefs = set()
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
72
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
73 # The line numbers of docstring lines.
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
74 self.raw_docstrings = set()
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
75
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
76 # Internal detail, used by lab/parser.py.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
77 self.show_tokens = False
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
78
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
79 # A dict mapping line numbers to lexical statement starts for
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
80 # multi-line statements.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
81 self._multiline = {}
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
82
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
83 # Lazily-created arc data, and missing arc descriptions.
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
84 self._all_arcs = None
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
85 self._missing_arc_fragments = None
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
86
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
87 def lines_matching(self, *regexes):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
88 """Find the lines matching one of a list of regexes.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
89
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
90 Returns a set of line numbers, the lines that contain a match for one
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
91 of the regexes in `regexes`. The entire line needn't match, just a
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
92 part of it.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
93
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
94 """
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
95 combined = join_regex(regexes)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
96 regex_c = re.compile(combined)
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
97 matches = set()
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
98 for i, ltext in enumerate(self.lines, start=1):
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
99 if regex_c.search(ltext):
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
100 matches.add(i)
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
101 return matches
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
102
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
103 def _raw_parse(self):
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
104 """Parse the source to find the interesting facts about its lines.
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
105
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
106 A handful of attributes are updated.
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
107
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
108 """
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
109 # Find lines which match an exclusion pattern.
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
110 if self.exclude:
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
111 self.raw_excluded = self.lines_matching(self.exclude)
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
112
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
113 # Tokenize, to find excluded suites, to find docstrings, and to find
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
114 # multi-line statements.
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
115 indent = 0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
116 exclude_indent = 0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
117 excluding = False
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
118 excluding_decorators = False
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
119 prev_toktype = token.INDENT
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
120 first_line = None
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
121 empty = True
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
122 first_on_line = True
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
123
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
124 tokgen = generate_tokens(self.text)
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
125 for toktype, ttext, (slineno, _), (elineno, _), ltext in tokgen:
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
126 if self.show_tokens: # pragma: debugging
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
127 print("%10s %5s %-20r %r" % (
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
128 tokenize.tok_name.get(toktype, toktype),
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
129 nice_pair((slineno, elineno)), ttext, ltext
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
130 ))
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
131 if toktype == token.INDENT:
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
132 indent += 1
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
133 elif toktype == token.DEDENT:
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
134 indent -= 1
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
135 elif toktype == token.NAME:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
136 if ttext == 'class':
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
137 # Class definitions look like branches in the bytecode, so
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
138 # we need to exclude them. The simplest way is to note the
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
139 # lines with the 'class' keyword.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
140 self.raw_classdefs.add(slineno)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
141 elif toktype == token.OP:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
142 if ttext == ':':
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
143 should_exclude = (elineno in self.raw_excluded) or excluding_decorators
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
144 if not excluding and should_exclude:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
145 # Start excluding a suite. We trigger off of the colon
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
146 # token so that the #pragma comment will be recognized on
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
147 # the same line as the colon.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
148 self.raw_excluded.add(elineno)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
149 exclude_indent = indent
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
150 excluding = True
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
151 excluding_decorators = False
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
152 elif ttext == '@' and first_on_line:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
153 # A decorator.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
154 if elineno in self.raw_excluded:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
155 excluding_decorators = True
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
156 if excluding_decorators:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
157 self.raw_excluded.add(elineno)
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
158 elif toktype == token.STRING and prev_toktype == token.INDENT:
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
159 # Strings that are first on an indented line are docstrings.
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
160 # (a trick from trace.py in the stdlib.) This works for
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
161 # 99.9999% of cases. For the rest (!) see:
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
162 # http://stackoverflow.com/questions/1769332/x/1769794#1769794
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
163 self.raw_docstrings.update(range(slineno, elineno+1))
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
164 elif toktype == token.NEWLINE:
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
165 if first_line is not None and elineno != first_line:
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
166 # We're at the end of a line, and we've ended on a
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
167 # different line than the first line of the statement,
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
168 # so record a multi-line range.
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
169 for l in range(first_line, elineno+1):
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
170 self._multiline[l] = first_line
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
171 first_line = None
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
172 first_on_line = True
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
173
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
174 if ttext.strip() and toktype != tokenize.COMMENT:
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
175 # A non-whitespace token.
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
176 empty = False
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
177 if first_line is None:
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
178 # The token is not whitespace, and is the first in a
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
179 # statement.
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
180 first_line = slineno
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
181 # Check whether to end an excluded suite.
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
182 if excluding and indent <= exclude_indent:
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
183 excluding = False
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
184 if excluding:
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
185 self.raw_excluded.add(elineno)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
186 first_on_line = False
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
187
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
188 prev_toktype = toktype
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
189
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
190 # Find the starts of the executable statements.
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
191 if not empty:
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
192 byte_parser = ByteParser(self.text, filename=self.filename)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
193 self.raw_statements.update(byte_parser._find_statements())
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
194
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
195 # The first line of modules can lie and say 1 always, even if the first
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
196 # line of code is later. If so, map 1 to the actual first line of the
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
197 # module.
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
198 if env.PYBEHAVIOR.module_firstline_1 and self._multiline:
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
199 self._multiline[1] = min(self.raw_statements)
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
200
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
201 def first_line(self, line):
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
202 """Return the first line number of the statement including `line`."""
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6942
diff changeset
203 if line < 0:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6942
diff changeset
204 line = -self._multiline.get(-line, -line)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6942
diff changeset
205 else:
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6942
diff changeset
206 line = self._multiline.get(line, line)
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6942
diff changeset
207 return line
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
208
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
209 def first_lines(self, lines):
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
210 """Map the line numbers in `lines` to the correct first line of the
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
211 statement.
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
212
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
213 Returns a set of the first lines.
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
214
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
215 """
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
216 return {self.first_line(l) for l in lines}
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
217
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
218 def translate_lines(self, lines):
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
219 """Implement `FileReporter.translate_lines`."""
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
220 return self.first_lines(lines)
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
221
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
222 def translate_arcs(self, arcs):
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
223 """Implement `FileReporter.translate_arcs`."""
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
224 return [(self.first_line(a), self.first_line(b)) for (a, b) in arcs]
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
225
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
226 def parse_source(self):
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
227 """Parse source text to find executable lines, excluded lines, etc.
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
228
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
229 Sets the .excluded and .statements attributes, normalized to the first
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
230 line of multi-line statements.
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
231
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
232 """
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
233 try:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
234 self._raw_parse()
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
235 except (tokenize.TokenError, IndentationError) as err:
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
236 if hasattr(err, "lineno"):
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
237 lineno = err.lineno # IndentationError
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
238 else:
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
239 lineno = err.args[1][0] # TokenError
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
240 raise NotPython(
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
241 f"Couldn't parse '{self.filename}' as Python source: " +
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
242 f"{err.args[0]!r} at line {lineno}"
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
243 ) from err
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
244
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
245 self.excluded = self.first_lines(self.raw_excluded)
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
246
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
247 ignore = self.excluded | self.raw_docstrings
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
248 starts = self.raw_statements - ignore
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
249 self.statements = self.first_lines(starts) - ignore
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
250
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
251 def arcs(self):
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
252 """Get information about the arcs available in the code.
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
253
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
254 Returns a set of line number pairs. Line numbers have been normalized
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
255 to the first line of multi-line statements.
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
256
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
257 """
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
258 if self._all_arcs is None:
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
259 self._analyze_ast()
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
260 return self._all_arcs
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
261
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
262 def _analyze_ast(self):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
263 """Run the AstArcAnalyzer and save its results.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
264
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
265 `_all_arcs` is the set of arcs in the code.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
266
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
267 """
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
268 aaa = AstArcAnalyzer(self.text, self.raw_statements, self._multiline)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
269 aaa.analyze()
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
270
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
271 self._all_arcs = set()
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
272 for l1, l2 in aaa.arcs:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
273 fl1 = self.first_line(l1)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
274 fl2 = self.first_line(l2)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
275 if fl1 != fl2:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
276 self._all_arcs.add((fl1, fl2))
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
277
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
278 self._missing_arc_fragments = aaa.missing_arc_fragments
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
279
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
280 def exit_counts(self):
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
281 """Get a count of exits from that each line.
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
282
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
283 Excluded lines are excluded.
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
284
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
285 """
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
286 exit_counts = collections.defaultdict(int)
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
287 for l1, l2 in self.arcs():
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
288 if l1 < 0:
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
289 # Don't ever report -1 as a line number
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
290 continue
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
291 if l1 in self.excluded:
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
292 # Don't report excluded lines as line numbers.
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
293 continue
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
294 if l2 in self.excluded:
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
295 # Arcs to excluded lines shouldn't count.
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
296 continue
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
297 exit_counts[l1] += 1
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
298
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
299 # Class definitions have one extra exit, so remove one for each:
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
300 for l in self.raw_classdefs:
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
301 # Ensure key is there: class definitions can include excluded lines.
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
302 if l in exit_counts:
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
303 exit_counts[l] -= 1
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
304
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
305 return exit_counts
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
306
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
307 def missing_arc_description(self, start, end, executed_arcs=None):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
308 """Provide an English sentence describing a missing arc."""
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
309 if self._missing_arc_fragments is None:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
310 self._analyze_ast()
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
311
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
312 actual_start = start
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
313
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
314 if (
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
315 executed_arcs and
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
316 end < 0 and end == -start and
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
317 (end, start) not in executed_arcs and
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
318 (end, start) in self._missing_arc_fragments
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
319 ):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
320 # It's a one-line callable, and we never even started it,
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
321 # and we have a message about not starting it.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
322 start, end = end, start
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
323
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
324 fragment_pairs = self._missing_arc_fragments.get((start, end), [(None, None)])
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
325
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
326 msgs = []
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
327 for smsg, emsg in fragment_pairs:
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
328 if emsg is None:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
329 if end < 0:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
330 # Hmm, maybe we have a one-line callable, let's check.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
331 if (-end, end) in self._missing_arc_fragments:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
332 return self.missing_arc_description(-end, end)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
333 emsg = "didn't jump to the function exit"
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
334 else:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
335 emsg = "didn't jump to line {lineno}"
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
336 emsg = emsg.format(lineno=end)
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
337
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
338 msg = f"line {actual_start} {emsg}"
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
339 if smsg is not None:
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
340 msg += f", because {smsg.format(lineno=actual_start)}"
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
341
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
342 msgs.append(msg)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
343
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
344 return " or ".join(msgs)
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
345
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
346
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
347 class ByteParser:
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
348 """Parse bytecode to understand the structure of code."""
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
349
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
350 @contract(text='unicode')
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
351 def __init__(self, text, code=None, filename=None):
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
352 self.text = text
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
353 if code:
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
354 self.code = code
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
355 else:
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
356 try:
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
357 self.code = compile_unicode(text, filename, "exec")
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
358 except SyntaxError as synerr:
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
359 raise NotPython(
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
360 "Couldn't parse '%s' as Python source: '%s' at line %d" % (
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
361 filename, synerr.msg, synerr.lineno
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
362 )
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
363 ) from synerr
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
364
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
365 # Alternative Python implementations don't always provide all the
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
366 # attributes on code objects that we need to do the analysis.
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
367 for attr in ['co_lnotab', 'co_firstlineno']:
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
368 if not hasattr(self.code, attr):
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
369 raise StopEverything( # pragma: only jython
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
370 "This implementation of Python doesn't support code analysis.\n" +
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
371 "Run coverage.py under another Python for this command."
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
372 )
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
373
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
374 def child_parsers(self):
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
375 """Iterate over all the code objects nested within this one.
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
376
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
377 The iteration includes `self` as its first value.
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
378
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
379 """
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6942
diff changeset
380 return (ByteParser(self.text, code=c) for c in code_objects(self.code))
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
381
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
382 def _line_numbers(self):
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
383 """Yield the line numbers possible in this code object.
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
384
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
385 Uses co_lnotab described in Python/compile.c to find the
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
386 line numbers. Produces a sequence: l0, l1, ...
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
387 """
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
388 if hasattr(self.code, "co_lines"):
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
389 for _, _, line in self.code.co_lines():
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
390 if line is not None:
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
391 yield line
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
392 else:
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
393 # Adapted from dis.py in the standard library.
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
394 byte_increments = self.code.co_lnotab[0::2]
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
395 line_increments = self.code.co_lnotab[1::2]
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
396
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
397 last_line_num = None
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
398 line_num = self.code.co_firstlineno
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
399 byte_num = 0
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
400 for byte_incr, line_incr in zip(byte_increments, line_increments):
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
401 if byte_incr:
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
402 if line_num != last_line_num:
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
403 yield line_num
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
404 last_line_num = line_num
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
405 byte_num += byte_incr
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
406 if env.PYBEHAVIOR.negative_lnotab and line_incr >= 0x80:
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
407 line_incr -= 0x100
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
408 line_num += line_incr
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
409 if line_num != last_line_num:
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
410 yield line_num
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
411
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
412 def _find_statements(self):
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
413 """Find the statements in `self.code`.
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
414
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
415 Produce a sequence of line numbers that start statements. Recurses
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
416 into all code objects reachable from `self.code`.
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
417
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
418 """
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
419 for bp in self.child_parsers():
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
420 # Get all of the lineno information from this code.
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
421 yield from bp._line_numbers()
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
422
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
423
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
424 #
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
425 # AST analysis
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
426 #
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
427
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
428 class BlockBase:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
429 """
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
430 Blocks need to handle various exiting statements in their own ways.
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
431
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
432 All of these methods take a list of exits, and a callable `add_arc`
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
433 function that they can use to add arcs if needed. They return True if the
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
434 exits are handled, or False if the search should continue up the block
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
435 stack.
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
436 """
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
437 # pylint: disable=unused-argument
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
438 def process_break_exits(self, exits, add_arc):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
439 """Process break exits."""
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
440 # Because break can only appear in loops, and most subclasses
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
441 # implement process_break_exits, this function is never reached.
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
442 raise AssertionError
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
443
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
444 def process_continue_exits(self, exits, add_arc):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
445 """Process continue exits."""
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
446 # Because continue can only appear in loops, and most subclasses
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
447 # implement process_continue_exits, this function is never reached.
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
448 raise AssertionError
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
449
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
450 def process_raise_exits(self, exits, add_arc):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
451 """Process raise exits."""
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
452 return False
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
453
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
454 def process_return_exits(self, exits, add_arc):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
455 """Process return exits."""
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
456 return False
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
457
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
458
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
459 class LoopBlock(BlockBase):
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
460 """A block on the block stack representing a `for` or `while` loop."""
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
461 @contract(start=int)
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
462 def __init__(self, start):
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
463 # The line number where the loop starts.
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
464 self.start = start
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
465 # A set of ArcStarts, the arcs from break statements exiting this loop.
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
466 self.break_exits = set()
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
467
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
468 def process_break_exits(self, exits, add_arc):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
469 self.break_exits.update(exits)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
470 return True
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
471
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
472 def process_continue_exits(self, exits, add_arc):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
473 for xit in exits:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
474 add_arc(xit.lineno, self.start, xit.cause)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
475 return True
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
476
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
477
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
478 class FunctionBlock(BlockBase):
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
479 """A block on the block stack representing a function definition."""
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
480 @contract(start=int, name=str)
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
481 def __init__(self, start, name):
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
482 # The line number where the function starts.
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
483 self.start = start
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
484 # The name of the function.
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
485 self.name = name
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
486
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
487 def process_raise_exits(self, exits, add_arc):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
488 for xit in exits:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
489 add_arc(
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
490 xit.lineno, -self.start, xit.cause,
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
491 f"didn't except from function {self.name!r}",
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
492 )
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
493 return True
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
494
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
495 def process_return_exits(self, exits, add_arc):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
496 for xit in exits:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
497 add_arc(
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
498 xit.lineno, -self.start, xit.cause,
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
499 f"didn't return from function {self.name!r}",
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
500 )
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
501 return True
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
502
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
503
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
504 class TryBlock(BlockBase):
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
505 """A block on the block stack representing a `try` block."""
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
506 @contract(handler_start='int|None', final_start='int|None')
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
507 def __init__(self, handler_start, final_start):
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
508 # The line number of the first "except" handler, if any.
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
509 self.handler_start = handler_start
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
510 # The line number of the "finally:" clause, if any.
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
511 self.final_start = final_start
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
512
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
513 # The ArcStarts for breaks/continues/returns/raises inside the "try:"
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
514 # that need to route through the "finally:" clause.
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
515 self.break_from = set()
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
516 self.continue_from = set()
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
517 self.raise_from = set()
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
518 self.return_from = set()
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
519
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
520 def process_break_exits(self, exits, add_arc):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
521 if self.final_start is not None:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
522 self.break_from.update(exits)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
523 return True
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
524 return False
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
525
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
526 def process_continue_exits(self, exits, add_arc):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
527 if self.final_start is not None:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
528 self.continue_from.update(exits)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
529 return True
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
530 return False
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
531
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
532 def process_raise_exits(self, exits, add_arc):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
533 if self.handler_start is not None:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
534 for xit in exits:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
535 add_arc(xit.lineno, self.handler_start, xit.cause)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
536 else:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
537 assert self.final_start is not None
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
538 self.raise_from.update(exits)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
539 return True
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
540
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
541 def process_return_exits(self, exits, add_arc):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
542 if self.final_start is not None:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
543 self.return_from.update(exits)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
544 return True
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
545 return False
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
546
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
547
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
548 class WithBlock(BlockBase):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
549 """A block on the block stack representing a `with` block."""
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
550 @contract(start=int)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
551 def __init__(self, start):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
552 # We only ever use this block if it is needed, so that we don't have to
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
553 # check this setting in all the methods.
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
554 assert env.PYBEHAVIOR.exit_through_with
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
555
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
556 # The line number of the with statement.
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
557 self.start = start
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
558
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
559 # The ArcStarts for breaks/continues/returns/raises inside the "with:"
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
560 # that need to go through the with-statement while exiting.
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
561 self.break_from = set()
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
562 self.continue_from = set()
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
563 self.return_from = set()
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
564
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
565 def _process_exits(self, exits, add_arc, from_set=None):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
566 """Helper to process the four kinds of exits."""
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
567 for xit in exits:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
568 add_arc(xit.lineno, self.start, xit.cause)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
569 if from_set is not None:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
570 from_set.update(exits)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
571 return True
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
572
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
573 def process_break_exits(self, exits, add_arc):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
574 return self._process_exits(exits, add_arc, self.break_from)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
575
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
576 def process_continue_exits(self, exits, add_arc):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
577 return self._process_exits(exits, add_arc, self.continue_from)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
578
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
579 def process_raise_exits(self, exits, add_arc):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
580 return self._process_exits(exits, add_arc)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
581
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
582 def process_return_exits(self, exits, add_arc):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
583 return self._process_exits(exits, add_arc, self.return_from)
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
584
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
585
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
586 class ArcStart(collections.namedtuple("Arc", "lineno, cause")):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
587 """The information needed to start an arc.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
588
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
589 `lineno` is the line number the arc starts from.
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
590
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
591 `cause` is an English text fragment used as the `startmsg` for
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
592 AstArcAnalyzer.missing_arc_fragments. It will be used to describe why an
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
593 arc wasn't executed, so should fit well into a sentence of the form,
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
594 "Line 17 didn't run because {cause}." The fragment can include "{lineno}"
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
595 to have `lineno` interpolated into it.
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
596
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
597 """
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
598 def __new__(cls, lineno, cause=None):
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
599 return super().__new__(cls, lineno, cause)
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
600
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
601
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
602 # Define contract words that PyContract doesn't have.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
603 # ArcStarts is for a list or set of ArcStart's.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
604 new_contract('ArcStarts', lambda seq: all(isinstance(x, ArcStart) for x in seq))
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
605
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
606
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
607 class NodeList:
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
608 """A synthetic fictitious node, containing a sequence of nodes.
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
609
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
610 This is used when collapsing optimized if-statements, to represent the
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
611 unconditional execution of one of the clauses.
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
612
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
613 """
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
614 def __init__(self, body):
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
615 self.body = body
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
616 self.lineno = body[0].lineno
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
617
6649
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
618 # TODO: some add_arcs methods here don't add arcs, they return them. Rename them.
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
619 # TODO: the cause messages have too many commas.
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
620 # TODO: Shouldn't the cause messages join with "and" instead of "or"?
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
621
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
622 def ast_parse(text):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
623 """How we create an AST parse."""
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
624 return ast.parse(neuter_encoding_declaration(text))
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
625
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
626
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
627 class AstArcAnalyzer:
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
628 """Analyze source text with an AST to find executable code paths."""
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
629
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
630 @contract(text='unicode', statements=set)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
631 def __init__(self, text, statements, multiline):
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
632 self.root_node = ast_parse(text)
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
633 # TODO: I think this is happening in too many places.
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
634 self.statements = {multiline.get(l, l) for l in statements}
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
635 self.multiline = multiline
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
636
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
637 # Turn on AST dumps with an environment variable.
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
638 # $set_env.py: COVERAGE_AST_DUMP - Dump the AST nodes when parsing code.
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
639 dump_ast = bool(int(os.environ.get("COVERAGE_AST_DUMP", 0)))
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
640
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
641 if dump_ast: # pragma: debugging
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
642 # Dump the AST so that failing tests have helpful output.
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
643 print(f"Statements: {self.statements}")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
644 print(f"Multiline map: {self.multiline}")
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
645 ast_dump(self.root_node)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
646
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
647 self.arcs = set()
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
648
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
649 # A map from arc pairs to a list of pairs of sentence fragments:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
650 # { (start, end): [(startmsg, endmsg), ...], }
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
651 #
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
652 # For an arc from line 17, they should be usable like:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
653 # "Line 17 {endmsg}, because {startmsg}"
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
654 self.missing_arc_fragments = collections.defaultdict(list)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
655 self.block_stack = []
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
656
7427
362cd1b6f81a coverage: updated coverage.py to 5.0.3.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6942
diff changeset
657 # $set_env.py: COVERAGE_TRACK_ARCS - Trace every arc added while parsing code.
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
658 self.debug = bool(int(os.environ.get("COVERAGE_TRACK_ARCS", 0)))
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
659
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
660 def analyze(self):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
661 """Examine the AST tree from `root_node` to determine possible arcs.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
662
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
663 This sets the `arcs` attribute to be a set of (from, to) line number
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
664 pairs.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
665
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
666 """
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
667 for node in ast.walk(self.root_node):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
668 node_name = node.__class__.__name__
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
669 code_object_handler = getattr(self, "_code_object__" + node_name, None)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
670 if code_object_handler is not None:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
671 code_object_handler(node)
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
672
6649
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
673 @contract(start=int, end=int)
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
674 def add_arc(self, start, end, smsg=None, emsg=None):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
675 """Add an arc, including message fragments to use if it is missing."""
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
676 if self.debug: # pragma: debugging
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
677 print(f"\nAdding arc: ({start}, {end}): {smsg!r}, {emsg!r}")
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
678 print(short_stack(limit=6))
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
679 self.arcs.add((start, end))
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
680
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
681 if smsg is not None or emsg is not None:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
682 self.missing_arc_fragments[(start, end)].append((smsg, emsg))
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
683
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
684 def nearest_blocks(self):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
685 """Yield the blocks in nearest-to-farthest order."""
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
686 return reversed(self.block_stack)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
687
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
688 @contract(returns=int)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
689 def line_for_node(self, node):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
690 """What is the right line number to use for this node?
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
691
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
692 This dispatches to _line__Node functions where needed.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
693
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
694 """
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
695 node_name = node.__class__.__name__
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
696 handler = getattr(self, "_line__" + node_name, None)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
697 if handler is not None:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
698 return handler(node)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
699 else:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
700 return node.lineno
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
701
6649
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
702 def _line_decorated(self, node):
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
703 """Compute first line number for things that can be decorated (classes and functions)."""
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
704 lineno = node.lineno
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
705 if env.PYBEHAVIOR.trace_decorated_def:
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
706 if node.decorator_list:
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
707 lineno = node.decorator_list[0].lineno
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
708 return lineno
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
709
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
710 def _line__Assign(self, node):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
711 return self.line_for_node(node.value)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
712
6649
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
713 _line__ClassDef = _line_decorated
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
714
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
715 def _line__Dict(self, node):
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
716 if node.keys:
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
717 if node.keys[0] is not None:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
718 return node.keys[0].lineno
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
719 else:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
720 # Unpacked dict literals `{**{'a':1}}` have None as the key,
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
721 # use the value in that case.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
722 return node.values[0].lineno
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
723 else:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
724 return node.lineno
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
725
6649
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
726 _line__FunctionDef = _line_decorated
7702
f8b97639deb5 Third Party packages: updated coverage.py to 5.3.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7427
diff changeset
727 _line__AsyncFunctionDef = _line_decorated
6649
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
728
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
729 def _line__List(self, node):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
730 if node.elts:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
731 return self.line_for_node(node.elts[0])
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
732 else:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
733 return node.lineno
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
734
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
735 def _line__Module(self, node):
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
736 if env.PYBEHAVIOR.module_firstline_1:
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
737 return 1
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
738 elif node.body:
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
739 return self.line_for_node(node.body[0])
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
740 else:
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
741 # Empty modules have no line number, they always start at 1.
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
742 return 1
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
743
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
744 # The node types that just flow to the next node with no complications.
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
745 OK_TO_DEFAULT = {
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
746 "AnnAssign", "Assign", "Assert", "AugAssign", "Delete", "Expr", "Global",
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
747 "Import", "ImportFrom", "Nonlocal", "Pass",
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
748 }
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
749
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
750 @contract(returns='ArcStarts')
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
751 def add_arcs(self, node):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
752 """Add the arcs for `node`.
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
753
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
754 Return a set of ArcStarts, exits from this node to the next. Because a
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
755 node represents an entire sub-tree (including its children), the exits
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
756 from a node can be arbitrarily complex::
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
757
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
758 if something(1):
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
759 if other(2):
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
760 doit(3)
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
761 else:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
762 doit(5)
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
763
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
764 There are two exits from line 1: they start at line 3 and line 5.
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
765
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
766 """
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
767 node_name = node.__class__.__name__
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
768 handler = getattr(self, "_handle__" + node_name, None)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
769 if handler is not None:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
770 return handler(node)
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
771 else:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
772 # No handler: either it's something that's ok to default (a simple
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
773 # statement), or it's something we overlooked.
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
774 if env.TESTING:
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
775 if node_name not in self.OK_TO_DEFAULT:
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
776 raise Exception(f"*** Unhandled: {node}") # pragma: only failure
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
777
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
778 # Default for simple statements: one exit from this node.
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
779 return {ArcStart(self.line_for_node(node))}
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
780
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
781 @one_of("from_start, prev_starts")
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
782 @contract(returns='ArcStarts')
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
783 def add_body_arcs(self, body, from_start=None, prev_starts=None):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
784 """Add arcs for the body of a compound statement.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
785
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
786 `body` is the body node. `from_start` is a single `ArcStart` that can
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
787 be the previous line in flow before this body. `prev_starts` is a set
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
788 of ArcStarts that can be the previous line. Only one of them should be
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
789 given.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
790
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
791 Returns a set of ArcStarts, the exits from this body.
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
792
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
793 """
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
794 if prev_starts is None:
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
795 prev_starts = {from_start}
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
796 for body_node in body:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
797 lineno = self.line_for_node(body_node)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
798 first_line = self.multiline.get(lineno, lineno)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
799 if first_line not in self.statements:
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
800 body_node = self.find_non_missing_node(body_node)
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
801 if body_node is None:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
802 continue
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
803 lineno = self.line_for_node(body_node)
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
804 for prev_start in prev_starts:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
805 self.add_arc(prev_start.lineno, lineno, prev_start.cause)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
806 prev_starts = self.add_arcs(body_node)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
807 return prev_starts
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
808
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
809 def find_non_missing_node(self, node):
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
810 """Search `node` looking for a child that has not been optimized away.
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
811
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
812 This might return the node you started with, or it will work recursively
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
813 to find a child node in self.statements.
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
814
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
815 Returns a node, or None if none of the node remains.
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
816
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
817 """
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
818 # This repeats work just done in add_body_arcs, but this duplication
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
819 # means we can avoid a function call in the 99.9999% case of not
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
820 # optimizing away statements.
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
821 lineno = self.line_for_node(node)
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
822 first_line = self.multiline.get(lineno, lineno)
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
823 if first_line in self.statements:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
824 return node
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
825
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
826 missing_fn = getattr(self, "_missing__" + node.__class__.__name__, None)
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
827 if missing_fn:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
828 node = missing_fn(node)
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
829 else:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
830 node = None
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
831 return node
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
832
6649
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
833 # Missing nodes: _missing__*
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
834 #
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
835 # Entire statements can be optimized away by Python. They will appear in
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
836 # the AST, but not the bytecode. These functions are called (by
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
837 # find_non_missing_node) to find a node to use instead of the missing
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
838 # node. They can return None if the node should truly be gone.
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
839
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
840 def _missing__If(self, node):
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
841 # If the if-node is missing, then one of its children might still be
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
842 # here, but not both. So return the first of the two that isn't missing.
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
843 # Use a NodeList to hold the clauses as a single node.
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
844 non_missing = self.find_non_missing_node(NodeList(node.body))
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
845 if non_missing:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
846 return non_missing
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
847 if node.orelse:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
848 return self.find_non_missing_node(NodeList(node.orelse))
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
849 return None
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
850
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
851 def _missing__NodeList(self, node):
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
852 # A NodeList might be a mixture of missing and present nodes. Find the
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
853 # ones that are present.
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
854 non_missing_children = []
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
855 for child in node.body:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
856 child = self.find_non_missing_node(child)
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
857 if child is not None:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
858 non_missing_children.append(child)
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
859
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
860 # Return the simplest representation of the present children.
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
861 if not non_missing_children:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
862 return None
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
863 if len(non_missing_children) == 1:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
864 return non_missing_children[0]
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
865 return NodeList(non_missing_children)
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
866
6649
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
867 def _missing__While(self, node):
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
868 body_nodes = self.find_non_missing_node(NodeList(node.body))
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
869 if not body_nodes:
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
870 return None
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
871 # Make a synthetic While-true node.
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
872 new_while = ast.While()
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
873 new_while.lineno = body_nodes.lineno
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
874 new_while.test = ast.Name()
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
875 new_while.test.lineno = body_nodes.lineno
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
876 new_while.test.id = "True"
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
877 new_while.body = body_nodes.body
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
878 new_while.orelse = None
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
879 return new_while
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
880
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
881 def is_constant_expr(self, node):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
882 """Is this a compile-time constant?"""
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
883 node_name = node.__class__.__name__
6649
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
884 if node_name in ["Constant", "NameConstant", "Num"]:
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
885 return "Num"
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
886 elif node_name == "Name":
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
887 if node.id in ["True", "False", "None", "__debug__"]:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
888 return "Name"
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
889 return None
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
890
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
891 # In the fullness of time, these might be good tests to write:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
892 # while EXPR:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
893 # while False:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
894 # listcomps hidden deep in other expressions
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
895 # listcomps hidden in lists: x = [[i for i in range(10)]]
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
896 # nested function definitions
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
897
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
898
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
899 # Exit processing: process_*_exits
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
900 #
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
901 # These functions process the four kinds of jump exits: break, continue,
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
902 # raise, and return. To figure out where an exit goes, we have to look at
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
903 # the block stack context. For example, a break will jump to the nearest
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
904 # enclosing loop block, or the nearest enclosing finally block, whichever
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
905 # is nearer.
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
906
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
907 @contract(exits='ArcStarts')
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
908 def process_break_exits(self, exits):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
909 """Add arcs due to jumps from `exits` being breaks."""
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
910 for block in self.nearest_blocks(): # pragma: always breaks
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
911 if block.process_break_exits(exits, self.add_arc):
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
912 break
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
913
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
914 @contract(exits='ArcStarts')
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
915 def process_continue_exits(self, exits):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
916 """Add arcs due to jumps from `exits` being continues."""
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
917 for block in self.nearest_blocks(): # pragma: always breaks
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
918 if block.process_continue_exits(exits, self.add_arc):
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
919 break
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
920
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
921 @contract(exits='ArcStarts')
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
922 def process_raise_exits(self, exits):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
923 """Add arcs due to jumps from `exits` being raises."""
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
924 for block in self.nearest_blocks():
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
925 if block.process_raise_exits(exits, self.add_arc):
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
926 break
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
927
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
928 @contract(exits='ArcStarts')
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
929 def process_return_exits(self, exits):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
930 """Add arcs due to jumps from `exits` being returns."""
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
931 for block in self.nearest_blocks(): # pragma: always breaks
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
932 if block.process_return_exits(exits, self.add_arc):
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
933 break
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
934
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
935 # Handlers: _handle__*
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
936 #
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
937 # Each handler deals with a specific AST node type, dispatched from
6649
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
938 # add_arcs. Handlers return the set of exits from that node, and can
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
939 # also call self.add_arc to record arcs they find. These functions mirror
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
940 # the Python semantics of each syntactic construct. See the docstring
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
941 # for add_arcs to understand the concept of exits from a node.
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
942 #
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
943 # Every node type that represents a statement should have a handler, or it
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
944 # should be listed in OK_TO_DEFAULT.
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
945
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
946 @contract(returns='ArcStarts')
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
947 def _handle__Break(self, node):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
948 here = self.line_for_node(node)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
949 break_start = ArcStart(here, cause="the break on line {lineno} wasn't executed")
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
950 self.process_break_exits([break_start])
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
951 return set()
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
952
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
953 @contract(returns='ArcStarts')
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
954 def _handle_decorated(self, node):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
955 """Add arcs for things that can be decorated (classes and functions)."""
6649
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
956 main_line = last = node.lineno
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
957 if node.decorator_list:
6649
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
958 if env.PYBEHAVIOR.trace_decorated_def:
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
959 last = None
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
960 for dec_node in node.decorator_list:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
961 dec_start = self.line_for_node(dec_node)
6649
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
962 if last is not None and dec_start != last:
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
963 self.add_arc(last, dec_start)
6649
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
964 last = dec_start
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
965 if env.PYBEHAVIOR.trace_decorated_def:
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
966 self.add_arc(last, main_line)
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
967 last = main_line
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
968 # The definition line may have been missed, but we should have it
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
969 # in `self.statements`. For some constructs, `line_for_node` is
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
970 # not what we'd think of as the first line in the statement, so map
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
971 # it to the first one.
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
972 if node.body:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
973 body_start = self.line_for_node(node.body[0])
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
974 body_start = self.multiline.get(body_start, body_start)
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
975 for lineno in range(last+1, body_start):
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
976 if lineno in self.statements:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
977 self.add_arc(last, lineno)
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
978 last = lineno
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
979 # The body is handled in collect_arcs.
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
980 return {ArcStart(last)}
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
981
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
982 _handle__ClassDef = _handle_decorated
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
983
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
984 @contract(returns='ArcStarts')
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
985 def _handle__Continue(self, node):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
986 here = self.line_for_node(node)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
987 continue_start = ArcStart(here, cause="the continue on line {lineno} wasn't executed")
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
988 self.process_continue_exits([continue_start])
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
989 return set()
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
990
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
991 @contract(returns='ArcStarts')
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
992 def _handle__For(self, node):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
993 start = self.line_for_node(node.iter)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
994 self.block_stack.append(LoopBlock(start=start))
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
995 from_start = ArcStart(start, cause="the loop on line {lineno} never started")
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
996 exits = self.add_body_arcs(node.body, from_start=from_start)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
997 # Any exit from the body will go back to the top of the loop.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
998 for xit in exits:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
999 self.add_arc(xit.lineno, start, xit.cause)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1000 my_block = self.block_stack.pop()
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1001 exits = my_block.break_exits
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1002 from_start = ArcStart(start, cause="the loop on line {lineno} didn't complete")
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1003 if node.orelse:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1004 else_exits = self.add_body_arcs(node.orelse, from_start=from_start)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1005 exits |= else_exits
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1006 else:
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1007 # No else clause: exit from the for line.
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1008 exits.add(from_start)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1009 return exits
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1010
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1011 _handle__AsyncFor = _handle__For
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1012
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1013 _handle__FunctionDef = _handle_decorated
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1014 _handle__AsyncFunctionDef = _handle_decorated
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
1015
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1016 @contract(returns='ArcStarts')
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1017 def _handle__If(self, node):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1018 start = self.line_for_node(node.test)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1019 from_start = ArcStart(start, cause="the condition on line {lineno} was never true")
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1020 exits = self.add_body_arcs(node.body, from_start=from_start)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1021 from_start = ArcStart(start, cause="the condition on line {lineno} was never false")
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1022 exits |= self.add_body_arcs(node.orelse, from_start=from_start)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1023 return exits
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1024
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1025 @contract(returns='ArcStarts')
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1026 def _handle__Match(self, node):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1027 start = self.line_for_node(node)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1028 last_start = start
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1029 exits = set()
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1030 had_wildcard = False
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1031 for case in node.cases:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1032 case_start = self.line_for_node(case.pattern)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1033 if isinstance(case.pattern, ast.MatchAs):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1034 had_wildcard = True
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1035 self.add_arc(last_start, case_start, "the pattern on line {lineno} always matched")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1036 from_start = ArcStart(case_start, cause="the pattern on line {lineno} never matched")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1037 exits |= self.add_body_arcs(case.body, from_start=from_start)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1038 last_start = case_start
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1039 if not had_wildcard:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1040 exits.add(from_start)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1041 return exits
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1042
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1043 @contract(returns='ArcStarts')
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1044 def _handle__NodeList(self, node):
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1045 start = self.line_for_node(node)
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1046 exits = self.add_body_arcs(node.body, from_start=ArcStart(start))
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1047 return exits
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1048
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1049 @contract(returns='ArcStarts')
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1050 def _handle__Raise(self, node):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1051 here = self.line_for_node(node)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1052 raise_start = ArcStart(here, cause="the raise on line {lineno} wasn't executed")
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1053 self.process_raise_exits([raise_start])
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1054 # `raise` statement jumps away, no exits from here.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1055 return set()
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1056
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1057 @contract(returns='ArcStarts')
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1058 def _handle__Return(self, node):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1059 here = self.line_for_node(node)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1060 return_start = ArcStart(here, cause="the return on line {lineno} wasn't executed")
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1061 self.process_return_exits([return_start])
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1062 # `return` statement jumps away, no exits from here.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1063 return set()
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1064
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1065 @contract(returns='ArcStarts')
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1066 def _handle__Try(self, node):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1067 if node.handlers:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1068 handler_start = self.line_for_node(node.handlers[0])
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1069 else:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1070 handler_start = None
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1071
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1072 if node.finalbody:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1073 final_start = self.line_for_node(node.finalbody[0])
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1074 else:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1075 final_start = None
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1076
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1077 # This is true by virtue of Python syntax: have to have either except
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1078 # or finally, or both.
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1079 assert handler_start is not None or final_start is not None
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1080 try_block = TryBlock(handler_start, final_start)
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1081 self.block_stack.append(try_block)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1082
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1083 start = self.line_for_node(node)
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1084 exits = self.add_body_arcs(node.body, from_start=ArcStart(start))
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
1085
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1086 # We're done with the `try` body, so this block no longer handles
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1087 # exceptions. We keep the block so the `finally` clause can pick up
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1088 # flows from the handlers and `else` clause.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1089 if node.finalbody:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1090 try_block.handler_start = None
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1091 if node.handlers:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1092 # If there are `except` clauses, then raises in the try body
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1093 # will already jump to them. Start this set over for raises in
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1094 # `except` and `else`.
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
1095 try_block.raise_from = set()
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1096 else:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1097 self.block_stack.pop()
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1098
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1099 handler_exits = set()
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1100
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1101 if node.handlers:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1102 last_handler_start = None
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1103 for handler_node in node.handlers:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1104 handler_start = self.line_for_node(handler_node)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1105 if last_handler_start is not None:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1106 self.add_arc(last_handler_start, handler_start)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1107 last_handler_start = handler_start
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1108 from_cause = "the exception caught by line {lineno} didn't happen"
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1109 from_start = ArcStart(handler_start, cause=from_cause)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1110 handler_exits |= self.add_body_arcs(handler_node.body, from_start=from_start)
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
1111
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1112 if node.orelse:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1113 exits = self.add_body_arcs(node.orelse, prev_starts=exits)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1114
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1115 exits |= handler_exits
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
1116
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1117 if node.finalbody:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1118 self.block_stack.pop()
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1119 final_from = ( # You can get to the `finally` clause from:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1120 exits | # the exits of the body or `else` clause,
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1121 try_block.break_from | # or a `break`,
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1122 try_block.continue_from | # or a `continue`,
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1123 try_block.raise_from | # or a `raise`,
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1124 try_block.return_from # or a `return`.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1125 )
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
1126
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1127 final_exits = self.add_body_arcs(node.finalbody, prev_starts=final_from)
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1128
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1129 if try_block.break_from:
6649
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1130 if env.PYBEHAVIOR.finally_jumps_back:
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1131 for break_line in try_block.break_from:
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1132 lineno = break_line.lineno
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1133 cause = break_line.cause.format(lineno=lineno)
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1134 for final_exit in final_exits:
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1135 self.add_arc(final_exit.lineno, lineno, cause)
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1136 breaks = try_block.break_from
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1137 else:
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1138 breaks = self._combine_finally_starts(try_block.break_from, final_exits)
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1139 self.process_break_exits(breaks)
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1140
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1141 if try_block.continue_from:
6649
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1142 if env.PYBEHAVIOR.finally_jumps_back:
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1143 for continue_line in try_block.continue_from:
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1144 lineno = continue_line.lineno
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1145 cause = continue_line.cause.format(lineno=lineno)
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1146 for final_exit in final_exits:
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1147 self.add_arc(final_exit.lineno, lineno, cause)
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1148 continues = try_block.continue_from
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1149 else:
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1150 continues = self._combine_finally_starts(try_block.continue_from, final_exits)
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1151 self.process_continue_exits(continues)
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1152
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1153 if try_block.raise_from:
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1154 self.process_raise_exits(
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1155 self._combine_finally_starts(try_block.raise_from, final_exits)
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1156 )
6649
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1157
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1158 if try_block.return_from:
6649
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1159 if env.PYBEHAVIOR.finally_jumps_back:
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1160 for return_line in try_block.return_from:
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1161 lineno = return_line.lineno
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1162 cause = return_line.cause.format(lineno=lineno)
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1163 for final_exit in final_exits:
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1164 self.add_arc(final_exit.lineno, lineno, cause)
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1165 returns = try_block.return_from
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1166 else:
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1167 returns = self._combine_finally_starts(try_block.return_from, final_exits)
f1b3a73831c9 coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 6219
diff changeset
1168 self.process_return_exits(returns)
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1169
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1170 if exits:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1171 # The finally clause's exits are only exits for the try block
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1172 # as a whole if the try block had some exits to begin with.
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1173 exits = final_exits
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
1174
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1175 return exits
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
1176
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1177 @contract(starts='ArcStarts', exits='ArcStarts', returns='ArcStarts')
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1178 def _combine_finally_starts(self, starts, exits):
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1179 """Helper for building the cause of `finally` branches.
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1180
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1181 "finally" clauses might not execute their exits, and the causes could
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1182 be due to a failure to execute any of the exits in the try block. So
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1183 we use the causes from `starts` as the causes for `exits`.
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1184 """
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1185 causes = []
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1186 for start in sorted(starts):
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1187 if start.cause is not None:
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1188 causes.append(start.cause.format(lineno=start.lineno))
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1189 cause = " or ".join(causes)
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
1190 exits = {ArcStart(xit.lineno, cause) for xit in exits}
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1191 return exits
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
1192
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1193 @contract(returns='ArcStarts')
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1194 def _handle__While(self, node):
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
1195 start = to_top = self.line_for_node(node.test)
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1196 constant_test = self.is_constant_expr(node.test)
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
1197 top_is_body0 = False
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1198 if constant_test:
8527
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
1199 top_is_body0 = True
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
1200 if env.PYBEHAVIOR.keep_constant_test:
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
1201 top_is_body0 = False
2bd1325d727e Upgraded the included code coverage library to v5.5.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8312
diff changeset
1202 if top_is_body0:
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1203 to_top = self.line_for_node(node.body[0])
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1204 self.block_stack.append(LoopBlock(start=to_top))
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1205 from_start = ArcStart(start, cause="the condition on line {lineno} was never true")
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1206 exits = self.add_body_arcs(node.body, from_start=from_start)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1207 for xit in exits:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1208 self.add_arc(xit.lineno, to_top, xit.cause)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1209 exits = set()
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1210 my_block = self.block_stack.pop()
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1211 exits.update(my_block.break_exits)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1212 from_start = ArcStart(start, cause="the condition on line {lineno} was never false")
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1213 if node.orelse:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1214 else_exits = self.add_body_arcs(node.orelse, from_start=from_start)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1215 exits |= else_exits
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1216 else:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1217 # No `else` clause: you can exit from the start.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1218 if not constant_test:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1219 exits.add(from_start)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1220 return exits
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1221
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1222 @contract(returns='ArcStarts')
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1223 def _handle__With(self, node):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1224 start = self.line_for_node(node)
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1225 if env.PYBEHAVIOR.exit_through_with:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1226 self.block_stack.append(WithBlock(start=start))
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1227 exits = self.add_body_arcs(node.body, from_start=ArcStart(start))
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1228 if env.PYBEHAVIOR.exit_through_with:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1229 with_block = self.block_stack.pop()
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1230 with_exit = {ArcStart(start)}
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1231 if exits:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1232 for xit in exits:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1233 self.add_arc(xit.lineno, start)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1234 exits = with_exit
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1235 if with_block.break_from:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1236 self.process_break_exits(
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1237 self._combine_finally_starts(with_block.break_from, with_exit)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1238 )
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1239 if with_block.continue_from:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1240 self.process_continue_exits(
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1241 self._combine_finally_starts(with_block.continue_from, with_exit)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1242 )
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1243 if with_block.return_from:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1244 self.process_return_exits(
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1245 self._combine_finally_starts(with_block.return_from, with_exit)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1246 )
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1247 return exits
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
1248
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1249 _handle__AsyncWith = _handle__With
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
1250
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1251 # Code object dispatchers: _code_object__*
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1252 #
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1253 # These methods are used by analyze() as the start of the analysis.
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1254 # There is one for each construct with a code object.
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1255
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1256 def _code_object__Module(self, node):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1257 start = self.line_for_node(node)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1258 if node.body:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1259 exits = self.add_body_arcs(node.body, from_start=ArcStart(-start))
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1260 for xit in exits:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1261 self.add_arc(xit.lineno, -start, xit.cause, "didn't exit the module")
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1262 else:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1263 # Empty module.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1264 self.add_arc(-start, start)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1265 self.add_arc(start, -start)
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
1266
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1267 def _code_object__FunctionDef(self, node):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1268 start = self.line_for_node(node)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1269 self.block_stack.append(FunctionBlock(start=start, name=node.name))
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1270 exits = self.add_body_arcs(node.body, from_start=ArcStart(-start))
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1271 self.process_return_exits(exits)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1272 self.block_stack.pop()
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1273
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1274 _code_object__AsyncFunctionDef = _code_object__FunctionDef
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
1275
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1276 def _code_object__ClassDef(self, node):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1277 start = self.line_for_node(node)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1278 self.add_arc(-start, start)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1279 exits = self.add_body_arcs(node.body, from_start=ArcStart(start))
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1280 for xit in exits:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1281 self.add_arc(
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1282 xit.lineno, -start, xit.cause,
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1283 f"didn't exit the body of class {node.name!r}",
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1284 )
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
1285
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1286 def _make_expression_code_method(noun): # pylint: disable=no-self-argument
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1287 """A function to make methods for expression-based callable _code_object__ methods."""
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1288 def _code_object__expression_callable(self, node):
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1289 start = self.line_for_node(node)
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1290 self.add_arc(-start, start, None, f"didn't run the {noun} on line {start}")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1291 self.add_arc(start, -start, None, f"didn't finish the {noun} on line {start}")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1292 return _code_object__expression_callable
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
1293
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1294 _code_object__Lambda = _make_expression_code_method("lambda")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1295 _code_object__GeneratorExp = _make_expression_code_method("generator expression")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1296 _code_object__DictComp = _make_expression_code_method("dictionary comprehension")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1297 _code_object__SetComp = _make_expression_code_method("set comprehension")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1298 _code_object__ListComp = _make_expression_code_method("list comprehension")
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
1299
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
1300
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1301 # Code only used when dumping the AST for debugging.
6219
d6c795b5ce33 Third Party, coverage: updated coverage.py to 4.5.1.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 5178
diff changeset
1302
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1303 SKIP_DUMP_FIELDS = ["ctx"]
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
1304
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1305 def _is_simple_value(value):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1306 """Is `value` simple enough to be displayed on a single line?"""
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1307 return (
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1308 value in [None, [], (), {}, set()] or
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1309 isinstance(value, (bytes, int, float, str))
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1310 )
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
1311
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1312 def ast_dump(node, depth=0, print=print): # pylint: disable=redefined-builtin
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1313 """Dump the AST for `node`.
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
1314
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1315 This recursively walks the AST, printing a readable version.
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
1316
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1317 """
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1318 indent = " " * depth
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1319 lineno = getattr(node, "lineno", None)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1320 if lineno is not None:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1321 linemark = f" @ {node.lineno},{node.col_offset}"
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1322 if hasattr(node, "end_lineno"):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1323 linemark += ":"
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1324 if node.end_lineno != node.lineno:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1325 linemark += f"{node.end_lineno},"
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1326 linemark += f"{node.end_col_offset}"
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1327 else:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1328 linemark = ""
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1329 head = f"{indent}<{node.__class__.__name__}{linemark}"
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
1330
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1331 named_fields = [
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1332 (name, value)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1333 for name, value in ast.iter_fields(node)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1334 if name not in SKIP_DUMP_FIELDS
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1335 ]
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1336 if not named_fields:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1337 print(f"{head}>")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1338 elif len(named_fields) == 1 and _is_simple_value(named_fields[0][1]):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1339 field_name, value = named_fields[0]
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1340 print(f"{head} {field_name}: {value!r}>")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1341 else:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1342 print(head)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1343 if 0:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1344 print("{}# mro: {}".format(
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1345 indent, ", ".join(c.__name__ for c in node.__class__.__mro__[1:]),
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1346 ))
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1347 next_indent = indent + " "
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1348 for field_name, value in named_fields:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1349 prefix = f"{next_indent}{field_name}:"
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1350 if _is_simple_value(value):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1351 print(f"{prefix} {value!r}")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1352 elif isinstance(value, list):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1353 print(f"{prefix} [")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1354 for n in value:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1355 if _is_simple_value(n):
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1356 print(f"{next_indent} {n!r}")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1357 else:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1358 ast_dump(n, depth + 8, print=print)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1359 print(f"{next_indent}]")
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1360 else:
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1361 print(prefix)
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1362 ast_dump(value, depth + 8, print=print)
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
1363
8775
0802ae193343 Upgraded coverage to 6.1.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 8527
diff changeset
1364 print(f"{indent}>")

eric ide

mercurial