Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make pytype conformance test a little faster. #1559

Merged
merged 1 commit into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions conformance/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
tomli
tomlkit
tqdm
pyright
mypy
pyre-check
Expand Down
3 changes: 1 addition & 2 deletions conformance/results/pytype/aliases_type_statement.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ notes = """
Does not support `type` statement.
"""
output = """
File "aliases_type_statement.py", line 8: Type statement is only supported in Python 3.12 and greater [python-compiler-error]
"""
SyntaxError: Type statement is only supported in Python 3.12 and greater (<unknown>, line 8)"""
25 changes: 25 additions & 0 deletions conformance/results/pytype/literals_literalstring.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,29 @@ notes = """
Does not understand `LiteralString` special form.
"""
output = """
File "literals_literalstring.py", line 8, in <module>: typing.LiteralString not supported yet [not-supported-yet]
File "literals_literalstring.py", line 24, in my_function: bad return type [bad-return-type]
Expected: str
Actually returned: None
File "literals_literalstring.py", line 36, in <module>: Invalid type annotation 'Literal' [invalid-annotation]
Bad parameter 'str' at index 1
File "literals_literalstring.py", line 37, in <module>: Invalid type annotation 'Literal' [invalid-annotation]
Bad parameter 'str' at index 0
File "literals_literalstring.py", line 43, in func1: Type annotation for x2 does not match type of assignment [annotation-type-mismatch]
Annotation: Literal['']
Assignment: Literal['two']
File "literals_literalstring.py", line 74, in func2: Type annotation for x3 does not match type of assignment [annotation-type-mismatch]
Annotation: str
Assignment: int
File "literals_literalstring.py", line 75, in func2: Type annotation for x4 does not match type of assignment [annotation-type-mismatch]
Annotation: str
Assignment: bytes
File "literals_literalstring.py", line 157, in func8: bad return type [bad-return-type]
Expected: int
Actually returned: None
Called from (traceback):
line 160, in current file
File "literals_literalstring.py", line 162, in <module>: bool [assert-type]
Expected: str
Actual: bool
"""
9 changes: 9 additions & 0 deletions conformance/results/pytype/typeddicts_operations.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,24 @@ output = """
File "typeddicts_operations.py", line 28, in <module>: Type annotation for movie does not match type of assignment [annotation-type-mismatch]
Annotation: Movie(TypedDict)
Assignment: Dict[str, str]

TypedDict missing keys: year
File "typeddicts_operations.py", line 29, in <module>: Type annotation for movie does not match type of assignment [annotation-type-mismatch]
Annotation: Movie(TypedDict)
Assignment: Dict[str, Union[float, str]]

TypedDict type errors:
{'year': ...}: expected int, got float
File "typeddicts_operations.py", line 32, in <module>: Type annotation for movie does not match type of assignment [annotation-type-mismatch]
Annotation: Movie(TypedDict)
Assignment: Dict[str, Union[int, str]]

TypedDict extra keys: other
File "typeddicts_operations.py", line 37, in func1: Type annotation for movie does not match type of assignment [annotation-type-mismatch]
Annotation: Movie(TypedDict)
Assignment: Dict[str, Union[int, str]]

TypedDict missing keys: name
File "typeddicts_operations.py", line 60, in <module>: str [assert-type]
Expected: Optional[str]
Actual: str
Expand Down
2 changes: 1 addition & 1 deletion conformance/results/pytype/typeddicts_required.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ Does not reject use of `Required` in function parameter annotation.
Does not reject nested use of `Required` in type annotation.
"""
output = """
"""
RecursionError: maximum recursion depth exceeded"""
9 changes: 9 additions & 0 deletions conformance/results/pytype/typeddicts_type_consistency.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,22 @@ output = """
File "typeddicts_type_consistency.py", line 62, in <module>: Type annotation for a3 does not match type of assignment [annotation-type-mismatch]
Annotation: A3(TypedDict)
Assignment: B3

TypedDict extra keys: y
File "typeddicts_type_consistency.py", line 65, in <module>: Type annotation for b3 does not match type of assignment [annotation-type-mismatch]
Annotation: B3(TypedDict)
Assignment: Dict[str, int]

TypedDict missing keys: y
File "typeddicts_type_consistency.py", line 69, in <module>: Type annotation for a3_1 does not match type of assignment [annotation-type-mismatch]
Annotation: A3(TypedDict)
Assignment: Dict[str, int]

TypedDict extra keys: y
File "typeddicts_type_consistency.py", line 124, in <module>: Type annotation for o2 does not match type of assignment [annotation-type-mismatch]
Annotation: Outer1(TypedDict)
Assignment: Dict[str, Dict[str, Dict[str, int]]]

TypedDict type errors:
{'outer_key': ...}: expected Inner2, got Dict[str, Dict[str, int]]
"""
3 changes: 3 additions & 0 deletions conformance/results/pytype/typeddicts_usage.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,7 @@ File "typeddicts_usage.py", line 24, in <module>: Type annotation for key year i
File "typeddicts_usage.py", line 28, in <module>: Type annotation for movie2 does not match type of assignment [annotation-type-mismatch]
Annotation: Movie(TypedDict)
Assignment: Dict[str, Union[int, str]]

