Stop using more-itertools

We barely use it; the couple places that do are not really worth the
extra dependency, I think the code is clearer without it.

Also simplifies one (regular) itertools usage.

Also improves a check and an error message in `pytest.raises`.
This commit is contained in:
Ran Benita 2020-07-30 17:05:32 +03:00
parent 645cbc91fc
commit 96a48f0c66
6 changed files with 40 additions and 22 deletions

View File

@ -0,0 +1 @@
The dependency on the ``more-itertools`` package has been removed.

View File

@ -42,7 +42,6 @@ packages =
install_requires =
attrs>=17.4.0
iniconfig
more-itertools>=4.0.0
packaging
pluggy>=0.12,<1.0
py>=1.8.2

View File

@ -1,6 +1,5 @@
import functools
import inspect
import itertools
import sys
import warnings
from collections import defaultdict
@ -1489,10 +1488,10 @@ class FixtureManager:
else:
argnames = ()
usefixtures = itertools.chain.from_iterable(
mark.args for mark in node.iter_markers(name="usefixtures")
usefixtures = tuple(
arg for mark in node.iter_markers(name="usefixtures") for arg in mark.args
)
initialnames = tuple(usefixtures) + argnames
initialnames = usefixtures + argnames
fm = node.session._fixturemanager
initialnames, names_closure, arg2fixturedefs = fm.getfixtureclosure(
initialnames, node, ignore_args=self._get_direct_parametrize_args(node)

View File

@ -1,11 +1,9 @@
import inspect
import math
import pprint
from collections.abc import Iterable
from collections.abc import Mapping
from collections.abc import Sized
from decimal import Decimal
from itertools import filterfalse
from numbers import Number
from types import TracebackType
from typing import Any
@ -18,8 +16,6 @@ from typing import Tuple
from typing import TypeVar
from typing import Union
from more_itertools.more import always_iterable
import _pytest._code
from _pytest.compat import overload
from _pytest.compat import STRING_TYPES
@ -30,9 +26,6 @@ if TYPE_CHECKING:
from typing import Type
BASE_TYPE = (type, STRING_TYPES)
def _non_numeric_type_error(value, at: Optional[str]) -> TypeError:
at_str = " at {}".format(at) if at else ""
return TypeError(
@ -680,11 +673,16 @@ def raises( # noqa: F811
documentation for :ref:`the try statement <python:try>`.
"""
__tracebackhide__ = True
for exc in filterfalse(
inspect.isclass, always_iterable(expected_exception, BASE_TYPE)
):
msg = "exceptions must be derived from BaseException, not %s"
raise TypeError(msg % type(exc))
if isinstance(expected_exception, type):
excepted_exceptions = (expected_exception,) # type: Tuple[Type[_E], ...]
else:
excepted_exceptions = expected_exception
for exc in excepted_exceptions:
if not isinstance(exc, type) or not issubclass(exc, BaseException):
msg = "expected exception must be a BaseException type, not {}"
not_a = exc.__name__ if isinstance(exc, type) else type(exc).__name__
raise TypeError(msg.format(not_a))
message = "DID NOT RAISE {}".format(expected_exception)

View File

@ -25,7 +25,6 @@ from typing import Union
import attr
import pluggy
import py
from more_itertools import collapse
import pytest
from _pytest import nodes
@ -715,11 +714,14 @@ class TerminalReporter:
self._write_report_lines_from_hooks(lines)
def _write_report_lines_from_hooks(
self, lines: List[Union[str, List[str]]]
self, lines: Sequence[Union[str, Sequence[str]]]
) -> None:
lines.reverse()
for line in collapse(lines):
self.write_line(line)
for line_or_lines in reversed(lines):
if isinstance(line_or_lines, str):
self.write_line(line_or_lines)
else:
for line in line_or_lines:
self.write_line(line)
def pytest_report_header(self, config: Config) -> List[str]:
line = "rootdir: %s" % config.rootdir

View File

@ -283,3 +283,22 @@ class TestRaises:
with pytest.raises(Exception, foo="bar"): # type: ignore[call-overload]
pass
assert "Unexpected keyword arguments" in str(excinfo.value)
def test_expected_exception_is_not_a_baseexception(self) -> None:
with pytest.raises(TypeError) as excinfo:
with pytest.raises("hello"): # type: ignore[call-overload]
pass # pragma: no cover
assert "must be a BaseException type, not str" in str(excinfo.value)
class NotAnException:
pass
with pytest.raises(TypeError) as excinfo:
with pytest.raises(NotAnException): # type: ignore[type-var]
pass # pragma: no cover
assert "must be a BaseException type, not NotAnException" in str(excinfo.value)
with pytest.raises(TypeError) as excinfo:
with pytest.raises(("hello", NotAnException)): # type: ignore[arg-type]
pass # pragma: no cover
assert "must be a BaseException type, not str" in str(excinfo.value)