Skip to content

Commit be6f145

Browse files
committed
apply suggestions from code review
1 parent 9c26d9d commit be6f145

13 files changed

Lines changed: 85 additions & 80 deletions

.vscode/settings.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,7 @@
44
"tests"
55
],
66
"python.testing.unittestEnabled": false,
7-
"python.testing.pytestEnabled": true
7+
"python.testing.pytestEnabled": true,
8+
"python-envs.defaultEnvManager": "ms-python.python:venv",
9+
"python-envs.pythonProjects": []
810
}

tests/conftest.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
# Note that this conftest file exists at the package level as it is needed to configure
22
# the JVM for docstrings at the package level.
3-
from collections.abc import Generator
4-
from pathlib import Path
53
import logging
64
import tempfile
5+
import textwrap
6+
from collections.abc import Generator
7+
from pathlib import Path
8+
79
import pytest
810

911
import chaquopy_stubgen
@@ -22,10 +24,11 @@ def jvm():
2224
import jpype.imports # type: ignore
2325

2426
try:
25-
yield jpype
27+
yield jpype
2628
finally:
2729
jpype.shutdownJVM()
2830

31+
2932
@pytest.fixture(scope="session")
3033
def stub_dir(jvm) -> Generator[Path, None, None]:
3134
# logging.basicConfig(level="DEBUG")
@@ -47,7 +50,20 @@ def stub_dir(jvm) -> Generator[Path, None, None]:
4750

4851

4952
@pytest.fixture(scope="session")
50-
def mypy_project_dir() -> Generator[Path, None, None]:
53+
def mypy_project_dir(stub_dir: Path) -> Generator[Path, None, None]:
5154
with tempfile.TemporaryDirectory() as tmp:
52-
yield Path(tmp)
53-
55+
project_dir = Path(tmp)
56+
with project_dir.joinpath("pyproject.toml").open("w") as f:
57+
f.write(
58+
textwrap.dedent(
59+
f"""\
60+
[tool.mypy]
61+
mypy_path = "{stub_dir.absolute()}"
62+
63+
[[tool.mypy.overrides]]
64+
module = "java.*"
65+
ignore_errors = true
66+
"""
67+
)
68+
)
69+
yield project_dir

tests/mypy_helper.py

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import json
33
import logging
44
import os
5-
import textwrap
5+
import re
66
import tokenize
77
from collections.abc import Generator
88
from contextlib import contextmanager
@@ -46,24 +46,9 @@ def _parse_mypy_jsonl_output(mypy_stdout: str) -> list[MypyMessage]:
4646

