Skip to content

WIP: An assortment of type annotations #6717

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/_pytest/assertion/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
from _pytest.assertion import util
from _pytest.compat import TYPE_CHECKING
from _pytest.config import hookimpl
from _pytest.config.argparsing import Parser

if TYPE_CHECKING:
from _pytest.main import Session


def pytest_addoption(parser):
def pytest_addoption(parser: Parser) -> None:
group = parser.getgroup("debugconfig")
group.addoption(
"--assert",
Expand Down Expand Up @@ -162,7 +163,7 @@ def call_assertion_pass_hook(lineno, orig, expl):
util._reprcompare, util._assertion_pass = saved_assert_hooks


def pytest_sessionfinish(session):
def pytest_sessionfinish(session: "Session") -> None:
assertstate = getattr(session.config, "_assertstate", None)
if assertstate:
if assertstate.hook is not None:
Expand Down
18 changes: 12 additions & 6 deletions src/_pytest/cacheprovider.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import os
from collections import OrderedDict
from typing import List
from typing import Optional
from typing import Union

import attr
import py
Expand All @@ -19,6 +21,8 @@
from _pytest import nodes
from _pytest._io import TerminalWriter
from _pytest.config import Config
from _pytest.config import ExitCode
from _pytest.config.argparsing import Parser
from _pytest.main import Session

README_CONTENT = """\
Expand Down Expand Up @@ -264,7 +268,7 @@ def pytest_collection_modifyitems(self, session, config, items):
else:
self._report_status += "not deselecting items."

def pytest_sessionfinish(self, session):
def pytest_sessionfinish(self, session: Session) -> None:
config = self.config
if config.getoption("cacheshow") or hasattr(config, "slaveinput"):
return
Expand Down Expand Up @@ -306,15 +310,15 @@ def pytest_collection_modifyitems(
def _get_increasing_order(self, items):
return sorted(items, key=lambda item: item.fspath.mtime(), reverse=True)

def pytest_sessionfinish(self, session):
def pytest_sessionfinish(self, session: Session) -> None:
config = self.config
if config.getoption("cacheshow") or hasattr(config, "slaveinput"):
return

config.cache.set("cache/nodeids", self.cached_nodeids)


def pytest_addoption(parser):
def pytest_addoption(parser: Parser) -> None:
group = parser.getgroup("general")
group.addoption(
"--lf",
Expand Down Expand Up @@ -372,16 +376,18 @@ def pytest_addoption(parser):
)


def pytest_cmdline_main(config):
def pytest_cmdline_main(config: Config) -> Optional[Union[int, ExitCode]]:
if config.option.cacheshow:
from _pytest.main import wrap_session

return wrap_session(config, cacheshow)
return None


@pytest.hookimpl(tryfirst=True)
def pytest_configure(config):
config.cache = Cache.for_config(config)
def pytest_configure(config: Config) -> None:
# Type ignored: pending mechanism to store typed objects scoped to config.
config.cache = Cache.for_config(config) # type: ignore # noqa: F821
config.pluginmanager.register(LFPlugin(config), "lfplugin")
config.pluginmanager.register(NFPlugin(config), "nfplugin")

Expand Down
6 changes: 3 additions & 3 deletions src/_pytest/capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
from _pytest.compat import CaptureAndPassthroughIO
from _pytest.compat import CaptureIO
from _pytest.config import Config
from _pytest.fixtures import FixtureRequest
from _pytest.config.argparsing import Parser

patchsysdict = {0: "stdin", 1: "stdout", 2: "stderr"}


def pytest_addoption(parser):
def pytest_addoption(parser: Parser) -> None:
group = parser.getgroup("general")
group._addoption(
"--capture",
Expand Down Expand Up @@ -150,7 +150,7 @@ def read_global_capture(self):

@contextlib.contextmanager
def _capturing_for_request(
self, request: FixtureRequest
self, request
) -> Generator["CaptureFixture", None, None]:
if self._capture_fixture:
other_name = next(
Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ def _bytes_to_ascii(val: bytes) -> str:
return val.decode("ascii", "backslashreplace")


def ascii_escaped(val: Union[bytes, str]):
def ascii_escaped(val: Union[bytes, str]) -> str:
"""If val is pure ascii, returns it as a str(). Otherwise, escapes
bytes objects into a sequence of escaped bytes:

Expand Down
37 changes: 22 additions & 15 deletions src/_pytest/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ class PytestPluginManager(PluginManager):
* ``conftest.py`` loading during start-up;
"""

def __init__(self):
def __init__(self) -> None:
import _pytest.assertion

super().__init__("pytest")
Expand Down Expand Up @@ -362,7 +362,7 @@ def parse_hookspec_opts(self, module_or_class, name):
}
return opts

def register(self, plugin, name=None):
def register(self, plugin: _PluggyPlugin, name: Optional[str] = None):
if name in _pytest.deprecated.DEPRECATED_EXTERNAL_PLUGINS:
warnings.warn(
PytestConfigWarning(
Expand Down Expand Up @@ -391,7 +391,7 @@ def hasplugin(self, name):
"""Return True if the plugin with the given name is registered."""
return bool(self.get_plugin(name))

def pytest_configure(self, config):
def pytest_configure(self, config: "Config") -> None:
# XXX now that the pluginmanager exposes hookimpl(tryfirst...)
# we should remove tryfirst/trylast as markers
config.addinivalue_line(
Expand Down Expand Up @@ -522,7 +522,7 @@ def _importconftest(self, conftestpath):
#
#

def consider_preparse(self, args, *, exclude_only=False):
def consider_preparse(self, args, *, exclude_only: bool = False) -> None:
i = 0
n = len(args)
while i < n:
Expand All @@ -543,7 +543,7 @@ def consider_preparse(self, args, *, exclude_only=False):
continue
self.consider_pluginarg(parg)

def consider_pluginarg(self, arg):
def consider_pluginarg(self, arg) -> None:
if arg.startswith("no:"):
name = arg[3:]
if name in essential_plugins:
Expand All @@ -568,21 +568,21 @@ def consider_pluginarg(self, arg):
del self._name2plugin["pytest_" + name]
self.import_plugin(arg, consider_entry_points=True)

def consider_conftest(self, conftestmodule):
def consider_conftest(self, conftestmodule) -> None:
self.register(conftestmodule, name=conftestmodule.__file__)

def consider_env(self):
def consider_env(self) -> None:
self._import_plugin_specs(os.environ.get("PYTEST_PLUGINS"))

def consider_module(self, mod):
def consider_module(self, mod: types.ModuleType) -> None:
self._import_plugin_specs(getattr(mod, "pytest_plugins", []))

def _import_plugin_specs(self, spec):
plugins = _get_plugin_specs_as_list(spec)
for import_spec in plugins:
self.import_plugin(import_spec)

def import_plugin(self, modname, consider_entry_points=False):
def import_plugin(self, modname: str, consider_entry_points: bool = False) -> None:
"""
Imports a plugin with ``modname``. If ``consider_entry_points`` is True, entry point
names are also considered to find a plugin.
Expand Down Expand Up @@ -766,7 +766,12 @@ class InvocationParams:
plugins = attr.ib()
dir = attr.ib(type=Path)

def __init__(self, pluginmanager, *, invocation_params=None) -> None:
def __init__(
self,
pluginmanager: PytestPluginManager,
*,
invocation_params: Optional[InvocationParams] = None
) -> None:
from .argparsing import Parser, FILE_OR_DIR

if invocation_params is None:
Expand Down Expand Up @@ -796,23 +801,23 @@ def __init__(self, pluginmanager, *, invocation_params=None) -> None:
)

