Skip to content

Commit cc283cf

Browse files
authored
Merge pull request #7142 from bluetech/typing
Add more type annotations
2 parents e7c26a9 + 2b05faf commit cc283cf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+2701
-1532
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ repos:
1818
args: [--remove]
1919
- id: check-yaml
2020
- id: debug-statements
21-
exclude: _pytest/debugging.py
21+
exclude: _pytest/(debugging|hookspec).py
2222
language_version: python3
2323
- repo: https://gitlab.com/pycqa/flake8
2424
rev: 3.8.2

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ formats = sdist.tgz,bdist_wheel
9191

9292
[mypy]
9393
mypy_path = src
94+
check_untyped_defs = True
9495
ignore_missing_imports = True
9596
no_implicit_optional = True
9697
show_error_codes = True

src/_pytest/_code/code.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from typing import Generic
1616
from typing import Iterable
1717
from typing import List
18+
from typing import Mapping
1819
from typing import Optional
1920
from typing import Pattern
2021
from typing import Sequence
@@ -46,7 +47,7 @@
4647
from typing_extensions import Literal
4748
from weakref import ReferenceType
4849

49-
_TracebackStyle = Literal["long", "short", "line", "no", "native", "value"]
50+
_TracebackStyle = Literal["long", "short", "line", "no", "native", "value", "auto"]
5051

5152

