Skip to content

Merge master into features #6616

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

Merged
merged 16 commits into from
Jan 29, 2020
Merged
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
19 changes: 9 additions & 10 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -70,6 +71,7 @@ jobs:
python: "3.8"
os: windows-latest
tox_env: "py38"
use_coverage: true

- name: "ubuntu-py35"
python: "3.5"
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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"
Expand All @@ -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
Expand All @@ -140,24 +139,24 @@ 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"
_PYTEST_TOX_EXTRA_DEP: "coverage-enable-subprocess"
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 }}
Expand Down
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ Guido Wesdorp
Guoqiang Zhang
Harald Armin Massa
Henk-Jaap Wagenaar
Holger Kohr
Hugo van Kemenade
Hui Wang (coldnight)
Ian Bicking
Expand Down
4 changes: 4 additions & 0 deletions changelog/6497.bugfix.rst
Original file line number Diff line number Diff line change
@@ -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``.
5 changes: 2 additions & 3 deletions src/_pytest/_code/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,11 @@ def path(self) -> Union[py.path.local, str]:
# 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"]:
Expand Down
9 changes: 6 additions & 3 deletions src/_pytest/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,8 +548,9 @@ def _compute_fixture_value(self, fixturedef: "FixtureDef") -> None:
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 = (
Expand Down Expand Up @@ -896,7 +897,9 @@ def execute(self, request):
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)
Expand Down
3 changes: 2 additions & 1 deletion src/_pytest/monkeypatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import sys
import warnings
from contextlib import contextmanager
from typing import Generator

import pytest
from _pytest.fixtures import fixture
Expand Down Expand Up @@ -108,7 +109,7 @@ def __init__(self):
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:
Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/python_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
51 changes: 50 additions & 1 deletion testing/python/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -1102,6 +1102,38 @@ def test_nothing(badscope):
"*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(
"""
Expand Down Expand Up @@ -3662,13 +3694,30 @@ def test_foo(request):
" 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(
Expand Down
10 changes: 10 additions & 0 deletions testing/test_pytester.py
Original file line number Diff line number Diff line change
Expand Up @@ -704,3 +704,13 @@ def test_error2(bad_fixture):
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"