Merge branch 'master' into merge-master-into-features

Conflicts:
	appveyor.yml
	setup.py
This commit is contained in:
Daniel Hahler 2019-03-05 19:07:36 +01:00
commit 76687030f0
32 changed files with 310 additions and 251 deletions

View File

@ -1,9 +1,18 @@
[run]
source = pytest,_pytest,testing/
include =
*/src/*
testing/*
*/lib/python*/site-packages/_pytest/*
*/lib/python*/site-packages/pytest.py
*/pypy*/site-packages/_pytest/*
*/pypy*/site-packages/pytest.py
*\Lib\site-packages\_pytest\*
*\Lib\site-packages\pytest.py
parallel = 1
branch = 1
[paths]
source = src/
.tox/*/lib/python*/site-packages/
.tox\*\Lib\site-packages\
*/lib/python*/site-packages/
*/pypy*/site-packages/
*\Lib\site-packages\

View File

@ -9,54 +9,68 @@ stages:
python:
- '3.7'
install:
- pip install --upgrade --pre tox
env:
matrix:
- TOXENV=py27
# Specialized factors for py27.
- TOXENV=py27-nobyte
- TOXENV=py27-xdist
- TOXENV=py27-pluggymaster
# Specialized factors for py37.
- TOXENV=py37-pexpect,py37-trial,py37-numpy
- TOXENV=py37-pluggymaster
- TOXENV=py37-freeze PYTEST_NO_COVERAGE=1
matrix:
allow_failures:
- python: '3.8-dev'
env: TOXENV=py38-xdist
- python -m pip install --upgrade --pre tox
jobs:
include:
# OSX tests - first (in test stage), since they are the slower ones.
- &test-macos
# NOTE: (tests with) pexpect appear to be buggy on Travis,
# at least with coverage.
# Log: https://travis-ci.org/pytest-dev/pytest/jobs/500358864
os: osx
osx_image: xcode10.1
language: generic
# Coverage for:
# - py2 with symlink in test_cmdline_python_package_symlink.
env: TOXENV=py27-xdist PYTEST_COVERAGE=1
before_install:
- python -V
- test $(python -c 'import sys; print("%d%d" % sys.version_info[0:2])') = 27
- <<: *test-macos
env: TOXENV=py37-xdist
before_install:
- which python3
- python3 -V
- ln -sfn "$(which python3)" /usr/local/bin/python
- python -V
- test $(python -c 'import sys; print("%d%d" % sys.version_info[0:2])') = 37
# Full run of latest (major) supported versions, without xdist.
- env: TOXENV=py27
python: '2.7'
- env: TOXENV=py37
python: '3.7'
# Coverage tracking is slow with pypy, skip it.
- env: TOXENV=pypy-xdist PYTEST_NO_COVERAGE=1
- env: TOXENV=pypy-xdist
python: 'pypy2.7-6.0'
- env: TOXENV=pypy3-xdist PYTEST_NO_COVERAGE=1
- env: TOXENV=pypy3-xdist
python: 'pypy3.5-6.0'
- env: TOXENV=py34-xdist
python: '3.4'
- env: TOXENV=py35-xdist
python: '3.5'
- env: TOXENV=py36-xdist
python: '3.6'
- env: TOXENV=py37
- &test-macos
language: generic
os: osx
osx_image: xcode9.4
sudo: required
install:
- python -m pip install --pre tox
env: TOXENV=py27-xdist
- <<: *test-macos
env: TOXENV=py37-xdist
before_install:
- brew update
- brew upgrade python
- brew unlink python
- brew link python
# Coverage for:
# - pytester's LsofFdLeakChecker
# - TestArgComplete (linux only)
# - numpy
- env: TOXENV=py37-lsof-numpy-xdist PYTEST_COVERAGE=1
# Specialized factors for py27.
- env: TOXENV=py27-nobyte-numpy-xdist
python: '2.7'
- env: TOXENV=py27-pluggymaster-xdist
python: '2.7'
# Specialized factors for py37.
# Coverage for:
# - test_sys_breakpoint_interception (via pexpect).
- env: TOXENV=py37-pexpect,py37-trial PYTEST_COVERAGE=1
- env: TOXENV=py37-pluggymaster-xdist
- env: TOXENV=py37-freeze
# Jobs only run via Travis cron jobs (currently daily).
- env: TOXENV=py38-xdist
@ -64,14 +78,17 @@ jobs:
if: type = cron
- stage: baseline
env: TOXENV=py27-pexpect,py27-trial,py27-numpy
- env: TOXENV=py37-xdist
- env: TOXENV=linting,docs,doctesting
python: '3.7'
# Coverage for:
# - _pytest.unittest._handle_skip (via pexpect).
env: TOXENV=py27-pexpect,py27-trial PYTEST_COVERAGE=1
python: '2.7'
# Use py36 here for faster baseline.
- env: TOXENV=py36-xdist
python: '3.6'
- env: TOXENV=linting,docs,doctesting PYTEST_COVERAGE=1
- stage: deploy
python: '3.6'
env: PYTEST_NO_COVERAGE=1
install: pip install -U setuptools setuptools_scm
script: skip
deploy:
@ -85,9 +102,19 @@ jobs:
tags: true
repo: pytest-dev/pytest
matrix:
allow_failures:
- python: '3.8-dev'
env: TOXENV=py38-xdist
before_script:
- |
if [[ "$PYTEST_NO_COVERAGE" != 1 ]]; then
# Do not (re-)upload coverage with cron runs.
if [[ "$TRAVIS_EVENT_TYPE" = cron ]]; then
PYTEST_COVERAGE=0
fi
- |
if [[ "$PYTEST_COVERAGE" = 1 ]]; then
export COVERAGE_FILE="$PWD/.coverage"
export COVERAGE_PROCESS_START="$PWD/.coveragerc"
export _PYTEST_TOX_COVERAGE_RUN="coverage run -m"
@ -98,14 +125,14 @@ script: tox --recreate
after_success:
- |
if [[ "$PYTEST_NO_COVERAGE" != 1 ]]; then
if [[ "$PYTEST_COVERAGE" = 1 ]]; then
set -e
# Add last TOXENV to $PATH.
PATH="$PWD/.tox/${TOXENV##*,}/bin:$PATH"
coverage combine
coverage xml --ignore-errors
coverage report -m --ignore-errors
bash <(curl -s https://codecov.io/bash) -Z -X gcov -X coveragepy -X search -X xcode -X gcovout -X fix -f coverage.xml -F $TRAVIS_OS_NAME
coverage xml
coverage report -m
bash <(curl -s https://codecov.io/bash) -Z -X gcov -X coveragepy -X search -X xcode -X gcovout -X fix -f coverage.xml -n $TOXENV-$TRAVIS_OS_NAME
fi
notifications:

View File

@ -22,8 +22,8 @@
.. image:: https://travis-ci.org/pytest-dev/pytest.svg?branch=master
:target: https://travis-ci.org/pytest-dev/pytest
.. image:: https://ci.appveyor.com/api/projects/status/mrgbjaua7t33pg6b?svg=true
:target: https://ci.appveyor.com/project/pytestbot/pytest
.. image:: https://dev.azure.com/pytest-dev/pytest/_apis/build/status/pytest-CI?branchName=master
:target: https://dev.azure.com/pytest-dev/pytest
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
:target: https://github.com/ambv/black

View File

@ -1,48 +0,0 @@
environment:
matrix:
- TOXENV: "py37-xdist"
- TOXENV: "py27-xdist"
- TOXENV: "linting,docs,doctesting"
- TOXENV: "py34-xdist"
- TOXENV: "py35-xdist"
- TOXENV: "py36-xdist"
# NOTE: pypy-xdist is buggy currently (https://github.com/pytest-dev/pytest-xdist/issues/142).
- TOXENV: "pypy"
PYTEST_NO_COVERAGE: "1"
# Specialized factors for py27.
- TOXENV: "py27-trial,py27-numpy,py27-nobyte"
# Specialized factors for py37.
- TOXENV: "py37-trial,py37-numpy"
- TOXENV: "py37-freeze"
PYTEST_NO_COVERAGE: "1"
matrix:
fast_finish: true
install:
- echo Installed Pythons
- dir c:\Python*
- if "%TOXENV%" == "pypy" call scripts\install-pypy.bat
- C:\Python36\python -m pip install --upgrade pip
- C:\Python36\python -m pip install --upgrade --pre tox
build: false # Not a C# project, build stuff at the test step instead.
before_test:
- call scripts\prepare-coverage.bat
test_script:
- C:\Python36\python -m tox
on_success:
- call scripts\upload-coverage.bat
cache:
- '%LOCALAPPDATA%\pip\cache'
- '%USERPROFILE%\.cache\pre-commit'
# We don't deploy anything on tags with AppVeyor, we use Travis instead, so we
# might as well save resources
skip_tags: true

View File

@ -6,6 +6,9 @@ variables:
PYTEST_ADDOPTS: "--junitxml=build/test-results/$(tox.env).xml"
python.needs_vc: False
python.exe: "python"
COVERAGE_FILE: "$(Build.Repository.LocalPath)/.coverage"
COVERAGE_PROCESS_START: "$(Build.Repository.LocalPath)/.coveragerc"
PYTEST_COVERAGE: '0'
jobs:
@ -17,47 +20,68 @@ jobs:
py27:
python.version: '2.7'
tox.env: 'py27'
py27-xdist:
py27-nobyte-lsof-numpy:
python.version: '2.7'
tox.env: 'py27-xdist'
py27-numpy/nobyte:
python.version: '2.7'
tox.env: 'py27-numpy,py27-nobyte'
tox.env: 'py27-lsof-nobyte-numpy'
# Coverage for:
# - test_supports_breakpoint_module_global
# - test_terminal_reporter_writer_attr (without xdist)
# - "if write" branch in _pytest.assertion.rewrite
# - numpy
# - pytester's LsofFdLeakChecker (being skipped)
PYTEST_COVERAGE: '1'
py27-trial:
python.version: '2.7'
tox.env: 'py27-trial'
python.needs_vc: True
py27-pluggymaster:
py27-pluggymaster-xdist:
python.version: '2.7'
tox.env: 'pluggymaster'
tox.env: 'py27-pluggymaster-xdist'
# Coverage for:
# - except-IOError in _attempt_to_close_capture_file for py2.
# Also seen with py27-nobyte (using xdist), and py27-xdist.
# But no exception with py27-pexpect,py27-trial,py27-numpy.
PYTEST_COVERAGE: '1'
pypy:
python.version: 'pypy'
tox.env: 'pypy'
python.exe: 'pypy'
py34:
# NOTE: pypy3 fails to install pip currently due to an interal error.
# pypy3:
# python.version: 'pypy3'
# tox.env: 'pypy3'
# python.exe: 'pypy3'
py34-xdist:
python.version: '3.4'
tox.env: 'py34'
py35:
tox.env: 'py34-xdist'
# Coverage for:
# - _pytest.compat._bytes_to_ascii
PYTEST_COVERAGE: '1'
py35-xdist:
python.version: '3.5'
tox.env: 'py35'
py36:
tox.env: 'py35-xdist'
# Coverage for:
# - test_supports_breakpoint_module_global
PYTEST_COVERAGE: '1'
py36-xdist:
python.version: '3.6'
tox.env: 'py36'
tox.env: 'py36-xdist'
py37:
python.version: '3.7'
tox.env: 'py37'
# Coverage for:
# - _py36_windowsconsoleio_workaround (with py36+)
# - test_request_garbage (no xdist)
PYTEST_COVERAGE: '1'
py37-linting/docs/doctesting:
python.version: '3.7'
tox.env: 'linting,docs,doctesting'
py37-xdist:
python.version: '3.7'
tox.env: 'py37-xdist'
py37-trial/numpy:
python.version: '3.7'
tox.env: 'py37-trial,py37-numpy'
py37-pluggymaster:
py37-pluggymaster-xdist:
python.version: '3.7'
tox.env: 'py37-pluggymaster'
tox.env: 'py37-pluggymaster-xdist'
maxParallel: 10
steps:
@ -91,7 +115,9 @@ jobs:
- script: $(python.exe) -m pip install --upgrade pip && $(python.exe) -m pip install tox
displayName: 'Install tox'
- script: $(python.exe) -m tox -e $(tox.env)
- script: |
call scripts/setup-coverage-vars.bat || goto :eof
$(python.exe) -m tox -e $(tox.env)
displayName: 'Run tests'
- task: PublishTestResults@2
@ -99,3 +125,11 @@ jobs:
testResultsFiles: 'build/test-results/$(tox.env).xml'
testRunTitle: '$(tox.env)'
condition: succeededOrFailed()
- script: call scripts\upload-coverage.bat
displayName: 'Report and upload coverage'
condition: eq(variables['PYTEST_COVERAGE'], '1')
env:
PYTHON: $(python.exe)
CODECOV_TOKEN: $(CODECOV_TOKEN)
PYTEST_CODECOV_NAME: $(tox.env)

View File

@ -2,7 +2,6 @@ from six.moves import range
import pytest
SKIP = True

View File

@ -0,0 +1 @@
Improve validation of contents written to captured output so it behaves the same as when capture is disabled.

View File

@ -252,8 +252,8 @@ the conftest file:
.. _assert-details:
.. _`assert introspection`:
Advanced assertion introspection
----------------------------------
Assertion introspection details
-------------------------------
.. versionadded:: 2.1
@ -266,28 +266,46 @@ supporting modules which are not themselves test modules will not be rewritten**
You can manually enable assertion rewriting for an imported module by calling
`register_assert_rewrite <https://docs.pytest.org/en/latest/writing_plugins.html#assertion-rewriting>`_
before you import it (a good place to do that is in ``conftest.py``).
.. note::
``pytest`` rewrites test modules on import by using an import
hook to write new ``pyc`` files. Most of the time this works transparently.
However, if you are messing with import yourself, the import hook may
interfere.
If this is the case you have two options:
* Disable rewriting for a specific module by adding the string
``PYTEST_DONT_REWRITE`` to its docstring.
* Disable rewriting for all modules by using ``--assert=plain``.
Additionally, rewriting will fail silently if it cannot write new ``.pyc`` files,
i.e. in a read-only filesystem or a zipfile.
before you import it (a good place to do that is in your root ``conftest.py``).
For further information, Benjamin Peterson wrote up `Behind the scenes of pytest's new assertion rewriting <http://pybites.blogspot.com/2011/07/behind-scenes-of-pytests-new-assertion.html>`_.
Assertion rewriting caches files on disk
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``pytest`` will write back the rewritten modules to disk for caching. You can disable
this behavior (for example to avoid leaving stale ``.pyc`` files around in projects that
move files around a lot) by adding this to the top of your ``conftest.py`` file:
.. code-block:: python
import sys
sys.dont_write_bytecode = True
Note that you still get the benefits of assertion introspection, the only change is that
the ``.pyc`` files won't be cached on disk.
Additionally, rewriting will silently skip caching if it cannot write new ``.pyc`` files,
i.e. in a read-only filesystem or a zipfile.
Disabling assert rewriting
~~~~~~~~~~~~~~~~~~~~~~~~~~
``pytest`` rewrites test modules on import by using an import
hook to write new ``pyc`` files. Most of the time this works transparently.
However, if you are working with the import machinery yourself, the import hook may
interfere.
If this is the case you have two options:
* Disable rewriting for a specific module by adding the string
``PYTEST_DONT_REWRITE`` to its docstring.
* Disable rewriting for all modules by using ``--assert=plain``.
.. versionadded:: 2.1
Add assert rewriting as an alternate introspection technique.

View File

@ -499,6 +499,32 @@ Each recorded warning is an instance of :class:`warnings.WarningMessage`.
differently; see :ref:`ensuring_function_triggers`.
tmp_path
~~~~~~~~
**Tutorial**: :doc:`tmpdir`
.. currentmodule:: _pytest.tmpdir
.. autofunction:: tmp_path()
:no-auto-options:
tmp_path_factory
~~~~~~~~~~~~~~~~
**Tutorial**: :ref:`tmp_path_factory example`
.. _`tmp_path_factory factory api`:
``tmp_path_factory`` instances have the following methods:
.. currentmodule:: _pytest.tmpdir
.. automethod:: TempPathFactory.mktemp
.. automethod:: TempPathFactory.getbasetemp
tmpdir
~~~~~~

View File

@ -66,6 +66,9 @@ Running this would result in a passed test except for the last
test_tmp_path.py:13: AssertionError
========================= 1 failed in 0.12 seconds =========================
.. _`tmp_path_factory example`:
The ``tmp_path_factory`` fixture
--------------------------------
@ -77,6 +80,8 @@ to create arbitrary temporary directories from any other fixture or test.
It is intended to replace ``tmpdir_factory``, and returns :class:`pathlib.Path` instances.
See :ref:`tmp_path_factory API <tmp_path_factory factory api>` for details.
The 'tmpdir' fixture
--------------------

View File

@ -1,6 +0,0 @@
REM install pypy using choco
REM redirect to a file because choco install python.pypy is too noisy. If the command fails, write output to console
choco install python.pypy > pypy-inst.log 2>&1 || (type pypy-inst.log & exit /b 1)
set PATH=C:\tools\pypy\pypy;%PATH% # so tox can find pypy
echo PyPy installed
pypy --version

View File

@ -1,10 +0,0 @@
REM scripts called by AppVeyor to setup the environment variables to enable coverage
if not defined PYTEST_NO_COVERAGE (
set "COVERAGE_FILE=%CD%\.coverage"
set "COVERAGE_PROCESS_START=%CD%\.coveragerc"
set "_PYTEST_TOX_COVERAGE_RUN=coverage run -m"
set "_PYTEST_TOX_EXTRA_DEP=coverage-enable-subprocess"
echo Coverage setup completed
) else (
echo Skipping coverage setup, PYTEST_NO_COVERAGE is set
)

View File

@ -0,0 +1,7 @@
if "%PYTEST_COVERAGE%" == "1" (
set "_PYTEST_TOX_COVERAGE_RUN=coverage run -m"
set "_PYTEST_TOX_EXTRA_DEP=coverage-enable-subprocess"
echo Coverage vars configured, PYTEST_COVERAGE=%PYTEST_COVERAGE%
) else (
echo Skipping coverage vars setup, PYTEST_COVERAGE=%PYTEST_COVERAGE%
)

View File

@ -1,11 +1,16 @@
REM script called by AppVeyor to combine and upload coverage information to codecov
if not defined PYTEST_NO_COVERAGE (
REM script called by Azure to combine and upload coverage information to codecov
if "%PYTEST_COVERAGE%" == "1" (
echo Prepare to upload coverage information
C:\Python36\Scripts\pip install codecov
C:\Python36\Scripts\coverage combine
C:\Python36\Scripts\coverage xml --ignore-errors
C:\Python36\Scripts\coverage report -m --ignore-errors
scripts\appveyor-retry C:\Python36\Scripts\codecov --required -X gcov pycov search -f coverage.xml --flags windows
if defined CODECOV_TOKEN (
echo CODECOV_TOKEN defined
) else (
echo CODECOV_TOKEN NOT defined
)
%PYTHON% -m pip install codecov
%PYTHON% -m coverage combine
%PYTHON% -m coverage xml
%PYTHON% -m coverage report -m
scripts\retry %PYTHON% -m codecov --required -X gcov pycov search -f coverage.xml --name %PYTEST_CODECOV_NAME%
) else (
echo Skipping coverage upload, PYTEST_NO_COVERAGE is set
echo Skipping coverage upload, PYTEST_COVERAGE=%PYTEST_COVERAGE%
)

View File

@ -1,8 +1,5 @@
import os
from setuptools import setup
# TODO: if py gets upgrade to >=1.6,
# remove _width_of_current_line in terminal.py
INSTALL_REQUIRES = [
@ -16,15 +13,10 @@ INSTALL_REQUIRES = [
'funcsigs>=1.0;python_version<"3.0"',
'pathlib2>=2.2.0;python_version<"3.6"',
'colorama;sys_platform=="win32"',
"pluggy>=0.9",
]
# if _PYTEST_SETUP_SKIP_PLUGGY_DEP is set, skip installing pluggy;
# used by tox.ini to test with pluggy master
if "_PYTEST_SETUP_SKIP_PLUGGY_DEP" not in os.environ:
INSTALL_REQUIRES.append("pluggy>=0.9")
def main():
setup(
use_scm_version={"write_to": "src/_pytest/_version.py"},
@ -33,6 +25,7 @@ def main():
# fmt: off
extras_require={
"testing": [
"argcomplete",
"hypothesis>=3.56",
"nose",
"requests",

View File

@ -12,7 +12,6 @@ import os
import six
DEFAULT_MAX_LINES = 8
DEFAULT_MAX_CHARS = 8 * 80
USAGE_MSG = "use '-vv' to show"

View File

@ -17,6 +17,7 @@ from tempfile import TemporaryFile
import six
import pytest
from _pytest.compat import _PY3
from _pytest.compat import CaptureIO
patchsysdict = {0: "stdin", 1: "stdout", 2: "stderr"}
@ -412,6 +413,10 @@ class EncodedFile(object):
def write(self, obj):
if isinstance(obj, six.text_type):
obj = obj.encode(self.encoding, "replace")
elif _PY3:
raise TypeError(
"write() argument must be str, not {}".format(type(obj).__name__)
)
self.buffer.write(obj)
def writelines(self, linelist):

View File

@ -16,7 +16,6 @@ from _pytest.warning_types import PytestDeprecationWarning
from _pytest.warning_types import RemovedInPytest4Warning
from _pytest.warning_types import UnformattedWarning
YIELD_TESTS = "yield tests were removed in pytest 4.0 - {name} will be ignored"

View File

@ -3,7 +3,6 @@ from pluggy import HookspecMarker
from _pytest.deprecated import PYTEST_LOGWARNING
hookspec = HookspecMarker("pytest")
# -------------------------------------------------------------------------

View File

@ -15,7 +15,6 @@ from _pytest.compat import dummy_context_manager
from _pytest.config import create_terminal_writer
from _pytest.pathlib import Path
DEFAULT_LOG_FORMAT = "%(filename)-25s %(lineno)4d %(levelname)-8s %(message)s"
DEFAULT_LOG_DATE_FORMAT = "%H:%M:%S"

View File

@ -24,7 +24,6 @@ from _pytest.deprecated import PYTEST_CONFIG_GLOBAL
from _pytest.outcomes import exit
from _pytest.runner import collect_one_node
# exitcodes for the command line
EXIT_OK = 0
EXIT_TESTSFAILED = 1

View File

@ -12,7 +12,6 @@ from ..compat import MappingMixin
from ..compat import NOTSET
from _pytest.outcomes import fail
EMPTY_PARAMETERSET_OPTION = "empty_parameter_set_mark"

View File

@ -19,7 +19,6 @@ from six.moves import map
from .compat import PY36
if PY36:
from pathlib import Path, PurePath
else:

View File

@ -16,7 +16,6 @@ import _pytest._code
import pytest
from _pytest._code import Source
astonly = pytest.mark.nothing
failsonjython = pytest.mark.xfail("sys.platform.startswith('java')")

View File

@ -1,7 +1,6 @@
import argparse
import pathlib
HERE = pathlib.Path(__file__).parent
TEST_CONTENT = (HERE / "template_test.py").read_bytes()

View File

@ -1313,8 +1313,7 @@ class TestEarlyRewriteBailout(object):
# always (previously triggered via xdist only).
# Ref: https://github.com/pytest-dev/py/pull/207
monkeypatch.setattr(sys, "path", [""] + sys.path)
if "pathlib" in sys.modules:
del sys.modules["pathlib"]
monkeypatch.delitem(sys.modules, "pathlib", raising=False)
testdir.makepyfile(
**{

View File

@ -18,6 +18,7 @@ from six import text_type
import pytest
from _pytest import capture
from _pytest.capture import CaptureManager
from _pytest.compat import _PY3
from _pytest.main import EXIT_NOTESTSCOLLECTED
# note: py.io capture tests where copied from
@ -1402,28 +1403,36 @@ def test_dontreadfrominput_has_encoding(testdir):
def test_crash_on_closing_tmpfile_py27(testdir):
testdir.makepyfile(
p = testdir.makepyfile(
"""
from __future__ import print_function
import time
import threading
import sys
printing = threading.Event()
def spam():
f = sys.stderr
while True:
print('.', end='', file=f)
print('SPAMBEFORE', end='', file=f)
printing.set()
def test_silly():
while True:
try:
f.flush()
except (OSError, ValueError):
break
def test_spam_in_thread():
t = threading.Thread(target=spam)
t.daemon = True
t.start()
time.sleep(0.5)
printing.wait()
"""
)
result = testdir.runpytest_subprocess()
result = testdir.runpytest_subprocess(str(p))
assert result.ret == 0
assert result.stderr.str() == ""
assert "IOError" not in result.stdout.str()
@ -1526,3 +1535,26 @@ def test_capture_with_live_logging(testdir, capture_fixture):
result = testdir.runpytest_subprocess("--log-cli-level=INFO")
assert result.ret == 0
def test_typeerror_encodedfile_write(testdir):
"""It should behave the same with and without output capturing (#4861)."""
p = testdir.makepyfile(
"""
def test_fails():
import sys
sys.stdout.write(b"foo")
"""
)
result_without_capture = testdir.runpytest("-s", str(p))
result_with_capture = testdir.runpytest(str(p))
assert result_with_capture.ret == result_without_capture.ret
if _PY3:
result_with_capture.stdout.fnmatch_lines(
["E TypeError: write() argument must be str, not bytes"]
)
else:
assert result_with_capture.ret == 0

View File

@ -299,15 +299,12 @@ def test_argcomplete(testdir, monkeypatch):
if not distutils.spawn.find_executable("bash"):
pytest.skip("bash not available")
script = str(testdir.tmpdir.join("test_argcomplete"))
pytest_bin = sys.argv[0]
if "pytest" not in os.path.basename(pytest_bin):
pytest.skip("need to be run with pytest executable, not {}".format(pytest_bin))
with open(str(script), "w") as fp:
# redirect output from argcomplete to stdin and stderr is not trivial
# http://stackoverflow.com/q/12589419/1307905
# so we use bash
fp.write('COMP_WORDBREAKS="$COMP_WORDBREAKS" %s 8>&1 9>&2' % pytest_bin)
fp.write('COMP_WORDBREAKS="$COMP_WORDBREAKS" python -m pytest 8>&1 9>&2')
# alternative would be exteneded Testdir.{run(),_run(),popen()} to be able
# to handle a keyword argument env that replaces os.environ in popen or
# extends the copy, advantage: could not forget to restore
@ -323,7 +320,11 @@ def test_argcomplete(testdir, monkeypatch):
# argcomplete not found
pytest.skip("argcomplete not available")
elif not result.stdout.str():
pytest.skip("bash provided no output, argcomplete not available?")
pytest.skip(
"bash provided no output on stdout, argcomplete not available? (stderr={!r})".format(
result.stderr.str()
)
)
else:
result.stdout.fnmatch_lines(["--funcargs", "--fulltrace"])
os.mkdir("test_argcomplete.d")

View File

@ -12,7 +12,6 @@ from _pytest.resultlog import pytest_configure
from _pytest.resultlog import pytest_unconfigure
from _pytest.resultlog import ResultLog
pytestmark = pytest.mark.filterwarnings("ignore:--result-log is deprecated")

View File

@ -8,7 +8,6 @@ import six
import pytest
WARNINGS_SUMMARY_HEADER = "warnings summary"

77
tox.ini
View File

@ -14,30 +14,43 @@ envlist =
pypy
pypy3
{py27,py37}-{pexpect,xdist,trial,numpy,pluggymaster}
py27-nobyte
py27-nobyte-xdist
doctesting
py37-freeze
docs
[testenv]
commands =
{env:_PYTEST_TOX_COVERAGE_RUN:} pytest {env:_PYTEST_TOX_ARGS:} {posargs}
{env:_PYTEST_TOX_COVERAGE_RUN:} pytest {posargs:{env:_PYTEST_TOX_DEFAULT_POSARGS:}}
coverage: coverage combine
coverage: coverage report
passenv = USER USERNAME COVERAGE_* TRAVIS PYTEST_ADDOPTS
setenv =
_PYTEST_TOX_ARGS=--lsof
_PYTEST_TOX_DEFAULT_POSARGS={env:_PYTEST_TOX_POSARGS_LSOF:} {env:_PYTEST_TOX_POSARGS_PEXPECT:} {env:_PYTEST_TOX_POSARGS_XDIST:}
# Configuration to run with coverage similar to Travis/Appveyor, e.g.
# "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
coverage: COVERAGE_PROCESS_START={toxinidir}/.coveragerc
xdist: _PYTEST_TOX_ARGS={env:_PYTEST_TOX_ARGS:-n auto}
nobyte: PYTHONDONTWRITEBYTECODE=1
lsof: _PYTEST_TOX_POSARGS_LSOF=--lsof
pexpect: _PYTEST_TOX_PLATFORM=linux|darwin
pexpect: _PYTEST_TOX_POSARGS_PEXPECT=testing/test_pdb.py testing/test_terminal.py testing/test_unittest.py
xdist: _PYTEST_TOX_POSARGS_XDIST=-n auto
extras = testing
deps =
numpy: numpy
pexpect: pexpect
pluggymaster: git+https://github.com/pytest-dev/pluggy.git@master
xdist: pytest-xdist>=1.13
{env:_PYTEST_TOX_EXTRA_DEP:}
platform = {env:_PYTEST_TOX_PLATFORM:.*}
[testenv:py27-subprocess]
deps =
@ -54,31 +67,6 @@ basepython = python3
deps = pre-commit>=1.11.0
commands = pre-commit run --all-files --show-diff-on-failure
[testenv:py27-pexpect]
platform = linux|darwin
deps =
{[testenv]deps}
pexpect
commands =
{env:_PYTEST_TOX_COVERAGE_RUN:} pytest {posargs:testing/test_pdb.py testing/test_terminal.py testing/test_unittest.py}
[testenv:py37-pexpect]
platform = {[testenv:py27-pexpect]platform}
deps = {[testenv:py27-pexpect]deps}
commands = {[testenv:py27-pexpect]commands}
[testenv:py27-nobyte]
extras = testing
deps =
{[testenv]deps}
pytest-xdist>=1.13
distribute = true
setenv =
{[testenv]setenv}
PYTHONDONTWRITEBYTECODE=1
commands =
{env:_PYTEST_TOX_COVERAGE_RUN:} pytest -n auto {posargs}
[testenv:py27-trial]
deps =
{[testenv]deps}
@ -91,29 +79,6 @@ commands =
deps = {[testenv:py27-trial]deps}
commands = {[testenv:py27-trial]commands}
[testenv:py27-numpy]
deps =
{[testenv]deps}
numpy
commands=
{env:_PYTEST_TOX_COVERAGE_RUN:} pytest {posargs:testing/python/approx.py}
[testenv:py37-numpy]
deps = {[testenv:py27-numpy]deps}
commands = {[testenv:py27-numpy]commands}
[testenv:py27-pluggymaster]
setenv=
{[testenv]setenv}
_PYTEST_SETUP_SKIP_PLUGGY_DEP=1
deps =
{[testenv]deps}
git+https://github.com/pytest-dev/pluggy.git@master
[testenv:py37-pluggymaster]
setenv = {[testenv:py27-pluggymaster]setenv}
deps = {[testenv:py27-pluggymaster]deps}
[testenv:docs]
basepython = python3
skipsdist = True
@ -211,6 +176,14 @@ filterwarnings =
# Do not cause SyntaxError for invalid escape sequences in py37.
default:invalid escape sequence:DeprecationWarning
pytester_example_dir = testing/example_scripts
[flake8]
max-line-length = 120
ignore = E203,W503
[isort]
; This config mimics what reorder-python-imports does.
force_single_line = 1
known_localfolder = pytest,_pytest
known_third_party = test_source,test_excinfo
force_alphabetical_sort_within_sections = 1