Merge master into features

This commit is contained in:
Daniel Hahler 2020-01-29 03:07:35 +01:00
commit 55e5817570
9 changed files with 85 additions and 19 deletions

View File

@ -54,6 +54,7 @@ jobs:
python: "3.5"
os: windows-latest
tox_env: "py35-xdist"
use_coverage: true
- name: "windows-py36"
python: "3.6"
os: windows-latest
@ -70,6 +71,7 @@ jobs:
python: "3.8"
os: windows-latest
tox_env: "py38"
use_coverage: true
- name: "ubuntu-py35"
python: "3.5"
@ -83,6 +85,7 @@ jobs:
python: "3.7"
os: ubuntu-latest
tox_env: "py37-lsof-numpy-oldattrs-pexpect-twisted"
use_coverage: true
- name: "ubuntu-py37-pluggy"
python: "3.7"
os: ubuntu-latest
@ -91,8 +94,6 @@ jobs:
python: "3.7"
os: ubuntu-latest
tox_env: "py37-freeze"
# coverage does not apply for freeze test, skip it
skip_coverage: true
- name: "ubuntu-py38"
python: "3.8"
os: ubuntu-latest
@ -101,8 +102,6 @@ jobs:
python: "pypy3"
os: ubuntu-latest
tox_env: "pypy3-xdist"
# coverage too slow with pypy3, skip it
skip_coverage: true
- name: "macos-py37"
python: "3.7"
@ -112,21 +111,21 @@ jobs:
python: "3.8"
os: macos-latest
tox_env: "py38-xdist"
use_coverage: true
- name: "linting"
python: "3.7"
os: ubuntu-latest
tox_env: "linting"
skip_coverage: true
- name: "docs"
python: "3.7"
os: ubuntu-latest
tox_env: "docs"
skip_coverage: true
- name: "doctesting"
python: "3.7"
os: ubuntu-latest
tox_env: "doctesting"
use_coverage: true
steps:
- uses: actions/checkout@v1
@ -140,11 +139,11 @@ jobs:
pip install tox coverage
- name: Test without coverage
if: "matrix.skip_coverage"
if: "! matrix.use_coverage"
run: "tox -e ${{ matrix.tox_env }}"
- name: Test with coverage
if: "! matrix.skip_coverage"
if: "matrix.use_coverage"
env:
_PYTEST_TOX_COVERAGE_RUN: "coverage run -m"
COVERAGE_PROCESS_START: ".coveragerc"
@ -152,12 +151,12 @@ jobs:
run: "tox -e ${{ matrix.tox_env }}"
- name: Prepare coverage token
if: (!matrix.skip_coverage && ( github.repository == 'pytest-dev/pytest' || github.event_name == 'pull_request' ))
if: (matrix.use_coverage && ( github.repository == 'pytest-dev/pytest' || github.event_name == 'pull_request' ))
run: |
python scripts/append_codecov_token.py
- name: Report coverage
if: (!matrix.skip_coverage)
if: (matrix.use_coverage)
env:
CODECOV_NAME: ${{ matrix.name }}
run: bash scripts/report-coverage.sh -F GHA,${{ runner.os }}

View File

@ -114,6 +114,7 @@ Guido Wesdorp
Guoqiang Zhang
Harald Armin Massa
Henk-Jaap Wagenaar
Holger Kohr
Hugo van Kemenade
Hui Wang (coldnight)
Ian Bicking

View File

@ -0,0 +1,4 @@
Fix bug in the comparison of request key with cached key in fixture.
A construct ``if key == cached_key:`` can fail either because ``==`` is explicitly disallowed, or for, e.g., NumPy arrays, where the result of ``a == b`` cannot generally be converted to `bool`.
The implemented fix replaces `==` with ``is``.

View File

@ -77,12 +77,11 @@ class Code:
# maybe don't try this checking
if not p.check():
raise OSError("py.path check failed.")
return p
except OSError:
# XXX maybe try harder like the weird logic
# in the standard lib [linecache.updatecache] does?
p = self.raw.co_filename
return p
return self.raw.co_filename
@property
def fullsource(self) -> Optional["Source"]:

View File

