diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2023-01-07 21:25:42 -0500 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2023-01-07 21:25:42 -0500 |
commit | 13218037401dc30f05fd3a16a2cd52ee882fd1c4 (patch) | |
tree | c58e4361b3bc81c15196255e3c3a90cb10aa2b04 /tests/test_parser.py | |
parent | 2c527825ac0cf394b32d773fd0ca5375dd8c031b (diff) | |
download | python-coveragepy-git-13218037401dc30f05fd3a16a2cd52ee882fd1c4.tar.gz |
mypy: test_parser.py test_phystokens.py test_process.py test_report.py test_results.py test_setup.py
Diffstat (limited to 'tests/test_parser.py')
-rw-r--r-- | tests/test_parser.py | 56 |
1 files changed, 30 insertions, 26 deletions
diff --git a/tests/test_parser.py b/tests/test_parser.py index 057b9244..8009ce51 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -3,11 +3,15 @@ """Tests for coverage.py's code parsing.""" +from __future__ import annotations + import ast import os.path import textwrap import warnings +from typing import List + import pytest from coverage import env @@ -23,14 +27,14 @@ class PythonParserTest(CoverageTest): run_in_temp_dir = False - def parse_source(self, text): + def parse_source(self, text: str) -> PythonParser: """Parse `text` as source, and return the `PythonParser` used.""" text = textwrap.dedent(text) parser = PythonParser(text=text, exclude="nocover") parser.parse_source() return parser - def test_exit_counts(self): + def test_exit_counts(self) -> None: parser = self.parse_source("""\ # check some basic branch counting class Foo: @@ -47,7 +51,7 @@ class PythonParserTest(CoverageTest): 2:1, 3:1, 4:2, 5:1, 7:1, 9:1, 10:1 } - def test_generator_exit_counts(self): + def test_generator_exit_counts(self) -> None: # https://github.com/nedbat/coveragepy/issues/324 parser = self.parse_source("""\ def gen(input): @@ -63,7 +67,7 @@ class PythonParserTest(CoverageTest): 5:1, # list -> exit } - def test_try_except(self): + def test_try_except(self) -> None: parser = self.parse_source("""\ try: a = 2 @@ -79,7 +83,7 @@ class PythonParserTest(CoverageTest): 1: 1, 2:1, 3:2, 4:1, 5:2, 6:1, 7:1, 8:1, 9:1 } - def test_excluded_classes(self): + def test_excluded_classes(self) -> None: parser = self.parse_source("""\ class Foo: def __init__(self): @@ -93,7 +97,7 @@ class PythonParserTest(CoverageTest): 1:0, 2:1, 3:1 } - def test_missing_branch_to_excluded_code(self): + def test_missing_branch_to_excluded_code(self) -> None: parser = self.parse_source("""\ if fooey: a = 2 @@ -121,7 +125,7 @@ class PythonParserTest(CoverageTest): """) assert parser.exit_counts() == { 1:1, 2:1, 3:1, 6:1 } - def test_indentation_error(self): + def test_indentation_error(self) -> None: msg = ( "Couldn't parse '<code>' as Python source: " + "'unindent does not match any outer indentation level' at line 3" @@ -133,7 +137,7 @@ class PythonParserTest(CoverageTest): 1 """) - def test_token_error(self): + def test_token_error(self) -> None: msg = "Couldn't parse '<code>' as Python source: 'EOF in multi-line string' at line 1" with pytest.raises(NotPython, match=msg): _ = self.parse_source("""\ @@ -141,7 +145,7 @@ class PythonParserTest(CoverageTest): """) @xfail_pypy38 - def test_decorator_pragmas(self): + def test_decorator_pragmas(self) -> None: parser = self.parse_source("""\ # 1 @@ -177,7 +181,7 @@ class PythonParserTest(CoverageTest): assert parser.statements == {8} @xfail_pypy38 - def test_decorator_pragmas_with_colons(self): + def test_decorator_pragmas_with_colons(self) -> None: # A colon in a decorator expression would confuse the parser, # ending the exclusion of the decorated function. parser = self.parse_source("""\ @@ -197,7 +201,7 @@ class PythonParserTest(CoverageTest): assert parser.raw_statements == raw_statements assert parser.statements == set() - def test_class_decorator_pragmas(self): + def test_class_decorator_pragmas(self) -> None: parser = self.parse_source("""\ class Foo(object): def __init__(self): @@ -211,7 +215,7 @@ class PythonParserTest(CoverageTest): assert parser.raw_statements == {1, 2, 3, 5, 6, 7, 8} assert parser.statements == {1, 2, 3} - def test_empty_decorated_function(self): + def test_empty_decorated_function(self) -> None: parser = self.parse_source("""\ def decorator(func): return func @@ -247,7 +251,7 @@ class PythonParserTest(CoverageTest): assert expected_arcs == parser.arcs() assert expected_exits == parser.exit_counts() - def test_fuzzed_double_parse(self): + def test_fuzzed_double_parse(self) -> None: # https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=50381 # The second parse used to raise `TypeError: 'NoneType' object is not iterable` msg = "EOF in multi-line statement" @@ -262,13 +266,13 @@ class ParserMissingArcDescriptionTest(CoverageTest): run_in_temp_dir = False - def parse_text(self, source): + def parse_text(self, source: str) -> PythonParser: """Parse Python source, and return the parser object.""" parser = PythonParser(text=textwrap.dedent(source)) parser.parse_source() return parser - def test_missing_arc_description(self): + def test_missing_arc_description(self) -> None: # This code is never run, so the actual values don't matter. parser = self.parse_text("""\ if x: @@ -304,7 +308,7 @@ class ParserMissingArcDescriptionTest(CoverageTest): ) assert expected == parser.missing_arc_description(11, 13) - def test_missing_arc_descriptions_for_small_callables(self): + def test_missing_arc_descriptions_for_small_callables(self) -> None: parser = self.parse_text("""\ callables = [ lambda: 2, @@ -323,7 +327,7 @@ class ParserMissingArcDescriptionTest(CoverageTest): expected = "line 5 didn't finish the set comprehension on line 5" assert expected == parser.missing_arc_description(5, -5) - def test_missing_arc_descriptions_for_exceptions(self): + def test_missing_arc_descriptions_for_exceptions(self) -> None: parser = self.parse_text("""\ try: pass @@ -343,7 +347,7 @@ class ParserMissingArcDescriptionTest(CoverageTest): ) assert expected == parser.missing_arc_description(5, 6) - def test_missing_arc_descriptions_for_finally(self): + def test_missing_arc_descriptions_for_finally(self) -> None: parser = self.parse_text("""\ def function(): for i in range(2): @@ -417,7 +421,7 @@ class ParserMissingArcDescriptionTest(CoverageTest): ) assert expected == parser.missing_arc_description(18, -1) - def test_missing_arc_descriptions_bug460(self): + def test_missing_arc_descriptions_bug460(self) -> None: parser = self.parse_text("""\ x = 1 d = { @@ -429,7 +433,7 @@ class ParserMissingArcDescriptionTest(CoverageTest): assert parser.missing_arc_description(2, -3) == "line 3 didn't finish the lambda on line 3" @pytest.mark.skipif(not env.PYBEHAVIOR.match_case, reason="Match-case is new in 3.10") - def test_match_case_with_default(self): + def test_match_case_with_default(self) -> None: parser = self.parse_text("""\ for command in ["huh", "go home", "go n"]: match command.split(): @@ -450,7 +454,7 @@ class ParserMissingArcDescriptionTest(CoverageTest): class ParserFileTest(CoverageTest): """Tests for coverage.py's code parsing from files.""" - def parse_file(self, filename): + def parse_file(self, filename: str) -> PythonParser: """Parse `text` as source, and return the `PythonParser` used.""" parser = PythonParser(filename=filename, exclude="nocover") parser.parse_source() @@ -459,7 +463,7 @@ class ParserFileTest(CoverageTest): @pytest.mark.parametrize("slug, newline", [ ("unix", "\n"), ("dos", "\r\n"), ("mac", "\r"), ]) - def test_line_endings(self, slug, newline): + def test_line_endings(self, slug: str, newline: str) -> None: text = """\ # check some basic branch counting class Foo: @@ -478,14 +482,14 @@ class ParserFileTest(CoverageTest): parser = self.parse_file(fname) assert parser.exit_counts() == counts, f"Wrong for {fname!r}" - def test_encoding(self): + def test_encoding(self) -> None: self.make_file("encoded.py", """\ coverage = "\xe7\xf6v\xear\xe3g\xe9" """) parser = self.parse_file("encoded.py") assert parser.exit_counts() == {1: 1} - def test_missing_line_ending(self): + def test_missing_line_ending(self) -> None: # Test that the set of statements is the same even if a final # multi-line statement has no final newline. # https://github.com/nedbat/coveragepy/issues/293 @@ -514,7 +518,7 @@ class ParserFileTest(CoverageTest): assert parser.statements == {1} -def test_ast_dump(): +def test_ast_dump() -> None: # Run the AST_DUMP code to make sure it doesn't fail, with some light # assertions. Use parser.py as the test code since it is the longest file, # and fitting, since it's the AST_DUMP code. @@ -531,7 +535,7 @@ def test_ast_dump(): # stress_phystoken.tok has deprecation warnings, suppress them. warnings.filterwarnings("ignore", message=r".*invalid escape sequence",) ast_root = ast.parse(source) - result = [] + result: List[str] = [] ast_dump(ast_root, print=result.append) if num_lines < 100: continue |