Skip to content

Commit ddf754a

Browse files
authored
Merge pull request #86 from nicoddemus/type-checking
2 parents df38531 + 96cdca4 commit ddf754a

File tree

11 files changed

+371
-177
lines changed

11 files changed

+371
-177
lines changed

.pre-commit-config.yaml

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1-
exclude: '^($|.*\.bin)'
1+
default_language_version:
2+
python: "3.10"
23
repos:
4+
- repo: https://github.com/myint/autoflake
5+
rev: v1.5.3
6+
hooks:
7+
- id: autoflake
8+
name: autoflake
9+
args: [ "--in-place", "--remove-unused-variables", "--remove-all-unused-imports" ]
10+
language: python
11+
files: \.py$
312
- repo: https://github.com/asottile/reorder_python_imports
413
rev: v3.8.2
514
hooks:
@@ -11,7 +20,6 @@ repos:
1120
hooks:
1221
- id: black
1322
args: [--safe, --quiet]
14-
language_version: python3.7
1523
- repo: https://github.com/pre-commit/pre-commit-hooks
1624
rev: v4.2.0
1725
hooks:
@@ -25,3 +33,11 @@ repos:
2533
files: README.rst
2634
language: python
2735
additional_dependencies: [pygments, restructuredtext_lint]
36+
- repo: https://github.com/pre-commit/mirrors-mypy
37+
rev: v0.971
38+
hooks:
39+
- id: mypy
40+
files: src/
41+
args: []
42+
additional_dependencies:
43+
- pytest>=7

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
# 2.2.1 (2022-09-23)
2+
3+
- Fixed a problem while handling errors using``--gtest_filter``. The recommendation is to use pytest's own
4+
filtering facilities (like `-k`) instead of passing filtering arguments to the underlying framework
5+
([#84](https://github.com/pytest-dev/pytest-cpp/issues/84)).
6+
7+
18
# 2.2.0 (2022-08-22)
29

310
- Dropped support for Python 3.6.

README.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ pytest's ``-o`` option:
9999
100100
$ pytest -o cpp_arguments='-v --log-dir=logs'
101101
102+
**Important**: do not pass filtering arguments (for example ``--gtest_filter``), as this will conflict
103+
with the plugin functionality and behave incorrectly.
104+
105+
To filter tests, use the standard pytest filtering facilities (such as ``-k``).
106+
102107
cpp_ignore_py_files
103108
^^^^^^^^^^^^^^^^^^^
104109

mypy.ini

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[mypy]
2+
files = src
3+
check_untyped_defs = True
4+
disallow_any_generics = True
5+
ignore_missing_imports = True
6+
no_implicit_optional = True
7+
show_error_codes = True
8+
strict_equality = True
9+
warn_redundant_casts = True
10+
warn_return_any = True
11+
warn_unreachable = True
12+
warn_unused_configs = True
13+
no_implicit_reexport = True
14+
local_partial_types = True
15+
disallow_untyped_defs = True
16+
; workaround for https://github.com/python/mypy/issues/10709
17+
ignore_missing_imports_per_module = True

src/pytest_cpp/boost.py

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
1+
from __future__ import annotations
2+
13
import io
24
import os
3-
import shutil
45
import subprocess
56
import tempfile
7+
from typing import Sequence
68
from xml.etree import ElementTree
79

810
from pytest_cpp.error import CppTestFailure
11+
from pytest_cpp.error import Markup
12+
from pytest_cpp.facade_abc import AbstractFacade
913

1014

11-
class BoostTestFacade(object):
15+
class BoostTestFacade(AbstractFacade):
1216
"""
1317
Facade for BoostTests.
1418
"""
1519

1620
@classmethod
17-
def is_test_suite(cls, executable):
21+
def is_test_suite(cls, executable: str) -> bool:
1822
try:
1923
output = subprocess.check_output(
2024
[executable, "--help"],
@@ -26,37 +30,41 @@ def is_test_suite(cls, executable):
2630
else:
2731
return "--output_format" in output and "log_format" in output
2832

29-
def list_tests(self, executable):
33+
def list_tests(self, executable: str) -> list[str]:
3034
# unfortunately boost doesn't provide us with a way to list the tests
3135
# inside the executable, so the test_id is a dummy placeholder :(
3236
return [os.path.basename(os.path.splitext(executable)[0])]
3337

34-
def run_test(self, executable, test_id, test_args=(), harness=None):
35-
harness = harness or []
36-
37-
def read_file(name):
38+
def run_test(
39+
self,
40+
executable: str,
41+
test_id: str,
42+
test_args: Sequence[str] = (),
43+
harness: Sequence[str] = (),
44+
) -> tuple[Sequence[BoostTestFailure] | None, str]:
45+
def read_file(name: str) -> str:
3846
try:
3947
with io.open(name) as f:
4048
return f.read()
4149
except IOError:
42-
return None
43-
44-
temp_dir = tempfile.mkdtemp()
45-
log_xml = os.path.join(temp_dir, "log.xml")
46-
report_xml = os.path.join(temp_dir, "report.xml")
47-
args = harness + [
48-
executable,
49-
"--output_format=XML",
50-
"--log_sink=%s" % log_xml,
51-
"--report_sink=%s" % report_xml,
52-
]
53-
args.extend(test_args)
54-
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
55-
raw_stdout, _ = p.communicate()
56-
stdout = raw_stdout.decode("utf-8") if raw_stdout else ""
57-
58-
log = read_file(log_xml)
59-
report = read_file(report_xml)
50+
return ""
51+
52+
with tempfile.TemporaryDirectory(prefix="pytest-cpp") as temp_dir:
53+
log_xml = os.path.join(temp_dir, "log.xml")
54+
report_xml = os.path.join(temp_dir, "report.xml")
55+
args = list(harness) + [
56+
executable,
57+
"--output_format=XML",
58+
"--log_sink=%s" % log_xml,
59+
"--report_sink=%s" % report_xml,
60+
]
61+
args.extend(test_args)
62+
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
63+
raw_stdout, _ = p.communicate()
64+
stdout = raw_stdout.decode("utf-8") if raw_stdout else ""
65+
66+
log = read_file(log_xml)
67+
report = read_file(report_xml)
6068

6169
if p.returncode not in (0, 200, 201):
6270
msg = (
@@ -81,14 +89,13 @@ def read_file(name):
8189
return [failure], stdout
8290

8391
results = self._parse_log(log=log)
84-
shutil.rmtree(temp_dir)
8592

8693
if results:
8794
return results, stdout
8895

8996
return None, stdout
9097

91-
def _parse_log(self, log):
98+
def _parse_log(self, log: str) -> list[BoostTestFailure]:
9299
"""
93100
Parse the "log" section produced by BoostTest.
94101
@@ -116,19 +123,19 @@ def _parse_log(self, log):
116123
for elem in parsed_elements:
117124
filename = elem.attrib["file"]
118125
linenum = int(elem.attrib["line"])
119-
result.append(BoostTestFailure(filename, linenum, elem.text))
126+
result.append(BoostTestFailure(filename, linenum, elem.text or ""))
120127
return result
121128

122129

123130
class BoostTestFailure(CppTestFailure):
124-
def __init__(self, filename, linenum, contents):
131+
def __init__(self, filename: str, linenum: int, contents: str) -> None:
125132
self.filename = filename
126133
self.linenum = linenum
127134
self.lines = contents.splitlines()
128135

129-
def get_lines(self):
136+
def get_lines(self) -> list[tuple[str, Markup]]:
130137
m = ("red", "bold")
131138
return [(x, m) for x in self.lines]
132139

133-
def get_file_reference(self):
140+
def get_file_reference(self) -> tuple[str, int]:
134141
return self.filename, self.linenum

0 commit comments

Comments
 (0)