Merge pull request #4887 from blueyed/merge-master-into-features
Merge master into features
This commit is contained in:
commit
4668ee03f6
15
.coveragerc
15
.coveragerc
|
@ -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\
|
||||
|
|
121
.travis.yml
121
.travis.yml
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
48
appveyor.yml
48
appveyor.yml
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -2,7 +2,6 @@ from six.moves import range
|
|||
|
||||
import pytest
|
||||
|
||||
|
||||
SKIP = True
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Improve validation of contents written to captured output so it behaves the same as when capture is disabled.
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
~~~~~~
|
||||
|
||||
|
|
|
@ -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
|
||||
--------------------
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
)
|
|
@ -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%
|
||||
)
|
|
@ -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%
|
||||
)
|
||||
|
|
11
setup.py
11
setup.py
|
@ -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",
|
||||
|
|
|
@ -12,7 +12,6 @@ import os
|
|||
|
||||
import six
|
||||
|
||||
|
||||
DEFAULT_MAX_LINES = 8
|
||||
DEFAULT_MAX_CHARS = 8 * 80
|
||||
USAGE_MSG = "use '-vv' to show"
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ from pluggy import HookspecMarker
|
|||
|
||||
from _pytest.deprecated import PYTEST_LOGWARNING
|
||||
|
||||
|
||||
hookspec = HookspecMarker("pytest")
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -12,7 +12,6 @@ from ..compat import MappingMixin
|
|||
from ..compat import NOTSET
|
||||
from _pytest.outcomes import fail
|
||||
|
||||
|
||||
EMPTY_PARAMETERSET_OPTION = "empty_parameter_set_mark"
|
||||
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ from six.moves import map
|
|||
|
||||
from .compat import PY36
|
||||
|
||||
|
||||
if PY36:
|
||||
from pathlib import Path, PurePath
|
||||
else:
|
||||
|
|
|
@ -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')")
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import argparse
|
||||
import pathlib
|
||||
|
||||
|
||||
HERE = pathlib.Path(__file__).parent
|
||||
TEST_CONTENT = (HERE / "template_test.py").read_bytes()
|
||||
|
||||
|
|
|
@ -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(
|
||||
**{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import six
|
|||
|
||||
import pytest
|
||||
|
||||
|
||||
WARNINGS_SUMMARY_HEADER = "warnings summary"
|
||||
|
||||
|
||||
|
|
77
tox.ini
77
tox.ini
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue