Skip to content

Commit d1b6672

Browse files
committed
Add typing to test suite
Signed-off-by: Bernát Gábor <bgabor8@bloomberg.net>
1 parent 9ef0d81 commit d1b6672

Some content is hidden

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

53 files changed

+292
-182
lines changed

Diff for: .dockerignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.tox*
2+
.*_cache
3+
*.egg-info
4+
Dockerfile
5+
build
6+
dist

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@ credentials.json
3333
pip-wheel-metadata
3434
.DS_Store
3535
.coverage.*
36+
Dockerfile

Diff for: pyproject.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ build-backend = "setuptools.build_meta"
66
line-length = 120
77

88
[tool.isort]
9+
line_length = 120
910
profile = "black"
10-
known_first_party = ["tox_ini_fmt"]
11+
known_first_party = ["tox", "tests"]
1112

1213
[tool.setuptools_scm]
1314
write_to = "src/tox/version.py"

Diff for: setup.cfg

+10-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ testing =
7171
wheel>=0.30
7272

7373
[options.package_data]
74-
tox_ini_fmt = py.typed
74+
tox = py.typed
7575

7676
[options.packages.find]
7777
where = src
@@ -113,5 +113,14 @@ ignore_missing_imports = True
113113
[mypy-pluggy.*]
114114
ignore_missing_imports = True
115115

116+
[mypy-psutil.*]
117+
ignore_missing_imports = True
118+
119+
[mypy-setuptools.*]
120+
ignore_missing_imports = True
121+
116122
[mypy-virtualenv.*]
117123
ignore_missing_imports = True
124+
125+
[mypy-wheel.*]
126+
ignore_missing_imports = True

Diff for: src/tox/config/cli/parser.py

+2-20
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,9 @@
66
import logging
77
import os
88
import sys
9-
from argparse import (
10-
SUPPRESS,
11-
Action,
12-
ArgumentDefaultsHelpFormatter,
13-
ArgumentParser,
14-
Namespace,
15-
_SubParsersAction,
16-
)
9+
from argparse import SUPPRESS, Action, ArgumentDefaultsHelpFormatter, ArgumentParser, Namespace, _SubParsersAction
1710
from itertools import chain
18-
from typing import (
19-
Any,
20-
Callable,
21-
Dict,
22-
List,
23-
Optional,
24-
Sequence,
25-
Tuple,
26-
Type,
27-
TypeVar,
28-
cast,
29-
)
11+
from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Type, TypeVar, cast
3012

3113
from tox.config.source.ini.convert import StrConvert
3214
from tox.plugin import NAME

Diff for: src/tox/config/sets.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -137,22 +137,26 @@ def add_config(
137137
desc: str,
138138
post_process: Optional[Callable[[V, "Config"], V]] = None,
139139
overwrite: bool = False,
140-
) -> None:
140+
) -> ConfigDynamicDefinition[V]:
141141
"""
142142
Add configuration value.
143143
"""
144144
keys_ = self._make_keys(keys)
145145
for key in keys_:
146146
if key in self._defined and overwrite is False:
147-
# already added
148-
return
147+
defined = self._defined[key]
148+
if isinstance(defined, ConfigDynamicDefinition):
149+
return defined
150+
raise TypeError(f"{keys} already defined with differing type {type(defined).__name__}")
149151
definition = ConfigDynamicDefinition(keys_, of_type, default, desc, post_process)
150152
self._add_conf(keys_, definition)
153+
return definition
151154

152-
def add_constant(self, keys: Sequence[str], desc: str, value: V) -> None:
155+
def add_constant(self, keys: Sequence[str], desc: str, value: V) -> ConfigConstantDefinition[V]:
153156
keys_ = self._make_keys(keys)
154157
definition = ConfigConstantDefinition(keys_, desc, value)
155158
self._add_conf(keys, definition)
159+
return definition
156160

157161
def make_package_conf(self) -> None:
158162
self._raw.make_package_conf()

Diff for: src/tox/config/source/ini/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,6 @@ def __repr__(self) -> str:
222222
__all__ = (
223223
"ToxIni",
224224
"IniLoader",
225+
"filter_for_env",
226+
"find_envs",
225227
)

Diff for: src/tox/execute/local_sub_process/read_via_thread_unix.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ def _read_stream(self) -> None:
2727
def _drain_stream(self) -> bytes:
2828
result = bytearray() # on closed file read returns empty
2929
while True:
30-
last_result = os.read(self.file_no, 1)
30+
try:
31+
last_result = os.read(self.file_no, 1)
32+
except OSError: # ignore failing to read the pipe - already closed
33+
break
3134
if last_result:
3235
result.append(last_result[0])
3336
else:

Diff for: src/tox/pytest.py

