eric6/DebugClients/Python/coverage/parser.py

changeset 7427
362cd1b6f81a
parent 6942
2602857055c5
child 7702
f8b97639deb5
diff -r dc171b1d8261 -r 362cd1b6f81a eric6/DebugClients/Python/coverage/parser.py
--- a/eric6/DebugClients/Python/coverage/parser.py	Wed Feb 19 19:38:36 2020 +0100
+++ b/eric6/DebugClients/Python/coverage/parser.py	Sat Feb 22 14:27:42 2020 +0100
@@ -1,5 +1,5 @@
 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
-# For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
+# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
 
 """Code parsing for coverage.py."""
 
@@ -13,7 +13,7 @@
 from coverage import env
 from coverage.backward import range    # pylint: disable=redefined-builtin
 from coverage.backward import bytes_to_ints, string_class
-from coverage.bytecode import CodeObjects
+from coverage.bytecode import code_objects
 from coverage.debug import short_stack
 from coverage.misc import contract, join_regex, new_contract, nice_pair, one_of
 from coverage.misc import NoSource, NotPython, StopEverything
@@ -207,7 +207,11 @@
 
     def first_line(self, line):
         """Return the first line number of the statement including `line`."""
-        return self._multiline.get(line, line)
+        if line < 0:
+            line = -self._multiline.get(-line, -line)
+        else:
+            line = self._multiline.get(line, line)
+        return line
 
     def first_lines(self, lines):
         """Map the line numbers in `lines` to the correct first line of the
@@ -383,8 +387,7 @@
         The iteration includes `self` as its first value.
 
         """
-        children = CodeObjects(self.code)
-        return (ByteParser(self.text, code=c) for c in children)
+        return (ByteParser(self.text, code=c) for c in code_objects(self.code))
 
     def _bytes_lines(self):
         """Map byte offsets to line numbers in `code`.
@@ -409,7 +412,7 @@
                     yield (byte_num, line_num)
                     last_line_num = line_num
                 byte_num += byte_incr
-            if env.PYVERSION >= (3, 6) and line_incr >= 0x80:
+            if env.PYBEHAVIOR.negative_lnotab and line_incr >= 0x80:
                 line_incr -= 0x100
             line_num += line_incr
         if line_num != last_line_num:
@@ -491,6 +494,7 @@
 
 
 # Turn on AST dumps with an environment variable.
+# $set_env.py: COVERAGE_AST_DUMP - Dump the AST nodes when parsing code.
 AST_DUMP = bool(int(os.environ.get("COVERAGE_AST_DUMP", 0)))
 
 class NodeList(object):
@@ -521,8 +525,8 @@
 
         if AST_DUMP:                                # pragma: debugging
             # Dump the AST so that failing tests have helpful output.
-            print("Statements: {0}".format(self.statements))
-            print("Multiline map: {0}".format(self.multiline))
+            print("Statements: {}".format(self.statements))
+            print("Multiline map: {}".format(self.multiline))
             ast_dump(self.root_node)
 
         self.arcs = set()
@@ -535,6 +539,7 @@
         self.missing_arc_fragments = collections.defaultdict(list)
         self.block_stack = []
 
+        # $set_env.py: COVERAGE_TRACK_ARCS - Trace every arc added while parsing code.
         self.debug = bool(int(os.environ.get("COVERAGE_TRACK_ARCS", 0)))
 
     def analyze(self):
@@ -652,7 +657,7 @@
             # to see if it's overlooked.
             if 0:
                 if node_name not in self.OK_TO_DEFAULT:
-                    print("*** Unhandled: {0}".format(node))
+                    print("*** Unhandled: {}".format(node))
 
             # Default for simple statements: one exit from this node.
             return set([ArcStart(self.line_for_node(node))])
@@ -822,7 +827,7 @@
                 for xit in exits:
                     self.add_arc(
                         xit.lineno, -block.start, xit.cause,
-                        "didn't except from function '{0}'".format(block.name),
+                        "didn't except from function {!r}".format(block.name),
                     )
                 break
 
@@ -837,7 +842,7 @@
                 for xit in exits:
                     self.add_arc(
                         xit.lineno, -block.start, xit.cause,
-                        "didn't return from function '{0}'".format(block.name),
+                        "didn't return from function {!r}".format(block.name),
                     )
                 break
 
@@ -1160,17 +1165,17 @@
         for xit in exits:
             self.add_arc(
                 xit.lineno, -start, xit.cause,
-                "didn't exit the body of class '{0}'".format(node.name),
+                "didn't exit the body of class {!r}".format(node.name),
             )
 
     def _make_oneline_code_method(noun):     # pylint: disable=no-self-argument
         """A function to make methods for online callable _code_object__ methods."""
         def _code_object__oneline_callable(self, node):
             start = self.line_for_node(node)
-            self.add_arc(-start, start, None, "didn't run the {0} on line {1}".format(noun, start))
+            self.add_arc(-start, start, None, "didn't run the {} on line {}".format(noun, start))
             self.add_arc(
                 start, -start, None,
-                "didn't finish the {0} on line {1}".format(noun, start),
+                "didn't finish the {} on line {}".format(noun, start),
             )
         return _code_object__oneline_callable
 
@@ -1202,15 +1207,15 @@
         """
         indent = " " * depth
         if not isinstance(node, ast.AST):
-            print("{0}<{1} {2!r}>".format(indent, node.__class__.__name__, node))
+            print("{}<{} {!r}>".format(indent, node.__class__.__name__, node))
             return
 
         lineno = getattr(node, "lineno", None)
         if lineno is not None:
-            linemark = " @ {0}".format(node.lineno)
+            linemark = " @ {}".format(node.lineno)
         else:
             linemark = ""
-        head = "{0}<{1}{2}".format(indent, node.__class__.__name__, linemark)
+        head = "{}<{}{}".format(indent, node.__class__.__name__, linemark)
 
         named_fields = [
             (name, value)
@@ -1218,28 +1223,28 @@
             if name not in SKIP_DUMP_FIELDS
         ]
         if not named_fields:
-            print("{0}>".format(head))
+            print("{}>".format(head))
         elif len(named_fields) == 1 and _is_simple_value(named_fields[0][1]):
             field_name, value = named_fields[0]
-            print("{0} {1}: {2!r}>".format(head, field_name, value))
+            print("{} {}: {!r}>".format(head, field_name, value))
         else:
             print(head)
             if 0:
-                print("{0}# mro: {1}".format(
+                print("{}# mro: {}".format(
                     indent, ", ".join(c.__name__ for c in node.__class__.__mro__[1:]),
                 ))
             next_indent = indent + "    "
             for field_name, value in named_fields:
-                prefix = "{0}{1}:".format(next_indent, field_name)
+                prefix = "{}{}:".format(next_indent, field_name)
                 if _is_simple_value(value):
-                    print("{0} {1!r}".format(prefix, value))
+                    print("{} {!r}".format(prefix, value))
                 elif isinstance(value, list):
-                    print("{0} [".format(prefix))
+                    print("{} [".format(prefix))
                     for n in value:
                         ast_dump(n, depth + 8)
-                    print("{0}]".format(next_indent))
+                    print("{}]".format(next_indent))
                 else:
                     print(prefix)
                     ast_dump(value, depth + 8)
 
-            print("{0}>".format(indent))
+            print("{}>".format(indent))

eric ide

mercurial