Skip to content

Commit 0e7970a

Browse files
authored
Merge pull request #340 from bluetech/type-annotations
Add type annotations
2 parents add0fb9 + 9ee5a1e commit 0e7970a

20 files changed

+650
-311
lines changed

.coveragerc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,15 @@ source = pluggy/
1212
*/lib/python*/site-packages/pluggy/
1313
*/pypy*/site-packages/pluggy/
1414
*\Lib\site-packages\pluggy\
15+
16+
[report]
17+
exclude_lines =
18+
# Have to re-enable the standard pragma
19+
pragma: no cover
20+
21+
if TYPE_CHECKING:
22+
23+
if __name__ == .__main__.:
24+
25+
# Ignore coverage on lines solely with `...`
26+
^\s*\.\.\.\s*$

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ htmlcov/
3939
.coverage
4040
.coverage.*
4141
.cache
42+
.mypy_cache/
4243
nosetests.xml
4344
coverage.xml
4445
*,cover

.pre-commit-config.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ repos:
1515
- id: trailing-whitespace
1616
- id: end-of-file-fixer
1717
- id: flake8
18+
additional_dependencies: [flake8-typing-imports]
19+
- repo: https://github.com/pre-commit/mirrors-mypy
20+
rev: v0.931
21+
hooks:
22+
- id: mypy
23+
files: ^(src/|testing/)
24+
args: []
25+
additional_dependencies: [pytest]
1826
- repo: local
1927
hooks:
2028
- id: rst

docs/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
# (source start file, name, description, authors, manual section).
6060
man_pages = [(master_doc, "pluggy", "pluggy Documentation", [author], 1)]
6161

62+
autodoc_typehints = "none"
6263

6364
# -- Options for Texinfo output -------------------------------------------
6465

pyproject.toml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,25 @@ template = "changelog/_template.rst"
4545
directory = "trivial"
4646
name = "Trivial/Internal Changes"
4747
showcontent = true
48+
49+
[tool.mypy]
50+
mypy_path = "src"
51+
check_untyped_defs = true
52+
# Hopefully we can set this someday!
53+
# disallow_any_expr = true
54+
disallow_any_generics = true
55+
disallow_any_unimported = true
56+
disallow_subclassing_any = true
57+
disallow_untyped_calls = true
58+
disallow_untyped_decorators = true
59+
ignore_missing_imports = true
60+
implicit_reexport = false
61+
no_implicit_optional = true
62+
show_error_codes = true
63+
strict_equality = true
64+
strict_optional = true
65+
warn_redundant_casts = true
66+
warn_return_any = true
67+
warn_unreachable = true
68+
warn_unused_configs = true
69+
warn_unused_ignores = true

src/pluggy/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@
1414
]
1515

1616
from ._manager import PluginManager, PluginValidationError
17-
from ._callers import HookCallError
17+
from ._result import HookCallError
1818
from ._hooks import HookspecMarker, HookimplMarker

src/pluggy/_callers.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,28 @@
22
Call loop machinery
33
"""
44
import sys
5+
from typing import cast, Generator, List, Mapping, Sequence, Union
6+
from typing import TYPE_CHECKING
57

68
from ._result import HookCallError, _Result, _raise_wrapfail
79

10+
if TYPE_CHECKING:
11+
from ._hooks import HookImpl
812

9-
def _multicall(hook_name, hook_impls, caller_kwargs, firstresult):
13+
14+
def _multicall(
15+
hook_name: str,
16+
hook_impls: Sequence["HookImpl"],
17+
caller_kwargs: Mapping[str, object],
18+
firstresult: bool,
19+
) -> Union[object, List[object]]:
1020
"""Execute a call into multiple python functions/methods and return the
1121
result(s).
1222
1323
``caller_kwargs`` comes from _HookCaller.__call__().
1424
"""
1525
__tracebackhide__ = True
16-
results = []
26+
results: List[object] = []
1727
excinfo = None
1828
try: # run impl and wrapper setup functions in a loop
1929
teardowns = []
@@ -30,7 +40,10 @@ def _multicall(hook_name, hook_impls, caller_kwargs, firstresult):
3040

3141
if hook_impl.hookwrapper:
3242
try:
33-
gen = hook_impl.function(*args)
43+
# If this cast is not valid, a type error is raised below,
44+
# which is the desired response.
45+
res = hook_impl.function(*args)
46+
gen = cast(Generator[None, _Result[object], None], res)
3447
next(gen) # first yield
3548
teardowns.append(gen)
3649
except StopIteration:
@@ -42,10 +55,16 @@ def _multicall(hook_name, hook_impls, caller_kwargs, firstresult):
4255
if firstresult: # halt further impl calls
4356
break
4457
except BaseException:
45-
excinfo = sys.exc_info()
58+
_excinfo = sys.exc_info()
59+
assert _excinfo[0] is not None
60+
assert _excinfo[1] is not None
61+
assert _excinfo[2] is not None
62+
excinfo = (_excinfo[0], _excinfo[1], _excinfo[2])
4663
finally:
4764
if firstresult: # first result hooks return a single value
48-
outcome = _Result(results[0] if results else None, excinfo)
65+
outcome: _Result[Union[object, List[object]]] = _Result(
66+
results[0] if results else None, excinfo
67+
)
4968
else:
5069
outcome = _Result(results, excinfo)
5170

0 commit comments

Comments
 (0)