TypedDict missing keys: name
TypedDict extra keys: title
"""
2 changes: 1 addition & 1 deletion conformance/results/pytype/version.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
version = "pytype 2023.12.18"
test_duration = 51.5667941570282
test_duration = 28.1415696144104
2 changes: 1 addition & 1 deletion conformance/results/results.html
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ <h3>Python Type System Conformance Test Results</h3>
<tr><th>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</th><th class="column col1">narrowing_typeguard</th><th class="column col2 partially-conformant">Partial</th><th class="column col3">Does not support `tuple` in `assert_type` call.<br>Does not reject TypeGuard method with too few parameters.<br></th></tr>
<tr><th class="column spacer" colspan="4"></th></tr>
</table></div>
<div class='tc-header'><span class='tc-name'>pytype 2023.12.18<span class='tc-time'>(51.57sec)</span>
<div class='tc-header'><span class='tc-name'>pytype 2023.12.18<span class='tc-time'>(28.14sec)</span>
</div>
<div class="table_container"><table>
<tr><th class="column spacer" colspan="4"></th></tr>
Expand Down
57 changes: 21 additions & 36 deletions conformance/src/type_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@
from abc import ABC, abstractmethod
import json
from pathlib import Path
import os
from pytype import config as pytype_config
from pytype import io as pytype_io
from pytype import load_pytd as pytype_loader
import re
from subprocess import PIPE, run
import sys
from tqdm import tqdm
from typing import Sequence


Expand Down Expand Up @@ -192,47 +197,27 @@ def run_tests(self, test_files: Sequence[str]) -> dict[str, str]:
# Specify 3.11 for now to work around the fact that pytype
# currently doesn't support 3.12 and emits an error when
# running on 3.12.
command = f"{sys.executable} -m pytype -V 3.11 -k *.py"
proc = run(command, stdout=PIPE, text=True, shell=True)
lines = proc.stdout.split("\n")
options = pytype_config.Options.create(
python_version=(3, 11),
quick=True)
loader = pytype_loader.create_loader(options)

# Add results to a dictionary keyed by the file name.
results_dict: dict[str, str] = {}
accumulated_lines: list[str] = []
file_name: str | None = None

def log_accumulated():
if file_name is not None:
results_dict[file_name] = (
results_dict.get(file_name, "") + "".join(accumulated_lines) + "\n"
)

for line in lines:
match = re.search(r'File "(.*?)",', line)

if not match or match.start() != 0:
# An empty line precedes the summary for the file. Ignore
# everything after that line until we see diagnostics for
# the next file.
if line.strip() == "":
log_accumulated()
file_name = None
accumulated_lines = []
elif file_name is not None:
accumulated_lines.append("\n" + line)
for fi in tqdm(os.listdir('.')):
if not fi.endswith('.py'):
continue
options.tweak(input=fi)
with open(fi, 'r') as test_file:
src = test_file.read()
try:
errorlog = pytype_io.check_py(
src, options=options, loader=loader)
except Exception as e:
results_dict[fi] = f'{e.__class__.__name__}: {e}'
else:
log_accumulated()

file_path = Path(match.group(1))
file_name = file_path.name

# Replace the full file path with the file name.
line = f'File "{file_name}",{line[match.end():]}'
accumulated_lines = [line]

# Log the final accumulated lines.
log_accumulated()

results_dict[fi] = str(errorlog)
return results_dict


Expand Down
Loading