Merge pull request #4383 from nicoddemus/merge-master-into-features

Merge master into features (about to prepare 4.0)
This commit is contained in:
Bruno Oliveira 2018-11-13 18:57:41 -02:00 committed by GitHub
commit fea09cda6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 197 additions and 59 deletions

View File

@ -1,5 +1,6 @@
sudo: false
language: python
dist: xenial
stages:
- baseline
- name: test
@ -7,7 +8,7 @@ stages:
- name: deploy
if: repo = pytest-dev/pytest AND tag IS present
python:
- '3.6'
- '3.7'
install:
- pip install --upgrade --pre tox
env:
@ -17,24 +18,21 @@ env:
- TOXENV=py27-nobyte
- TOXENV=py27-xdist
- TOXENV=py27-pluggymaster PYTEST_NO_COVERAGE=1
# Specialized factors for py36.
- TOXENV=py36-pexpect,py36-trial,py36-numpy
- TOXENV=py36-xdist
- TOXENV=py36-pluggymaster PYTEST_NO_COVERAGE=1
# Specialized factors for py37.
- TOXENV=py37-pexpect,py37-trial,py37-numpy
- TOXENV=py37-xdist
- TOXENV=py37-pluggymaster PYTEST_NO_COVERAGE=1
- TOXENV=py37-freeze PYTEST_NO_COVERAGE=1
jobs:
include:
# Coverage tracking is slow with pypy, skip it.
- env: TOXENV=pypy PYTEST_NO_COVERAGE=1
python: 'pypy-5.4'
dist: trusty
- env: TOXENV=py35
python: '3.5'
- env: TOXENV=py36-freeze PYTEST_NO_COVERAGE=1
python: '3.6'
- env: TOXENV=py37
python: '3.7'
sudo: required
dist: xenial
- &test-macos
language: generic
os: osx
@ -54,8 +52,11 @@ jobs:
- stage: baseline
env: TOXENV=py27
- env: TOXENV=py34
python: '3.4'
- env: TOXENV=py36
- env: TOXENV=linting,docs,doctesting PYTEST_NO_COVERAGE=1
python: '3.6'
- env: TOXENV=linting,docs,doctesting
python: '3.7'
- stage: deploy
python: '3.6'
@ -88,7 +89,8 @@ after_success:
- |
if [[ "$PYTEST_NO_COVERAGE" != 1 ]]; then
set -e
pip install coverage
# Add last TOXENV to $PATH.
PATH="$PWD/.tox/${TOXENV##*,}/bin:$PATH"
coverage combine
coverage xml --ignore-errors
coverage report -m --ignore-errors

View File

@ -18,6 +18,40 @@ with advance notice in the **Deprecations** section of releases.
.. towncrier release notes start
pytest 3.10.1 (2018-11-11)
==========================
Bug Fixes
---------
- `#4287 <https://github.com/pytest-dev/pytest/issues/4287>`_: Fix nested usage of debugging plugin (pdb), e.g. with pytester's ``testdir.runpytest``.
- `#4304 <https://github.com/pytest-dev/pytest/issues/4304>`_: Block the ``stepwise`` plugin if ``cacheprovider`` is also blocked, as one depends on the other.
- `#4306 <https://github.com/pytest-dev/pytest/issues/4306>`_: Parse ``minversion`` as an actual version and not as dot-separated strings.
- `#4310 <https://github.com/pytest-dev/pytest/issues/4310>`_: Fix duplicate collection due to multiple args matching the same packages.
- `#4321 <https://github.com/pytest-dev/pytest/issues/4321>`_: Fix ``item.nodeid`` with resolved symlinks.
- `#4325 <https://github.com/pytest-dev/pytest/issues/4325>`_: Fix collection of direct symlinked files, where the target does not match ``python_files``.
- `#4329 <https://github.com/pytest-dev/pytest/issues/4329>`_: Fix TypeError in report_collect with _collect_report_last_write.
Trivial/Internal Changes
------------------------
- `#4305 <https://github.com/pytest-dev/pytest/issues/4305>`_: Replace byte/unicode helpers in test_capture with python level syntax.
pytest 3.10.0 (2018-11-03)
==========================

View File

