Skip to content

Commit 055a9f4

Browse files
committed
fix(debug): ast_dump failed on a few things
1 parent 15aff0a commit 055a9f4

File tree

4 files changed

+42
-18
lines changed

4 files changed

+42
-18
lines changed

coverage/parser.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,7 +1306,7 @@ def _is_simple_value(value):
13061306
"""Is `value` simple enough to be displayed on a single line?"""
13071307
return (
13081308
value in [None, [], (), {}, set()] or
1309-
isinstance(value, (str, int, float))
1309+
isinstance(value, (bytes, int, float, str))
13101310
)
13111311

13121312
def ast_dump(node, depth=0, print=print): # pylint: disable=redefined-builtin
@@ -1352,7 +1352,10 @@ def ast_dump(node, depth=0, print=print): # pylint: disable=redefined-builtin
13521352
elif isinstance(value, list):
13531353
print(f"{prefix} [")
13541354
for n in value:
1355-
ast_dump(n, depth + 8, print=print)
1355+
if _is_simple_value(n):
1356+
print(f"{next_indent} {n!r}")
1357+
else:
1358+
ast_dump(n, depth + 8, print=print)
13561359
print(f"{next_indent}]")
13571360
else:
13581361
print(prefix)

tests/stress_phystoken.tok

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# Here's some random Python so that test_tokenize_myself will have some
55
# stressful stuff to try. This file is .tok instead of .py so pylint won't
66
# complain about it, check_eol won't look at it, etc.
7+
# Some lines are here to reproduce fixed bugs in ast_dump also.
78

89
first_back = """\
910
hey there!
@@ -50,6 +51,15 @@ a_long_string = \
5051
"3 is longer"
5152

5253
def hello():
54+
global x # ast_dump bug
5355
print("Hello world!")
5456

5557
hello()
58+
59+
# ast dump bugs:
60+
weird = {
61+
**d,
62+
**{'c': 7},
63+
'd': 8,
64+
}
65+
self.hash.update(b'.')

tests/test_parser.py

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
"""Tests for coverage.py's code parsing."""
55

66
import os.path
7-
import re
87
import textwrap
98

109
import pytest
@@ -14,7 +13,7 @@
1413
from coverage.parser import ast_dump, ast_parse, PythonParser
1514

1615
from tests.coveragetest import CoverageTest, TESTS_DIR
17-
from tests.helpers import arcz_to_arcs
16+
from tests.helpers import arcz_to_arcs, re_lines
1817

1918

2019
class PythonParserTest(CoverageTest):
@@ -485,17 +484,23 @@ def test_ast_dump():
485484
# Run the AST_DUMP code to make sure it doesn't fail, with some light
486485
# assertions. Use parser.py as the test code since it is the longest file,
487486
# and fitting, since it's the AST_DUMP code.
488-
parser_py = os.path.join(TESTS_DIR, "../coverage/parser.py")
489-
with open(parser_py) as f:
490-
ast_root = ast_parse(f.read())
491-
result = []
492-
ast_dump(ast_root, print=result.append)
493-
assert len(result) > 10000
494-
assert result[0] == "<Module"
495-
assert result[-1] == ">"
496-
497-
def count(pat):
498-
return sum(1 for line in result if re.search(pat, line))
499-
500-
assert count(r"^\s+>") > 2000
501-
assert count(r"<Name @ \d+,\d+(:\d+)? id: '\w+'>") > 1000
487+
files = [
488+
os.path.join(TESTS_DIR, "../coverage/parser.py"),
489+
os.path.join(TESTS_DIR, "stress_phystoken.tok"),
490+
]
491+
for fname in files:
492+
with open(fname) as f:
493+
source = f.read()
494+
num_lines = len(source.splitlines())
495+
print(f"file {fname} has {num_lines} lines")
496+
ast_root = ast_parse(source)
497+
result = []
498+
ast_dump(ast_root, print=result.append)
499+
if num_lines < 100:
500+
continue
501+
assert len(result) > 5 * num_lines
502+
assert result[0] == "<Module"
503+
assert result[-1] == ">"
504+
result_text = "\n".join(result)
505+
assert len(re_lines(result_text, r"^\s+>")) > num_lines
506+
assert len(re_lines(result_text, r"<Name @ \d+,\d+(:\d+)? id: '\w+'>")) > num_lines // 2

tests/test_phystokens.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from coverage.python import get_python_source
1616

1717
from tests.coveragetest import CoverageTest, TESTS_DIR
18+
from tests.helpers import re_lines
1819

1920

2021
# A simple program and its token stream.
@@ -97,10 +98,15 @@ def test_tokenize_real_file(self):
9798

9899
def test_stress(self):
99100
# Check the tokenization of a stress-test file.
101+
# And check that those files haven't been incorrectly "fixed".
100102
stress = os.path.join(TESTS_DIR, "stress_phystoken.tok")
101103
self.check_file_tokenization(stress)
104+
with open(stress) as fstress:
105+
assert re_lines(fstress.read(), r"\s$"), f"{stress} needs a trailing space."
102106
stress = os.path.join(TESTS_DIR, "stress_phystoken_dos.tok")
103107
self.check_file_tokenization(stress)
108+
with open(stress) as fstress:
109+
assert re_lines(fstress.read(), r"\s$"), f"{stress} needs a trailing space."
104110

105111

106112
@pytest.mark.skipif(not env.PYBEHAVIOR.soft_keywords, reason="Soft keywords are new in Python 3.10")

0 commit comments

Comments
 (0)