@property
def invocation_dir(self):
def invocation_dir(self) -> py.path.local:
"""Backward compatibility"""
return py.path.local(str(self.invocation_params.dir))

def add_cleanup(self, func):
def add_cleanup(self, func) -> None:
""" Add a function to be called when the config object gets out of
use (usually coninciding with pytest_unconfigure)."""
self._cleanup.append(func)

def _do_configure(self):
def _do_configure(self) -> None:
assert not self._configured
self._configured = True
with warnings.catch_warnings():
warnings.simplefilter("default")
self.hook.pytest_configure.call_historic(kwargs=dict(config=self))

def _ensure_unconfigure(self):
def _ensure_unconfigure(self) -> None:
if self._configured:
self._configured = False
self.hook.pytest_unconfigure(config=self)
Expand All @@ -824,7 +829,9 @@ def _ensure_unconfigure(self):
def get_terminal_writer(self):
return self.pluginmanager.get_plugin("terminalreporter")._tw

def pytest_cmdline_parse(self, pluginmanager, args):
def pytest_cmdline_parse(
self, pluginmanager: PytestPluginManager, args: List[str]
) -> object:
try:
self.parse(args)
except UsageError:
Expand Down
11 changes: 7 additions & 4 deletions src/_pytest/debugging.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
import sys

