Skip to content

Commit 9da16e8

Browse files
Strict typing (#703)
1 parent 9785283 commit 9da16e8

File tree

3 files changed

+51
-22
lines changed

3 files changed

+51
-22
lines changed

.mypy.ini

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,29 @@
11
[mypy]
2-
files =
3-
aiosignal/
4-
follow_imports = silent
5-
strict_optional = True
6-
warn_redundant_casts = True
7-
8-
# uncomment next lines
9-
# to enable strict mypy mode
10-
#
2+
files = aiosignal, tests
113
check_untyped_defs = True
4+
follow_imports_for_stubs = True
5+
disallow_any_decorated = True
126
disallow_any_generics = True
7+
disallow_any_unimported = True
8+
disallow_incomplete_defs = True
9+
disallow_subclassing_any = True
10+
disallow_untyped_calls = True
11+
disallow_untyped_decorators = True
1312
disallow_untyped_defs = True
13+
# TODO(PY312): explicit-override
14+
enable_error_code = deprecated, ignore-without-code, possibly-undefined, redundant-expr, redundant-self, truthy-bool, truthy-iterable, unused-awaitable
15+
extra_checks = True
16+
follow_untyped_imports = True
17+
implicit_reexport = False
18+
no_implicit_optional = True
19+
pretty = True
20+
show_column_numbers = True
21+
show_error_codes = True
22+
show_error_code_links = True
23+
strict_bytes = True
24+
strict_equality = True
25+
warn_incomplete_stub = True
26+
warn_redundant_casts = True
27+
warn_return_any = True
28+
warn_unreachable = True
1429
warn_unused_ignores = True
15-
16-
17-
[mypy-pytest]
18-
ignore_missing_imports = true

.pre-commit-config.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,15 @@ repos:
6161
- id: check-github-actions
6262

6363
- repo: https://github.com/pre-commit/mirrors-mypy.git
64-
rev: v1.14.1
64+
rev: v1.16.0
6565
hooks:
6666
- id: mypy
6767
alias: mypy-py313
6868
name: MyPy, for Python 3.13
6969
additional_dependencies:
7070
- frozenlist # runtime dependency
7171
- lxml # dep of `--txt-report`, `--cobertura-xml-report` & `--html-report`
72+
- pytest
7273
args:
7374
- --python-version=3.13
7475
- --any-exprs-report=.tox/.tmp/.test-results/mypy--py-3.13
@@ -85,6 +86,7 @@ repos:
8586
additional_dependencies:
8687
- frozenlist # runtime dependency
8788
- lxml # dep of `--txt-report`, `--cobertura-xml-report` & `--html-report`
89+
- pytest
8890
args:
8991
- --python-version=3.11
9092
- --any-exprs-report=.tox/.tmp/.test-results/mypy--py-3.11
@@ -101,6 +103,7 @@ repos:
101103
additional_dependencies:
102104
- frozenlist # runtime dependency
103105
- lxml # dep of `--txt-report`, `--cobertura-xml-report` & `--html-report`
106+
- pytest
104107
args:
105108
- --python-version=3.9
106109
- --any-exprs-report=.tox/.tmp/.test-results/mypy--py-3.9

tests/test_signals.py

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
import re
2+
import sys
23
from unittest import mock
34

45
import pytest
56

67
from aiosignal import Signal
78

9+
if sys.version_info >= (3, 11):
10+
from typing import Unpack
11+
else:
12+
from typing_extensions import Unpack
13+
814

915
class Owner:
1016
def __repr__(self) -> str:
@@ -16,10 +22,20 @@ def owner() -> Owner:
1622
return Owner()
1723

1824

25+
async def test_signal_positional_args(owner: Owner) -> None:
26+
async def callback(a: int, b: str) -> None:
27+
return
28+
29+
signal = Signal[int, str](owner)
30+
signal.append(callback)
31+
signal.freeze()
32+
await signal.send(42, "foo")
33+
34+
1935
async def test_add_signal_handler_not_a_callable(owner: Owner) -> None:
2036
callback = True
2137
signal = Signal(owner)
22-
signal.append(callback)
38+
signal.append(callback) # type: ignore[arg-type]
2339
signal.freeze()
2440
with pytest.raises(TypeError):
2541
await signal.send()
@@ -31,7 +47,7 @@ async def test_function_signal_dispatch_kwargs(owner: Owner) -> None:
3147

3248
callback_mock = mock.Mock()
3349

34-
async def callback(**kwargs):
50+
async def callback(**kwargs: object) -> None:
3551
callback_mock(**kwargs)
3652

3753
signal.append(callback)
@@ -42,20 +58,19 @@ async def callback(**kwargs):
4258

4359

4460
async def test_function_signal_dispatch_args_kwargs(owner: Owner) -> None:
45-
signal = Signal(owner)
46-
args = {"a", "b"}
61+
signal = Signal[Unpack[tuple[str, ...]]](owner)
4762
kwargs = {"foo": 1, "bar": 2}
4863

4964
callback_mock = mock.Mock()
5065

51-
async def callback(*args, **kwargs):
66+
async def callback(*args: str, **kwargs: object) -> None:
5267
callback_mock(*args, **kwargs)
5368

5469
signal.append(callback)
5570
signal.freeze()
5671

57-
await signal.send(*args, **kwargs)
58-
callback_mock.assert_called_once_with(*args, **kwargs)
72+
await signal.send("a", "b", **kwargs)
73+
callback_mock.assert_called_once_with("a", "b", **kwargs)
5974

6075

6176
async def test_non_coroutine(owner: Owner) -> None:
@@ -130,7 +145,7 @@ async def test_cannot_send_non_frozen_signal(owner: Owner) -> None:
130145

131146
callback_mock = mock.Mock()
132147

133-
async def callback(**kwargs):
148+
async def callback(**kwargs: object) -> None:
134149
callback_mock(**kwargs) # pragma: no cover # mustn't be called
135150

136151
signal.append(callback)

0 commit comments

Comments
 (0)