@ -169,7 +169,7 @@ Short version
#. Follow **PEP-8** for naming and `black <https://github.com/ambv/black>`_ for formatting.
#. Tests are run using ``tox``::
tox -e linting,py27,py36
tox -e linting,py27,py37
The test environments above are usually enough to cover most cases locally.
@ -237,12 +237,12 @@ Here is a simple overview, with pytest-specific bits:
#. Run all the tests
You need to have Python 2.7 and 3.6 available in your system. Now
You need to have Python 2.7 and 3.7 available in your system. Now
running tests is as simple as issuing this command::
$ tox -e linting,py27,py36
$ tox -e linting,py27,py37
This command will run tests via the "tox" tool against Python 2.7 and 3.6
This command will run tests via the "tox" tool against Python 2.7 and 3.7
and also perform "lint" coding-style checks.
#. You can now edit your local working copy and run the tests again as necessary. Please follow PEP-8 for naming.
@ -252,9 +252,9 @@ Here is a simple overview, with pytest-specific bits:
$ tox -e py27 -- --pdb
Or to only run tests in a particular test module on Python 3.6::
Or to only run tests in a particular test module on Python 3.7::
$ tox -e py36 -- testing/test_config.py
$ tox -e py37 -- testing/test_config.py
When committing, ``pre-commit`` will re-format the files if necessary.

View File

@ -2,7 +2,6 @@ environment:
matrix:
- TOXENV: "py27"
- TOXENV: "py37"
PYTEST_NO_COVERAGE: "1"
- TOXENV: "linting,docs,doctesting"
- TOXENV: "py36"
- TOXENV: "py35"
@ -14,13 +13,13 @@ environment:
- TOXENV: "py27-pluggymaster"
PYTEST_NO_COVERAGE: "1"
- TOXENV: "py27-xdist"
# Specialized factors for py36.
- TOXENV: "py36-trial,py36-numpy"
- TOXENV: "py36-pluggymaster"
# Specialized factors for py37.
- TOXENV: "py37-trial,py37-numpy"
- TOXENV: "py37-pluggymaster"
PYTEST_NO_COVERAGE: "1"
- TOXENV: "py36-freeze"
- TOXENV: "py37-freeze"
PYTEST_NO_COVERAGE: "1"
- TOXENV: "py36-xdist"
- TOXENV: "py37-xdist"
matrix:
fast_finish: true

View File

@ -1 +0,0 @@
Fix nested usage of debugging plugin (pdb), e.g. with pytester's ``testdir.runpytest``.

View File

@ -1 +0,0 @@
Block the ``stepwise`` plugin if ``cacheprovider`` is also blocked, as one depends on the other.

View File

@ -1 +0,0 @@
Replace byte/unicode helpers in test_capture with python level syntax.

View File

@ -1 +0,0 @@
Parse ``minversion`` as an actual version and not as dot-separated strings.

View File

@ -1 +0,0 @@
Fix duplicate collection due to multiple args matching the same packages.

View File

@ -1 +0,0 @@
Fix TypeError in report_collect with _collect_report_last_write.

View File

@ -6,6 +6,7 @@ Release announcements
:maxdepth: 2
release-3.10.1
release-3.10.0
release-3.9.3
release-3.9.2

View File

@ -0,0 +1,24 @@
pytest-3.10.1
=======================================
pytest 3.10.1 has just been released to PyPI.
This is a bug-fix release, being a drop-in replacement. To upgrade::
pip install --upgrade pytest
The full changelog is available at https://docs.pytest.org/en/latest/changelog.html.
Thanks to all who contributed to this release, among them:
* Anthony Sottile
* Boris Feld
* Bruno Oliveira
* Daniel Hahler
* Fabien ZARIFIAN
* Jon Dufresne
* Ronny Pfannschmidt
Happy testing,
The pytest Development Team

View File

@ -85,9 +85,8 @@ interesting to just look at the collection tree::
rootdir: $REGENDOC_TMPDIR/nonpython, inifile:
collected 2 items
<Package '$REGENDOC_TMPDIR/nonpython'>
<Package '$REGENDOC_TMPDIR/nonpython'>
<YamlFile 'test_simple.yml'>
<YamlItem 'hello'>
<YamlItem 'ok'>
<YamlFile 'test_simple.yml'>
<YamlItem 'hello'>
<YamlItem 'ok'>
======================= no tests ran in 0.12 seconds =======================

View File

@ -398,6 +398,7 @@ class Session(nodes.FSCollector):
# Keep track of any collected nodes in here, so we don't duplicate fixtures
self._node_cache = {}
self._bestrelpathcache = _bestrelpath_cache(config.rootdir)
# Dirnames of pkgs with dunder-init files.
self._pkg_roots = {}
self.config.pluginmanager.register(self, name="session")
@ -504,7 +505,7 @@ class Session(nodes.FSCollector):
from _pytest.python import Package
names = self._parsearg(arg)
argpath = names.pop(0).realpath()
argpath = names.pop(0)
# Start with a Session root, and delve to argpath item (dir or file)
# and stack all Packages found on the way.
@ -551,8 +552,7 @@ class Session(nodes.FSCollector):
seen_dirs.add(dirpath)
pkginit = dirpath.join("__init__.py")
if pkginit.exists():
collect_root = self._pkg_roots.get(dirpath, self)
for x in collect_root._collectfile(pkginit):
for x in self._collectfile(pkginit):
yield x
if isinstance(x, Package):
self._pkg_roots[dirpath] = x
@ -652,7 +652,7 @@ class Session(nodes.FSCollector):
"file or package not found: " + arg + " (missing __init__.py?)"
)
raise UsageError("file not found: " + arg)
parts[0] = path
parts[0] = path.realpath()
return parts
def matchnodes(self, matching, names):