from _pytest import outcomes
from _pytest.config import Config
from _pytest.config import hookimpl
from _pytest.config import PytestPluginManager
from _pytest.config.argparsing import Parser
from _pytest.config.exceptions import UsageError


Expand All @@ -19,7 +22,7 @@ def _validate_usepdb_cls(value):
return (modname, classname)


def pytest_addoption(parser):
def pytest_addoption(parser: Parser) -> None:
group = parser.getgroup("general")
group._addoption(
"--pdb",
Expand All @@ -43,7 +46,7 @@ def pytest_addoption(parser):
)


def pytest_configure(config):
def pytest_configure(config: Config) -> None:
import pdb

if config.getvalue("trace"):
Expand Down Expand Up @@ -73,8 +76,8 @@ def fin():
class pytestPDB:
""" Pseudo PDB that defers to the real pdb. """

_pluginmanager = None
_config = None
_pluginmanager = None # type: PytestPluginManager
_config = None # type: Config
_saved = [] # type: list
_recursive_debug = 0
_wrapped_pdb_cls = None
Expand Down
21 changes: 14 additions & 7 deletions src/_pytest/doctest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import warnings
from contextlib import contextmanager
from typing import Dict
from typing import Iterable
from typing import List
from typing import Optional
from typing import Sequence
Expand All @@ -23,6 +24,7 @@
from _pytest._io import TerminalWriter
from _pytest.compat import safe_getattr
from _pytest.compat import TYPE_CHECKING
from _pytest.config.argparsing import Parser
from _pytest.fixtures import FixtureRequest
from _pytest.outcomes import Skipped
from _pytest.python_api import approx
Expand Down Expand Up @@ -52,7 +54,7 @@
CHECKER_CLASS = None # type: Optional[Type[doctest.OutputChecker]]


def pytest_addoption(parser):
def pytest_addoption(parser: Parser) -> None:
parser.addini(
"doctest_optionflags",
"option flags for doctests",
Expand Down Expand Up @@ -102,19 +104,24 @@ def pytest_addoption(parser):
)


def pytest_unconfigure():
def pytest_unconfigure() -> None:
global RUNNER_CLASS

RUNNER_CLASS = None


def pytest_collect_file(path, parent):
def pytest_collect_file(
path: py.path.local, parent
) -> Optional[Union["DoctestModule", "DoctestTextfile"]]:
config = parent.config
if path.ext == ".py":
if config.option.doctestmodules and not _is_setup_py(config, path, parent):
return DoctestModule.from_parent(parent, fspath=path)
mod = DoctestModule.from_parent(parent, fspath=path) # type: DoctestModule
return mod
elif _is_doctest(config, path, parent):
return DoctestTextfile.from_parent(parent, fspath=path)
txt = DoctestTextfile.from_parent(parent, fspath=path) # type: DoctestTextfile
return txt
return None


def _is_setup_py(config, path, parent):
Expand Down Expand Up @@ -361,7 +368,7 @@ def _get_continue_on_failure(config):
class DoctestTextfile(pytest.Module):
obj = None

def collect(self):
def collect(self) -> Iterable[DoctestItem]:
import doctest

# inspired by doctest.testfile; ideally we would use it directly,
Expand Down Expand Up @@ -440,7 +447,7 @@ def _mock_aware_unwrap(obj, stop=None):


class DoctestModule(pytest.Module):
def collect(self):
def collect(self) -> Iterable[DoctestItem]:
import doctest

class MockAwareDocTestFinder(doctest.DocTestFinder):
Expand Down
Loading