Skip to content

Commit fe5d2c5

Browse files
committed
Make mypy stricter
Well, sort of. We immediately disable many of the strict checks for most modules, but doing things this way allows us to iteratively add types. Signed-off-by: Stephen Finucane <[email protected]>
1 parent baf3bdc commit fe5d2c5

File tree

7 files changed

+60
-21
lines changed

7 files changed

+60
-21
lines changed

pyproject.toml

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,16 @@ __version__ = {version_tuple!r}
5757
only-include = ["testtools"]
5858

5959
[tool.mypy]
60-
warn_redundant_casts = true
61-
warn_unused_configs = true
62-
check_untyped_defs = true
60+
python_version = "3.10"
61+
show_column_numbers = true
62+
show_error_context = true
63+
strict = true
64+
# this is here temporarily due to the rapid changes in typing across
65+
# dependencies
66+
warn_unused_ignores = false
67+
# FIXME(stephenfin): We should remove this
68+
implicit_reexport = true
69+
exclude = 'doc'
6370

6471
[[tool.mypy.overrides]]
6572
module = [
@@ -68,6 +75,30 @@ module = [
6875
]
6976
ignore_missing_imports = true
7077

78+
[[tool.mypy.overrides]]
79+
module = [
80+
# FIXME(stephenfin): We would like to remove all modules from this list
81+
# except testtools.tests (we're not sadists)
82+
"testtools.assertions",
83+
"testtools.compat",
84+
"testtools.content",
85+
"testtools.content_type",
86+
"testtools.matchers.*",
87+
"testtools.monkey",
88+
"testtools.run",
89+
"testtools.runtest",
90+
"testtools.tags",
91+
"testtools.testcase",
92+
"testtools.testresult.*",
93+
"testtools.testsuite",
94+
"testtools.twistedsupport.*",
95+
"testtools.tests.*",
96+
]
97+
disallow_untyped_calls = false
98+
disallow_untyped_defs = false
99+
disallow_subclassing_any = false
100+
disallow_any_generics = false
101+
71102
[tool.ruff.lint]
72103
select = [
73104
"E",
@@ -78,8 +109,7 @@ select = [
78109
"RSE",
79110
"RUF",
80111
]
81-
ignore = [
82-
]
112+
ignore = []
83113

84114
[tool.ruff.lint.pydocstyle]
85115
convention = "google"

testtools/__init__.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
)
9595

9696

97-
def __get_git_version():
97+
def __get_git_version() -> str | None:
9898
import os
9999
import subprocess
100100

@@ -135,9 +135,10 @@ def __get_git_version():
135135
from ._version import __version__, version
136136
except ModuleNotFoundError:
137137
# package is not installed
138-
if version := __get_git_version():
138+
if v := __get_git_version():
139+
version = v
139140
# we're in a git repo
140-
__version__ = tuple([int(v) if v.isdigit() else v for v in version.split(".")])
141+
__version__ = tuple([int(x) if x.isdigit() else x for x in version.split(".")])
141142
else:
142143
# we're working with a tarball or similar
143144
version = "0.0.0"

testtools/compat.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,20 @@
1616
import locale
1717
import os
1818
import sys
19-
import typing
19+
import types
20+
from typing import Any, NoReturn
2021
import unicodedata
2122

2223
# Ensure retro-compatibility with older testtools releases
2324
from io import BytesIO, StringIO
2425

2526

26-
def reraise(exc_class, exc_obj, exc_tb, _marker=object()) -> typing.NoReturn:
27+
def reraise(
28+
exc_class: type[BaseException],
29+
exc_obj: BaseException,
30+
exc_tb: types.TracebackType,
31+
_marker: Any = object(),
32+
) -> NoReturn:
2733
"""Re-raise an exception received from sys.exc_info() or similar."""
2834
raise exc_obj.with_traceback(exc_tb)
2935

testtools/matchers/_dict.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"KeysEqual",
55
]
66

7-
from typing import ClassVar
7+
from typing import Any, ClassVar
88

99
from ..helpers import (
1010
dict_subtract,
@@ -132,7 +132,7 @@ def match(self, super_dict):
132132
return _SubDictOf(super_dict, self.format_value).match(self.sub_dict)
133133

134134

135-
def _format_matcher_dict(matchers):
135+
def _format_matcher_dict(matchers: dict[str, Matcher]) -> str:
136136
return "{{{}}}".format(
137137
", ".join(sorted(f"{k!r}: {v}" for k, v in matchers.items()))
138138
)
@@ -180,7 +180,7 @@ class MatchesDict(_CombinedMatcher):
180180
"Differences": _MatchCommonKeys,
181181
}
182182

183-
def format_expected(self, expected) -> str:
183+
def format_expected(self, expected: dict[str, Matcher]) -> str:
184184
return _format_matcher_dict(expected)
185185

186186

@@ -204,7 +204,7 @@ class ContainsDict(_CombinedMatcher):
204204
"Differences": _MatchCommonKeys,
205205
}
206206

207-
def format_expected(self, expected):
207+
def format_expected(self, expected: dict[str, Matcher]) -> str:
208208
return _format_matcher_dict(expected)
209209

210210

@@ -228,7 +228,7 @@ class ContainedByDict(_CombinedMatcher):
228228
"Differences": _MatchCommonKeys,
229229
}
230230

231-
def format_expected(self, expected):
231+
def format_expected(self, expected: dict[str, Matcher]) -> str:
232232
return _format_matcher_dict(expected)
233233

234234

testtools/testcase.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import itertools
2121
import sys
2222
import unittest
23-
from typing import Any, Protocol, TypeVar
23+
from typing import cast, Any, Protocol, TypeVar
2424
from unittest.case import SkipTest
2525

2626
from testtools import content
@@ -971,11 +971,11 @@ class WithAttributes:
971971
_get_test_method: Any # Provided by the class we're mixed with
972972

973973
def id(self) -> str:
974-
orig = super().id() # type: ignore[misc]
974+
orig = cast(str, super().id()) # type: ignore[misc]
975975
# Depends on testtools.TestCase._get_test_method, be nice to support
976976
# plain unittest.
977977
fn = self._get_test_method()
978-
attributes = getattr(fn, "__testtools_attrs", None)
978+
attributes = cast(str, getattr(fn, "__testtools_attrs", None))
979979
if not attributes:
980980
return orig
981981
return orig + "[" + ",".join(sorted(attributes)) + "]"

testtools/testresult/doubles.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ def startTest(self, test):
134134
self._tags = TagContext(self._tags)
135135

136136
def stopTest(self, test):
137-
self._tags = self._tags.parent
137+
# NOTE: In Python 3.12.1 skipped tests may not call startTest()
138+
if self._tags is not None and self._tags.parent is not None:
139+
self._tags = self._tags.parent
138140
super().stopTest(test)
139141

140142
@property

testtools/testresult/real.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ def startTest(self, test):
237237

238238
def stopTest(self, test):
239239
# NOTE: In Python 3.12.1 skipped tests may not call startTest()
240-
if self._tags is not None:
240+
if self._tags is not None and self._tags.parent is not None:
241241
self._tags = self._tags.parent
242242
super().stopTest(test)
243243

@@ -1701,7 +1701,7 @@ def stop(self):
17011701

17021702
def stopTest(self, test):
17031703
# NOTE: In Python 3.12.1 skipped tests may not call startTest()
1704-
if self._tags is not None:
1704+
if self._tags is not None and self._tags.parent is not None:
17051705
self._tags = self._tags.parent
17061706
return self.decorated.stopTest(test)
17071707

0 commit comments

Comments
 (0)