View File

@ -449,7 +449,7 @@ class Collector(Node):
def _check_initialpaths_for_relpath(session, fspath):
for initial_path in session._initialpaths:
if fspath.common(initial_path) == initial_path:
return fspath.relto(initial_path.dirname)
return fspath.relto(initial_path)
class FSCollector(Collector):

View File

@ -666,11 +666,11 @@ class TestInvocationVariants(object):
assert result.ret == 0
result.stdout.fnmatch_lines(
[
"*test_hello.py::test_hello*PASSED*",
"*test_hello.py::test_other*PASSED*",
"*test_world.py::test_world*PASSED*",
"*test_world.py::test_other*PASSED*",
"*4 passed*",
"test_hello.py::test_hello*PASSED*",
"test_hello.py::test_other*PASSED*",
"ns_pkg/world/test_world.py::test_world*PASSED*",
"ns_pkg/world/test_world.py::test_other*PASSED*",
"*4 passed in*",
]
)

View File

@ -15,7 +15,7 @@ def equal_with_bash(prefix, ffc, fc, out=None):
res_bash = set(fc(prefix))
retval = set(res) == res_bash
if out:
out.write("equal_with_bash {} {}\n".format(retval, res))
out.write("equal_with_bash({}) {} {}\n".format(prefix, retval, res))
if not retval:
out.write(" python - bash: %s\n" % (set(res) - res_bash))
out.write(" bash - python: %s\n" % (res_bash - set(res)))
@ -91,13 +91,19 @@ class FilesCompleter(object):
class TestArgComplete(object):
@pytest.mark.skipif("sys.platform in ('win32', 'darwin')")
def test_compare_with_compgen(self):
def test_compare_with_compgen(self, tmpdir):
from _pytest._argcomplete import FastFilesCompleter
ffc = FastFilesCompleter()
fc = FilesCompleter()
for x in ["/", "/d", "/data", "qqq", ""]:
assert equal_with_bash(x, ffc, fc, out=sys.stdout)
with tmpdir.as_cwd():
assert equal_with_bash("", ffc, fc, out=sys.stdout)
tmpdir.ensure("data")
for x in ["d", "data", "doesnotexist", ""]:
assert equal_with_bash(x, ffc, fc, out=sys.stdout)
@pytest.mark.skipif("sys.platform in ('win32', 'darwin')")
def test_remove_dir_prefix(self):

View File

@ -6,6 +6,8 @@ import pprint
import sys
import textwrap
import py
import pytest
from _pytest.main import _in_venv
from _pytest.main import EXIT_NOTESTSCOLLECTED
@ -1082,4 +1084,55 @@ def test_collect_with_chdir_during_import(testdir):
with testdir.tmpdir.as_cwd():
result = testdir.runpytest("--collect-only")
result.stdout.fnmatch_lines(["collected 1 item"])
@pytest.mark.skipif(
not hasattr(py.path.local, "mksymlinkto"),
reason="symlink not available on this platform",
)
def test_collect_symlink_file_arg(testdir):
"""Test that collecting a direct symlink, where the target does not match python_files works (#4325)."""
real = testdir.makepyfile(
real="""
def test_nodeid(request):
assert request.node.nodeid == "real.py::test_nodeid"
"""
)
symlink = testdir.tmpdir.join("symlink.py")
symlink.mksymlinkto(real)
result = testdir.runpytest("-v", symlink)
result.stdout.fnmatch_lines(["real.py::test_nodeid PASSED*", "*1 passed in*"])
assert result.ret == 0
@pytest.mark.skipif(
not hasattr(py.path.local, "mksymlinkto"),
reason="symlink not available on this platform",
)
def test_collect_symlink_out_of_tree(testdir):
"""Test collection of symlink via out-of-tree rootdir."""
sub = testdir.tmpdir.join("sub")
real = sub.join("test_real.py")
real.write(
textwrap.dedent(
"""
def test_nodeid(request):
# Should not contain sub/ prefix.
assert request.node.nodeid == "test_real.py::test_nodeid"
"""
),
ensure=True,
)
out_of_tree = testdir.tmpdir.join("out_of_tree").ensure(dir=True)
symlink_to_sub = out_of_tree.join("symlink_to_sub")
symlink_to_sub.mksymlinkto(sub)
sub.chdir()
result = testdir.runpytest("-vs", "--rootdir=%s" % sub, symlink_to_sub)
result.stdout.fnmatch_lines(
[
# Should not contain "sub/"!
"test_real.py::test_nodeid PASSED"
]
)
assert result.ret == 0