4747
def run_mypy(
4848
project_dir: Path,
49-
extra_stub: Path,
5049
test_code: str,
5150
) -> str:
5251
"""Run mypy on the given test code and return the mypy stdout."""
53-
with project_dir.joinpath("pyproject.toml").open("w") as f:
54-
f.write(
55-
textwrap.dedent(
56-
f"""\
57-
[tool.mypy]
58-
mypy_path = "{extra_stub.absolute()}"
59-
60-
[[tool.mypy.overrides]]
61-
module = "java.*"
62-
ignore_errors = true
63-
"""
64-
)
65-
)
66-
6752
testfile_name = "testfile.py"
6853
with project_dir.joinpath(testfile_name).open("w") as f:
6954
f.write(test_code)
@@ -81,7 +66,6 @@ def run_mypy(
8166

8267
def run_and_assert_mypy(
8368
project_dir: Path,
84-
extra_stub: Path,
8569
test_code: str,
8670
expected_output: dict[str, str] | str,
8771
):
@@ -94,7 +78,7 @@ def run_and_assert_mypy(
9478
- A raw string containing the expected mypy output. In this case, the function will compare
9579
the raw mypy stdout with the expected string.
9680
"""
97-
mypy_stdout = run_mypy(project_dir, extra_stub, test_code)
81+
mypy_stdout = run_mypy(project_dir, test_code)
9882
if isinstance(expected_output, dict):
9983
mypy_output = _parse_mypy_jsonl_output(mypy_stdout)
10084
assert_mypy_json_output(test_code, mypy_output, expected_output)
@@ -122,9 +106,7 @@ def _parse_marked_lines_with_tokenize(code: str) -> dict[str, int]:
122106

123107
for token in tokens:
124108
if token.type == tokenize.COMMENT:
125-
# Token.string contains the comment including the #
126-
import re
127-
109+
# token.string contains the comment including the #
128110
match = re.search(r"#\s*\*(\d+)", token.string)
129111
if match:
130112
marker = f"*{match.group(1)}"
@@ -143,6 +125,11 @@ def assert_mypy_json_output(
143125
# Parse the code to find the marked lines
144126
marked_lines: dict[str, int] = _parse_marked_lines_with_tokenize(code)
145127

128+
# Validate that all expected markers are present in the code
129+
missing_markers = set(expected_output.keys()) - set(marked_lines.keys())
130+
if missing_markers:
131+
assert False, f"Expected markers not found in code: {', '.join(sorted(missing_markers))}"
132+
146133
# Group messages by line number
147134
result_by_line: dict[int, list[MypyMessage]] = {}
148135
for msg in mypy_output:
@@ -168,5 +155,5 @@ def assert_mypy_json_output(
168155
unexpected_msgs = []
169156
for line, msgs in result_by_line.items():
170157
for msg in msgs:
171-
unexpected_msgs.append(_format_mypy_msg(msg))
172-
assert False, f"Unexpected mypy message in line {line}:\n{unexpected_msgs}"
158+
unexpected_msgs.append(f"line {line}: {_format_mypy_msg(msg)}")
159+
assert False, "Unexpected mypy messages:\n" + "\n".join(unexpected_msgs)

tests/test_array_list.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from .mypy_helper import run_and_assert_mypy
44

55

6-
def test_array_list_valid(stub_dir: Path, mypy_project_dir: Path):
6+
def test_array_list_valid(mypy_project_dir: Path):
77
code = """\
88
from java.util import ArrayList
99
@@ -21,10 +21,10 @@ def test_array_list_valid(stub_dir: Path, mypy_project_dir: Path):
2121
note: Revealed type is "builtins.str"''',
2222
}
2323

24-
run_and_assert_mypy(mypy_project_dir, stub_dir, code, expected_mypy_output)
24+
run_and_assert_mypy(mypy_project_dir, code, expected_mypy_output)
2525

2626

27-
def test_array_list_invalid(stub_dir: Path, mypy_project_dir: Path):
27+
def test_array_list_invalid(mypy_project_dir: Path):
2828
code = """\
2929
from java.util import ArrayList
3030
@@ -40,10 +40,10 @@ def test_array_list_invalid(stub_dir: Path, mypy_project_dir: Path):
4040
hint: def add(self, int: int | jint | Integer, e: str) -> None""",
4141
}
4242

43-
run_and_assert_mypy(mypy_project_dir, stub_dir, code, expected_mypy_output)
43+
run_and_assert_mypy(mypy_project_dir, code, expected_mypy_output)
4444

4545

46-
def test_array_list_no_implicit_conversion(stub_dir: Path, mypy_project_dir: Path):
46+
def test_array_list_no_implicit_conversion(mypy_project_dir: Path):
4747
code = """\
4848
from java.util import ArrayList
4949
@@ -60,10 +60,10 @@ def test_array_list_no_implicit_conversion(stub_dir: Path, mypy_project_dir: Pat
6060
hint: def [_ArrayList__E] ArrayList(self, collection: Collection[_ArrayList__E]) -> ArrayList[_ArrayList__E]""",
6161
}
6262

63-
run_and_assert_mypy(mypy_project_dir, stub_dir, code, expected_mypy_output)
63+
run_and_assert_mypy(mypy_project_dir, code, expected_mypy_output)
6464

6565

66-
def test_array_list_missing_type_annotation(stub_dir: Path, mypy_project_dir: Path):
66+
def test_array_list_missing_type_annotation(mypy_project_dir: Path):
6767
code = """\
6868
from java.util import ArrayList
6969
@@ -74,10 +74,10 @@ def test_array_list_missing_type_annotation(stub_dir: Path, mypy_project_dir: Pa
7474
"*1": 'error: Need type annotation for "java_array_list"',
7575
}
7676

77-
run_and_assert_mypy(mypy_project_dir, stub_dir, code, expected_mypy_output)
77+
run_and_assert_mypy(mypy_project_dir, code, expected_mypy_output)
7878

7979

80-
def test_array_list_no_getitem(stub_dir: Path, mypy_project_dir: Path):
80+
def test_array_list_no_getitem(mypy_project_dir: Path):
8181
code = """\
8282
from java.util import ArrayList
8383
@@ -89,4 +89,4 @@ def test_array_list_no_getitem(stub_dir: Path, mypy_project_dir: Path):
8989
"*1": 'error: Value of type "ArrayList[str]" is not indexable',
9090
}
9191

92-
run_and_assert_mypy(mypy_project_dir, stub_dir, code, expected_mypy_output)
92+
run_and_assert_mypy(mypy_project_dir, code, expected_mypy_output)

tests/test_callbacks.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from .mypy_helper import run_and_assert_mypy
44

55

6-
def test_bifunction_callback(stub_dir: Path, mypy_project_dir: Path):
6+
def test_bifunction_callback(mypy_project_dir: Path):
77
code = """\
88
import typing
99
@@ -63,10 +63,10 @@ def invalid_for_each_cb_2(k: str) -> None:
6363
"*2": 'error: Argument 1 to "PyBiConsumer" has incompatible type "Callable[[str], None]"; expected "Callable[[str, float], None]"',
6464
}
6565

66-
run_and_assert_mypy(mypy_project_dir, stub_dir, code, expected_mypy_output)
66+
run_and_assert_mypy(mypy_project_dir, code, expected_mypy_output)
6767

6868

69-
def test_predicate_callback(stub_dir: Path, mypy_project_dir: Path):
69+
def test_predicate_callback(mypy_project_dir: Path):
7070
code = """\
7171
import typing
7272
@@ -135,10 +135,10 @@ def invalid_predicate_3(k: str) -> int:
135135
"*3": 'error: Argument 1 to "PyPredicate" has incompatible type "Callable[[str], int]"; expected "Callable[[str], bool]"',
136136
}
137137

138-
run_and_assert_mypy(mypy_project_dir, stub_dir, code, expected_mypy_output)
138+
run_and_assert_mypy(mypy_project_dir, code, expected_mypy_output)
139139

140140

141-
def test_stream_chaining_and_type_inference(stub_dir: Path, mypy_project_dir: Path):
141+
def test_stream_chaining_and_type_inference(mypy_project_dir: Path):
142142
code = """\
143143
import typing
144144
@@ -238,4 +238,4 @@ def map_atomicint_to_bool(v: AtomicInteger) -> bool:
238238
"*6": 'note: Revealed type is "java.util.Set[java.util.concurrent.atomic.AtomicInteger]"',
239239
}
240240

241-
run_and_assert_mypy(mypy_project_dir, stub_dir, code, expected_mypy_output)
241+
run_and_assert_mypy(mypy_project_dir, code, expected_mypy_output)

tests/test_enummap.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from .mypy_helper import run_and_assert_mypy
44

55

6-
def test_enum_map_valid(stub_dir: Path, mypy_project_dir: Path):
6+
def test_enum_map_valid(mypy_project_dir: Path):
77
code = """\
88
import typing
99
from java.util import EnumMap
@@ -19,10 +19,10 @@ def test_enum_map_valid(stub_dir: Path, mypy_project_dir: Path):
1919
"*1": 'note: Revealed type is "java.util.EnumMap[java.util.concurrent.TimeUnit, Any]"',
2020
}
2121

22-
run_and_assert_mypy(mypy_project_dir, stub_dir, code, expected_mypy_output)
22+
run_and_assert_mypy(mypy_project_dir, code, expected_mypy_output)
2323

2424

25-
def test_enum_map_invalid(stub_dir: Path, mypy_project_dir: Path):
25+
def test_enum_map_invalid(mypy_project_dir: Path):
2626
code = """\
2727
import typing
2828
from java.util import EnumMap
@@ -40,4 +40,4 @@ def test_enum_map_invalid(stub_dir: Path, mypy_project_dir: Path):
4040
"*2": 'error: Argument 1 to "put" of "EnumMap" has incompatible type "str"; expected "TimeUnit"',
4141
}
4242

43-
run_and_assert_mypy(mypy_project_dir, stub_dir, code, expected_mypy_output)
43+
run_and_assert_mypy(mypy_project_dir, code, expected_mypy_output)

tests/test_exception.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from .mypy_helper import run_and_assert_mypy
44

55

6-
def test_java_exception(stub_dir: Path, mypy_project_dir: Path):
6+
def test_java_exception(mypy_project_dir: Path):
77
code = """\
88
from java.lang import Exception
99
java_exception = Exception("Testing")
@@ -17,4 +17,4 @@ def test_java_exception(stub_dir: Path, mypy_project_dir: Path):
1717
"*1": 'note: Revealed type is "java.lang.Exception"',
1818
}
1919

20-
run_and_assert_mypy(mypy_project_dir, stub_dir, code, expected_mypy_output)
20+
run_and_assert_mypy(mypy_project_dir, code, expected_mypy_output)

tests/test_forward_declaration.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from .mypy_helper import run_and_assert_mypy
44

55

6-
def test_argument_type_declaration(stub_dir: Path, mypy_project_dir: Path):
6+
def test_argument_type_declaration(mypy_project_dir: Path):
77
code = """\
88
import typing
99
@@ -18,4 +18,4 @@ def foo(arg: "java.util.Formatter"):
1818
"*1": 'note: Revealed type is "java.util.Formatter"',
1919
}
2020

21-
run_and_assert_mypy(mypy_project_dir, stub_dir, code, expected_mypy_output)
21+
run_and_assert_mypy(mypy_project_dir, code, expected_mypy_output)

tests/test_hashmap.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from .mypy_helper import run_and_assert_mypy
44

55

6-
def test_hash_map_valid(stub_dir: Path, mypy_project_dir: Path):
6+
def test_hash_map_valid(mypy_project_dir: Path):
77
code = """\
88
from java.util import HashMap
99
@@ -27,10 +27,10 @@ def test_hash_map_valid(stub_dir: Path, mypy_project_dir: Path):
2727
"*4": 'note: Revealed type is "builtins.float"',
2828
}
2929

30-
run_and_assert_mypy(mypy_project_dir, stub_dir, code, expected_mypy_output)
30+
run_and_assert_mypy(mypy_project_dir, code, expected_mypy_output)
3131

3232

33-
def test_hash_map_invalid(stub_dir: Path, mypy_project_dir: Path):
33+
def test_hash_map_invalid(mypy_project_dir: Path):
3434
code = """\
3535
from java.util import HashMap
3636
@@ -45,4 +45,4 @@ def test_hash_map_invalid(stub_dir: Path, mypy_project_dir: Path):
4545
"*1": 'error: Argument 2 to "put" of "HashMap" has incompatible type "str"; expected "float"',
4646
}
4747

48-
run_and_assert_mypy(mypy_project_dir, stub_dir, code, expected_mypy_output)
48+
run_and_assert_mypy(mypy_project_dir, code, expected_mypy_output)

tests/test_jarray.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from .mypy_helper import run_and_assert_mypy
44

55

6-
def test_java_array_as_return_type(stub_dir: Path, mypy_project_dir: Path):
6+
def test_java_array_as_return_type(mypy_project_dir: Path):
77
code = """\
88
from java.lang import String
99
@@ -19,10 +19,10 @@ def test_java_array_as_return_type(stub_dir: Path, mypy_project_dir: Path):
1919
"*3": 'note: Revealed type is "java.chaquopy.JavaArrayJChar"',
2020
}
2121

22-
run_and_assert_mypy(mypy_project_dir, stub_dir, code, expected_mypy_output)
22+
run_and_assert_mypy(mypy_project_dir, code, expected_mypy_output)
2323

2424

25-
def test_java_array_as_parameter(stub_dir: Path, mypy_project_dir: Path):
25+
def test_java_array_as_parameter(mypy_project_dir: Path):
2626
code = """\
2727
from java.lang import String
2828
from java import jarray, jchar, jint, jbyte
@@ -62,4 +62,4 @@ def test_java_array_as_parameter(stub_dir: Path, mypy_project_dir: Path):
6262
hint: def String(self, stringBuilder: StringBuilder) -> String""",
6363
}
6464

65-
run_and_assert_mypy(mypy_project_dir, stub_dir, code, expected_mypy_output)
65+
run_and_assert_mypy(mypy_project_dir, code, expected_mypy_output)

0 commit comments

Comments
 (0)