5253
class Code:
@@ -728,7 +729,7 @@ def get_exconly(
728729
failindent = indentstr
729730
return lines
730731

731-
def repr_locals(self, locals: Dict[str, object]) -> Optional["ReprLocals"]:
732+
def repr_locals(self, locals: Mapping[str, object]) -> Optional["ReprLocals"]:
732733
if self.showlocals:
733734
lines = []
734735
keys = [loc for loc in locals if loc[0] != "@"]

src/_pytest/_io/saferepr.py

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import pprint
22
import reprlib
33
from typing import Any
4+
from typing import Dict
5+
from typing import IO
6+
from typing import Optional
47

58

6-
def _try_repr_or_str(obj):
9+
def _try_repr_or_str(obj: object) -> str:
710
try:
811
return repr(obj)
912
except (KeyboardInterrupt, SystemExit):
@@ -12,7 +15,7 @@ def _try_repr_or_str(obj):
1215
return '{}("{}")'.format(type(obj).__name__, obj)
1316

1417

15-
def _format_repr_exception(exc: BaseException, obj: Any) -> str:
18+
def _format_repr_exception(exc: BaseException, obj: object) -> str:
1619
try:
1720
exc_info = _try_repr_or_str(exc)
1821
except (KeyboardInterrupt, SystemExit):
@@ -42,7 +45,7 @@ def __init__(self, maxsize: int) -> None:
4245
self.maxstring = maxsize
4346
self.maxsize = maxsize
4447

45-
def repr(self, x: Any) -> str:
48+
def repr(self, x: object) -> str:
4649
try:
4750
s = super().repr(x)
4851
except (KeyboardInterrupt, SystemExit):
@@ -51,7 +54,7 @@ def repr(self, x: Any) -> str:
5154
s = _format_repr_exception(exc, x)
5255
return _ellipsize(s, self.maxsize)
5356

54-
def repr_instance(self, x: Any, level: int) -> str:
57+
def repr_instance(self, x: object, level: int) -> str:
5558
try:
5659
s = repr(x)
5760
except (KeyboardInterrupt, SystemExit):
@@ -61,7 +64,7 @@ def repr_instance(self, x: Any, level: int) -> str:
6164
return _ellipsize(s, self.maxsize)
6265

6366

64-
def safeformat(obj: Any) -> str:
67+
def safeformat(obj: object) -> str:
6568
"""return a pretty printed string for the given object.
6669
Failing __repr__ functions of user instances will be represented
6770
with a short exception info.
@@ -72,7 +75,7 @@ def safeformat(obj: Any) -> str:
7275
return _format_repr_exception(exc, obj)
7376

7477

75-
def saferepr(obj: Any, maxsize: int = 240) -> str:
78+
def saferepr(obj: object, maxsize: int = 240) -> str:
7679
"""return a size-limited safe repr-string for the given object.
7780
Failing __repr__ functions of user instances will be represented
7881
with a short exception info and 'saferepr' generally takes
@@ -85,19 +88,39 @@ def saferepr(obj: Any, maxsize: int = 240) -> str:
8588
class AlwaysDispatchingPrettyPrinter(pprint.PrettyPrinter):
8689
"""PrettyPrinter that always dispatches (regardless of width)."""
8790

88-
def _format(self, object, stream, indent, allowance, context, level):
89-
p = self._dispatch.get(type(object).__repr__, None)
91+
def _format(
92+
self,
93+
object: object,
94+
stream: IO[str],
95+
indent: int,
96+
allowance: int,
97+
context: Dict[int, Any],
98+
level: int,
99+
) -> None:
100+
# Type ignored because _dispatch is private.
101+
p = self._dispatch.get(type(object).__repr__, None) # type: ignore[attr-defined] # noqa: F821
90102

91103
objid = id(object)
92104
if objid in context or p is None:
93-
return super()._format(object, stream, indent, allowance, context, level)
105+
# Type ignored because _format is private.
106+
super()._format( # type: ignore[misc] # noqa: F821
107+
object, stream, indent, allowance, context, level,
108+
)
109+
return
94110

95111
context[objid] = 1
96112
p(self, object, stream, indent, allowance, context, level + 1)
97113
del context[objid]
98114

99115

100-
def _pformat_dispatch(object, indent=1, width=80, depth=None, *, compact=False):
116+
def _pformat_dispatch(
117+
object: object,
118+
indent: int = 1,
119+
width: int = 80,
120+
depth: Optional[int] = None,
121+
*,
122+
compact: bool = False
123+
) -> str:
101124
return AlwaysDispatchingPrettyPrinter(
102125
indent=indent, width=width, depth=depth, compact=compact
103126
).pformat(object)

src/_pytest/assertion/__init__.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44
import sys
55
from typing import Any
6+
from typing import Generator
67
from typing import List
78
from typing import Optional
89

@@ -13,12 +14,14 @@
1314
from _pytest.compat import TYPE_CHECKING
1415
from _pytest.config import Config
1516
from _pytest.config import hookimpl
17+
from _pytest.config.argparsing import Parser
18+
from _pytest.nodes import Item
1619

1720
if TYPE_CHECKING:
1821
from _pytest.main import Session
1922

2023

21-
def pytest_addoption(parser):
24+
def pytest_addoption(parser: Parser) -> None:
2225
group = parser.getgroup("debugconfig")
2326
group.addoption(
2427
"--assert",
@@ -43,7 +46,7 @@ def pytest_addoption(parser):
4346
)
4447

4548

46-
def register_assert_rewrite(*names) -> None:
49+
def register_assert_rewrite(*names: str) -> None:
4750
"""Register one or more module names to be rewritten on import.
4851
4952
This function will make sure that this module or all modules inside
@@ -72,27 +75,27 @@ def register_assert_rewrite(*names) -> None:
7275
class DummyRewriteHook:
7376
"""A no-op import hook for when rewriting is disabled."""
7477

75-
def mark_rewrite(self, *names):
78+
def mark_rewrite(self, *names: str) -> None:
7679
pass
7780

7881

7982
class AssertionState:
8083
"""State for the assertion plugin."""
8184

82-
def __init__(self, config, mode):
85+
def __init__(self, config: Config, mode) -> None:
8386
self.mode = mode
8487
self.trace = config.trace.root.get("assertion")
8588
self.hook = None # type: Optional[rewrite.AssertionRewritingHook]
8689

8790

88-
def install_importhook(config):
91+
def install_importhook(config: Config) -> rewrite.AssertionRewritingHook:
8992
"""Try to install the rewrite hook, raise SystemError if it fails."""
9093
config._store[assertstate_key] = AssertionState(config, "rewrite")
9194
config._store[assertstate_key].hook = hook = rewrite.AssertionRewritingHook(config)
9295
sys.meta_path.insert(0, hook)
9396
config._store[assertstate_key].trace("installed rewrite import hook")
9497

95-
def undo():
98+
def undo() -> None:
9699
hook = config._store[assertstate_key].hook
97100
if hook is not None and hook in sys.meta_path:
98101
sys.meta_path.remove(hook)
@@ -112,7 +115,7 @@ def pytest_collection(session: "Session") -> None:
112115

113116

114117
@hookimpl(tryfirst=True, hookwrapper=True)
115-
def pytest_runtest_protocol(item):
118+
def pytest_runtest_protocol(item: Item) -> Generator[None, None, None]:
116119
"""Setup the pytest_assertrepr_compare and pytest_assertion_pass hooks
117120
118121
The rewrite module will use util._reprcompare if
@@ -121,8 +124,7 @@ def pytest_runtest_protocol(item):
121124
comparison for the test.
122125
"""
123126

124-
def callbinrepr(op, left, right):
125-
# type: (str, object, object) -> Optional[str]
127+
def callbinrepr(op, left: object, right: object) -> Optional[str]:
126128
"""Call the pytest_assertrepr_compare hook and prepare the result
127129
128130
This uses the first result from the hook and then ensures the
@@ -155,7 +157,7 @@ def callbinrepr(op, left, right):
155157

156158
if item.ihook.pytest_assertion_pass.get_hookimpls():
157159

158-
def call_assertion_pass_hook(lineno, orig, expl):
160+
def call_assertion_pass_hook(lineno: int, orig: str, expl: str) -> None:
159161
item.ihook.pytest_assertion_pass(
160162
item=item, lineno=lineno, orig=orig, expl=expl
161163
)
@@ -167,7 +169,7 @@ def call_assertion_pass_hook(lineno, orig, expl):
167169
util._reprcompare, util._assertion_pass = saved_assert_hooks
168170

169171

170-
def pytest_sessionfinish(session):
172+
def pytest_sessionfinish(session: "Session") -> None:
171173
assertstate = session.config._store.get(assertstate_key, None)
172174
if assertstate:
173175
if assertstate.hook is not None:

0 commit comments

Comments
 (0)