+28-5
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
import textwrap
88
from contextlib import contextmanager
99
from pathlib import Path
10-
from typing import Any, Callable, Dict, Iterator, List, Optional, Sequence
10+
from typing import TYPE_CHECKING, Any, Callable, Dict, Iterator, List, Optional, Sequence
1111

1212
import pytest
13-
from _pytest.capture import CaptureFixture
13+
from _pytest.capture import CaptureFixture as _CaptureFixture
14+
from _pytest.logging import LogCaptureFixture
1415
from _pytest.monkeypatch import MonkeyPatch
1516

1617
import tox.run
@@ -23,6 +24,11 @@
2324
from tox.session.cmd.run.parallel import ENV_VAR_KEY
2425
from tox.session.state import State
2526

27+
if TYPE_CHECKING:
28+
CaptureFixture = _CaptureFixture[str]
29+
else:
30+
CaptureFixture = _CaptureFixture
31+
2632

2733
@pytest.fixture(autouse=True)
2834
def ensure_logging_framework_not_altered() -> Iterator[None]:
@@ -77,7 +83,7 @@ def __init__(
7783
self,
7884
files: Dict[str, Any],
7985
path: Path,
80-
capsys: CaptureFixture[str],
86+
capsys: CaptureFixture,
8187
monkeypatch: MonkeyPatch,
8288
) -> None:
8389
self.path = path
@@ -156,7 +162,13 @@ def __init__(self, cmd: Sequence[str], cwd: Path, code: int, out: str, err: str,
156162
self.code: int = code
157163
self.out: str = out
158164
self.err: str = err
159-
self.state: Optional[State] = state
165+
self._state: Optional[State] = state
166+
167+
@property
168+
def state(self) -> State:
169+
if self._state is None:
170+
raise RuntimeError("no state")
171+
return self._state
160172

161173
@property
162174
def success(self) -> bool:
@@ -188,7 +200,7 @@ def shell_cmd(self) -> str:
188200

189201

190202
@pytest.fixture(name="tox_project")
191-
def init_fixture(tmp_path: Path, capsys: CaptureFixture[str], monkeypatch: MonkeyPatch) -> ToxProjectCreator:
203+
def init_fixture(tmp_path: Path, capsys: CaptureFixture, monkeypatch: MonkeyPatch) -> ToxProjectCreator:
192204
def _init(files: Dict[str, Any]) -> ToxProject:
193205
"""create tox projects"""
194206
return ToxProject(files, tmp_path, capsys, monkeypatch)
@@ -201,3 +213,14 @@ def empty_project(tox_project: ToxProjectCreator, monkeypatch: MonkeyPatch) -> T
201213
project = tox_project({"tox.ini": ""})
202214
monkeypatch.chdir(project.path)
203215
return project
216+
217+
218+
__all__ = (
219+
"CaptureFixture",
220+
"LogCaptureFixture",
221+
"MonkeyPatch",
222+
"ToxRunOutcome",
223+
"ToxProject",
224+
"ToxProjectCreator",
225+
"check_os_environ",
226+
)

Diff for: src/tox/session/cmd/show_config.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def tox_add_option(parser: ToxParser) -> None:
1919
env_list_flag(our)
2020

2121

22-
def display_config(state: State) -> None:
22+
def display_config(state: State) -> int:
2323
first = True
2424
if not state.options.env:
2525
print("[tox]")
@@ -33,6 +33,7 @@ def display_config(state: State) -> None:
3333
print(f"[testenv:{name}]")
3434
print(f"type = {type(tox_env).__name__}")
3535
print_conf(tox_env.conf)
36+
return 0
3637

3738

3839
def print_conf(conf: ConfigSet) -> None:

Diff for: src/tox/tox_env/python/api.py

+1-11
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,7 @@
44
import sys
55
from abc import ABC, abstractmethod
66
from pathlib import Path
7-
from typing import (
8-
Any,
9-
Dict,
10-
List,
11-
NamedTuple,
12-
NoReturn,
13-
Optional,
14-
Sequence,
15-
Union,
16-
cast,
17-
)
7+
from typing import Any, Dict, List, NamedTuple, NoReturn, Optional, Sequence, Union, cast
188

199
from packaging.requirements import Requirement
2010
from virtualenv.discovery.py_spec import PythonSpec

Diff for: src/tox/tox_env/python/virtual_env/package/api.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@
1717
from ..api import VirtualEnv
1818

1919
try:
20-
from importlib.metadata import ( # type: ignore[attr-defined]
21-
Distribution,
22-
PathDistribution,
23-
)
20+
from importlib.metadata import Distribution, PathDistribution # type: ignore[attr-defined]
2421
except ImportError:
2522
from importlib_metadata import Distribution, PathDistribution # noqa
2623

Diff for: tests/__init__.py

Whitespace-only changes.

Diff for: tests/conftest.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import sys
2+
from typing import Callable
23

34
import pytest
45

56
pytest_plugins = "tox.pytest"
67

78

89
@pytest.fixture(scope="session")
9-
def value_error():
10-
def _fmt(msg):
10+
def value_error() -> Callable[[str], str]:
11+
def _fmt(msg: str) -> str:
1112
return f'ValueError("{msg}"{"," if sys.version_info < (3, 7) else ""})'
1213

1314
return _fmt

Diff for: tests/integration/__init__.py

Whitespace-only changes.

Diff for: tests/integration/tox_env/__init__.py

Whitespace-only changes.

Diff for: tests/integration/tox_env/virtual_env/__init__.py

Whitespace-only changes.

Diff for: tests/integration/tox_env/virtual_env/test_int_setuptools.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from tox.pytest import ToxProjectCreator
44

55

6-
def test_setuptools_package_py_project(tox_project: ToxProjectCreator):
6+
def test_setuptools_package_py_project(tox_project: ToxProjectCreator) -> None:
77
project = tox_project(
88
{
99
"tox.ini": """

Diff for: tests/unit/__init__.py

Whitespace-only changes.

Diff for: tests/unit/config/__init__.py

Whitespace-only changes.

Diff for: tests/unit/config/cli/__init__.py

Whitespace-only changes.

Diff for: tests/unit/config/cli/conftest.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1+
from typing import Callable, Dict
2+
13
import pytest
24

35
from tox.session.cmd.list_env import list_env
46
from tox.session.cmd.run.parallel import run_parallel
57
from tox.session.cmd.run.sequential import run_sequential
68
from tox.session.cmd.show_config import display_config
9+
from tox.session.state import State
710

811

912
@pytest.fixture()
10-
def core_handlers():
13+
def core_handlers() -> Dict[str, Callable[[State], int]]:
1114
return {
1215
"config": display_config,
1316
"c": display_config,

Diff for: tests/unit/config/cli/test_cli_env_var.py

+14-6
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
1+
from typing import Callable, Dict
2+
13
import pytest
24

35
from tox.config.cli.parse import get_options
46
from tox.config.override import Override
7+
from tox.pytest import CaptureFixture, LogCaptureFixture, MonkeyPatch
8+
from tox.session.state import State
59

610

7-
def test_verbose(monkeypatch):
11+
def test_verbose(monkeypatch: MonkeyPatch) -> None:
812
parsed, _, __ = get_options("-v", "-v")
913
assert parsed.verbosity == 4
1014

1115

12-
def test_verbose_compound(monkeypatch):
16+
def test_verbose_compound(monkeypatch: MonkeyPatch) -> None:
1317
parsed, _, __ = get_options("-vv")
1418
assert parsed.verbosity == 4
1519

1620

17-
def test_verbose_no_test_skip_missing(monkeypatch):
21+
def test_verbose_no_test_skip_missing(monkeypatch: MonkeyPatch) -> None:
1822
parsed, _, __ = get_options("--notest", "-vv", "--skip-missing-interpreters", "false", "--runner", "virtualenv")
1923
assert vars(parsed) == {
2024
"colored": "no",
@@ -29,7 +33,9 @@ def test_verbose_no_test_skip_missing(monkeypatch):
2933
}
3034

3135

32-
def test_env_var_exhaustive_parallel_values(monkeypatch, core_handlers):
36+
def test_env_var_exhaustive_parallel_values(
37+
monkeypatch: MonkeyPatch, core_handlers: Dict[str, Callable[[State], int]]
38+
) -> None:
3339
monkeypatch.setenv("TOX_COMMAND", "run-parallel")
3440
monkeypatch.setenv("TOX_VERBOSE", "5")
3541
monkeypatch.setenv("TOX_QUIET", "1")
@@ -60,7 +66,7 @@ def test_env_var_exhaustive_parallel_values(monkeypatch, core_handlers):
6066
assert handlers == core_handlers
6167

6268

63-
def test_ini_help(monkeypatch, capsys):
69+
def test_ini_help(monkeypatch: MonkeyPatch, capsys: CaptureFixture) -> None:
6470
monkeypatch.setenv("TOX_VERBOSE", "5")
6571
monkeypatch.setenv("TOX_QUIET", "1")
6672
with pytest.raises(SystemExit) as context:
@@ -72,7 +78,9 @@ def test_ini_help(monkeypatch, capsys):
7278
assert "from env var TOX_QUIET" in out
7379

7480

75-
def test_bad_env_var(monkeypatch, capsys, caplog, value_error):
81+
def test_bad_env_var(
82+
monkeypatch: MonkeyPatch, capsys: CaptureFixture, caplog: LogCaptureFixture, value_error: Callable[[str], str]
83+
) -> None:
7684
monkeypatch.setenv("TOX_VERBOSE", "should-be-number")
7785
monkeypatch.setenv("TOX_QUIET", "1.00")
7886
parsed, _, __ = get_options()

0 commit comments

Comments
 (0)