@ -548,8 +548,9 @@ class FixtureRequest:
frameinfo = inspect.getframeinfo(frame[0])
source_path = py.path.local(frameinfo.filename)
source_lineno = frameinfo.lineno
if source_path.relto(funcitem.config.rootdir):
source_path_str = source_path.relto(funcitem.config.rootdir)
rel_source_path = source_path.relto(funcitem.config.rootdir)
if rel_source_path:
source_path_str = rel_source_path
else:
source_path_str = str(source_path)
msg = (
@ -896,7 +897,9 @@ class FixtureDef:
cached_result = getattr(self, "cached_result", None)
if cached_result is not None:
result, cache_key, err = cached_result
if my_cache_key == cache_key:
# note: comparison with `==` can fail (or be expensive) for e.g.
# numpy arrays (#6497)
if my_cache_key is cache_key:
if err is not None:
_, val, tb = err
raise val.with_traceback(tb)

View File

@ -4,6 +4,7 @@ import re
import sys
import warnings
from contextlib import contextmanager
from typing import Generator
import pytest
from _pytest.fixtures import fixture
@ -108,7 +109,7 @@ class MonkeyPatch:
self._savesyspath = None
@contextmanager
def context(self):
def context(self) -> Generator["MonkeyPatch", None, None]:
"""
Context manager that returns a new :class:`MonkeyPatch` object which
undoes any patching done inside the ``with`` block upon exit:

View File

@ -685,7 +685,7 @@ def raises( # noqa: F811
"""
__tracebackhide__ = True
for exc in filterfalse(
inspect.isclass, always_iterable(expected_exception, BASE_TYPE)
inspect.isclass, always_iterable(expected_exception, BASE_TYPE) # type: ignore[arg-type] # noqa: F821
):
msg = "exceptions must be derived from BaseException, not %s"
raise TypeError(msg % type(exc))

View File

@ -1102,6 +1102,38 @@ class TestFixtureUsages:
"*Fixture 'badscope' from test_invalid_scope.py got an unexpected scope value 'functions'"
)
@pytest.mark.parametrize("scope", ["function", "session"])
def test_parameters_without_eq_semantics(self, scope, testdir):
testdir.makepyfile(
"""
class NoEq1: # fails on `a == b` statement
def __eq__(self, _):
raise RuntimeError
class NoEq2: # fails on `if a == b:` statement
def __eq__(self, _):
class NoBool:
def __bool__(self):
raise RuntimeError
return NoBool()
import pytest
@pytest.fixture(params=[NoEq1(), NoEq2()], scope={scope!r})
def no_eq(request):
return request.param
def test1(no_eq):
pass
def test2(no_eq):
pass
""".format(
scope=scope
)
)
result = testdir.runpytest()
result.stdout.fnmatch_lines(["*4 passed*"])
def test_funcarg_parametrized_and_used_twice(self, testdir):
testdir.makepyfile(
"""
@ -3662,13 +3694,30 @@ class TestParameterizedSubRequest:
" test_foos.py::test_foo",
"",
"Requested fixture 'fix_with_param' defined in:",
"*fix.py:4",
"{}:4".format(fixfile),
"Requested here:",
"test_foos.py:4",
"*1 failed*",
]
)
# With non-overlapping rootdir, passing tests_dir.
rootdir = testdir.mkdir("rootdir")
rootdir.chdir()
result = testdir.runpytest("--rootdir", rootdir, tests_dir)
result.stdout.fnmatch_lines(
[
"The requested fixture has no parameter defined for test:",
" test_foos.py::test_foo",
"",
"Requested fixture 'fix_with_param' defined in:",
"{}:4".format(fixfile),
"Requested here:",
"{}:4".format(testfile),
"*1 failed*",
]
)
def test_pytest_fixture_setup_and_post_finalizer_hook(testdir):
testdir.makeconftest(

View File

@ -704,3 +704,13 @@ def test_testdir_outcomes_with_multiple_errors(testdir):
result.assert_outcomes(error=2)
assert result.parseoutcomes() == {"error": 2}
def test_makefile_joins_absolute_path(testdir: Testdir) -> None:
absfile = testdir.tmpdir / "absfile"
if sys.platform == "win32":
with pytest.raises(OSError):
testdir.makepyfile(**{str(absfile): ""})
else:
p1 = testdir.makepyfile(**{str(absfile): ""})
assert str(p1) == (testdir.tmpdir / absfile) + ".py"