View File

@ -1,3 +1,5 @@
import py
import pytest
from _pytest import nodes
@ -29,3 +31,23 @@ def test_std_warn_not_pytestwarning(testdir):
)
with pytest.raises(ValueError, match=".*instance of PytestWarning.*"):
items[0].warn(UserWarning("some warning"))
def test__check_initialpaths_for_relpath():
"""Ensure that it handles dirs, and does not always use dirname."""
cwd = py.path.local()
class FakeSession:
_initialpaths = [cwd]
assert nodes._check_initialpaths_for_relpath(FakeSession, cwd) == ""
sub = cwd.join("file")
class FakeSession:
_initialpaths = [cwd]
assert nodes._check_initialpaths_for_relpath(FakeSession, sub) == "file"
outside = py.path.local("/outside")
assert nodes._check_initialpaths_for_relpath(FakeSession, outside) is None

View File

@ -333,7 +333,11 @@ def test_rootdir_option_arg(testdir, monkeypatch, path):
result = testdir.runpytest("--rootdir={}".format(path))
result.stdout.fnmatch_lines(
["*rootdir: {}/root, inifile:*".format(testdir.tmpdir), "*1 passed*"]
[
"*rootdir: {}/root, inifile:*".format(testdir.tmpdir),
"root/test_rootdir_option_arg.py *",
"*1 passed*",
]
)

20
tox.ini
View File

@ -10,10 +10,10 @@ envlist =
py36
py37
pypy
{py27,py36}-{pexpect,xdist,trial,numpy,pluggymaster}
{py27,py37}-{pexpect,xdist,trial,numpy,pluggymaster}
py27-nobyte
doctesting
py36-freeze
py37-freeze
docs
[testenv]
@ -23,7 +23,7 @@ commands =
coverage: coverage report
passenv = USER USERNAME COVERAGE_* TRAVIS
setenv =
# configuration if a user runs tox with a "coverage" factor, for example "tox -e py36-coverage"
# configuration if a user runs tox with a "coverage" factor, for example "tox -e py37-coverage"
coverage: _PYTEST_TOX_COVERAGE_RUN=coverage run -m
coverage: _PYTEST_TOX_EXTRA_DEP=coverage-enable-subprocess
coverage: COVERAGE_FILE={toxinidir}/.coverage
@ -46,7 +46,7 @@ commands =
[testenv:linting]
skip_install = True
basepython = python3.6
basepython = python3
deps = pre-commit>=1.11.0
commands = pre-commit run --all-files --show-diff-on-failure
@ -60,7 +60,7 @@ deps =
commands =
{env:_PYTEST_TOX_COVERAGE_RUN:} pytest -n auto {posargs}
[testenv:py36-xdist]
[testenv:py37-xdist]
# NOTE: copied from above due to https://github.com/tox-dev/tox/issues/706.
deps =
pytest-xdist>=1.13
@ -78,7 +78,7 @@ deps =
commands =
{env:_PYTEST_TOX_COVERAGE_RUN:} pytest testing/test_pdb.py testing/test_terminal.py testing/test_unittest.py {posargs}
[testenv:py36-pexpect]
[testenv:py37-pexpect]
platform = {[testenv:py27-pexpect]platform}
deps = {[testenv:py27-pexpect]deps}
commands = {[testenv:py27-pexpect]commands}
@ -103,7 +103,7 @@ deps =
commands =
{env:_PYTEST_TOX_COVERAGE_RUN:} pytest {posargs:testing/test_unittest.py}
[testenv:py36-trial]
[testenv:py37-trial]
deps = {[testenv:py27-trial]deps}
commands = {[testenv:py27-trial]commands}
@ -114,7 +114,7 @@ deps =
commands=
{env:_PYTEST_TOX_COVERAGE_RUN:} pytest {posargs:testing/python/approx.py}
[testenv:py36-numpy]
[testenv:py37-numpy]
deps = {[testenv:py27-numpy]deps}
commands = {[testenv:py27-numpy]commands}
@ -125,7 +125,7 @@ setenv=
# NOTE: using env instead of "{[testenv]deps}", because of https://github.com/tox-dev/tox/issues/706.
_PYTEST_TOX_EXTRA_DEP=git+https://github.com/pytest-dev/pluggy.git@master
[testenv:py36-pluggymaster]
[testenv:py37-pluggymaster]
setenv = {[testenv:py27-pluggymaster]setenv}
[testenv:docs]
@ -170,7 +170,7 @@ changedir = testing
commands =
{envpython} {envbindir}/py.test-jython {posargs}
[testenv:py36-freeze]
[testenv:py37-freeze]
changedir = testing/freeze
deps =
pyinstaller