Merge pull request #6432 from blueyed/merge-master-into-features

Merge master into features
This commit is contained in:
Daniel Hahler 2020-01-10 14:44:30 +01:00 committed by GitHub
commit 2d488f7615
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 512 additions and 87 deletions

123
.github/workflows/main.yml vendored Normal file
View File

@ -0,0 +1,123 @@
# evaluating GitHub actions for CI, disconsider failures when evaluating PRs
#
# this is still missing:
# - deploy
# - coverage
# - upload github notes
#
name: main
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
name: [
"windows-py35",
"windows-py36",
"windows-py37",
"windows-py37-pluggy",
"windows-py38",
"ubuntu-py35",
"ubuntu-py36",
"ubuntu-py37",
"ubuntu-py37-pluggy",
"ubuntu-py37-freeze",
"ubuntu-py38",
"ubuntu-pypy3",
"macos-py37",
"macos-py38",
"linting",
]
include:
- name: "windows-py35"
python: "3.5"
os: windows-latest
tox_env: "py35-xdist"
- name: "windows-py36"
python: "3.6"
os: windows-latest
tox_env: "py36-xdist"
- name: "windows-py37"
python: "3.7"
os: windows-latest
tox_env: "py37-twisted-numpy"
- name: "windows-py37-pluggy"
python: "3.7"
os: windows-latest
tox_env: "py37-pluggymaster-xdist"
- name: "windows-py38"
python: "3.8"
os: windows-latest
tox_env: "py38"
- name: "ubuntu-py35"
python: "3.5"
os: ubuntu-latest
tox_env: "py35-xdist"
- name: "ubuntu-py36"
python: "3.6"
os: ubuntu-latest
tox_env: "py36-xdist"
- name: "ubuntu-py37"
python: "3.7"
os: ubuntu-latest
tox_env: "py37-lsof-numpy-oldattrs-pexpect-twisted"
- name: "ubuntu-py37-pluggy"
python: "3.7"
os: ubuntu-latest
tox_env: "py37-pluggymaster-xdist"
- name: "ubuntu-py37-freeze"
python: "3.7"
os: ubuntu-latest
tox_env: "py37-freeze"
- name: "ubuntu-py38"
python: "3.8"
os: ubuntu-latest
tox_env: "py38-xdist"
- name: "ubuntu-pypy3"
python: "pypy3"
os: ubuntu-latest
tox_env: "pypy3-xdist"
- name: "macos-py37"
python: "3.7"
os: macos-latest
tox_env: "py37-xdist"
- name: "macos-py38"
python: "3.8"
os: macos-latest
tox_env: "py38-xdist"
- name: "linting"
python: "3.7"
os: ubuntu-latest
tox_env: "linting,docs,doctesting"
steps:
- uses: actions/checkout@v1
- name: Set up Python ${{ matrix.python }}
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install tox
- name: Test
run: tox -e ${{ matrix.tox_env }}

View File

@ -8,7 +8,7 @@ repos:
rev: v1.0.0 rev: v1.0.0
hooks: hooks:
- id: blacken-docs - id: blacken-docs
additional_dependencies: [black==19.3b0] additional_dependencies: [black==19.10b0]
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.2.3 rev: v2.2.3
hooks: hooks:

View File

@ -80,9 +80,9 @@ jobs:
addons: addons:
apt: apt:
packages: packages:
# required by publish_gh_release_notes # required by publish-gh-release-notes
- pandoc - pandoc
after_deploy: tox -e publish_gh_release_notes after_deploy: tox -e publish-gh-release-notes
deploy: deploy:
provider: pypi provider: pypi
user: nicoddemus user: nicoddemus

View File

@ -238,6 +238,7 @@ Samuele Pedroni
Sankt Petersbug Sankt Petersbug
Segev Finer Segev Finer
Serhii Mozghovyi Serhii Mozghovyi
Seth Junot
Simon Gomizelj Simon Gomizelj
Skylar Downes Skylar Downes
Srinivas Reddy Thatiparthy Srinivas Reddy Thatiparthy

View File

@ -51,7 +51,8 @@ Fix bugs
Look through the `GitHub issues for bugs <https://github.com/pytest-dev/pytest/labels/type:%20bug>`_. Look through the `GitHub issues for bugs <https://github.com/pytest-dev/pytest/labels/type:%20bug>`_.
:ref:`Talk <contact>` to developers to find out how you can fix specific bugs. :ref:`Talk <contact>` to developers to find out how you can fix specific bugs. To indicate that you are going
to work on a particular issue, add a comment to that effect on the specific issue.
Don't forget to check the issue trackers of your favourite plugins, too! Don't forget to check the issue trackers of your favourite plugins, too!

View File

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2004-2019 Holger Krekel and others Copyright (c) 2004-2020 Holger Krekel and others
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in

View File

@ -112,12 +112,12 @@ Support pytest
-------------- --------------
`Open Collective`_ is an online funding platform for open and transparent communities. `Open Collective`_ is an online funding platform for open and transparent communities.
It provide tools to raise money and share your finances in full transparency. It provides tools to raise money and share your finances in full transparency.
It is the platform of choice for individuals and companies that want to make one-time or It is the platform of choice for individuals and companies that want to make one-time or
monthly donations directly to the project. monthly donations directly to the project.
See more datails in the `pytest collective`_. See more details in the `pytest collective`_.
.. _Open Collective: https://opencollective.com .. _Open Collective: https://opencollective.com
.. _pytest collective: https://opencollective.com/pytest .. _pytest collective: https://opencollective.com/pytest
@ -145,7 +145,7 @@ Tidelift will coordinate the fix and disclosure.
License License
------- -------
Copyright Holger Krekel and others, 2004-2019. Copyright Holger Krekel and others, 2004-2020.
Distributed under the terms of the `MIT`_ license, pytest is free and open source software. Distributed under the terms of the `MIT`_ license, pytest is free and open source software.

View File

@ -39,6 +39,9 @@ jobs:
py37-pluggymaster-xdist: py37-pluggymaster-xdist:
python.version: '3.7' python.version: '3.7'
tox.env: 'py37-pluggymaster-xdist' tox.env: 'py37-pluggymaster-xdist'
py38-xdist:
python.version: '3.8'
tox.env: 'py38-xdist'
maxParallel: 10 maxParallel: 10
steps: steps:

View File

@ -0,0 +1,2 @@
Fix a ``pytest-xdist`` crash when dealing with exceptions raised in subprocesses created by the
``multiprocessing`` module.

View File

@ -0,0 +1 @@
Optimized automatic renaming of test parameter IDs.

View File

@ -0,0 +1 @@
Fix parsing of outcomes containing multiple errors with ``testdir`` results (regression in 5.3.0).

View File

@ -20,6 +20,10 @@ Release announcements
release-5.1.0 release-5.1.0
release-5.0.1 release-5.0.1
release-5.0.0 release-5.0.0
release-4.6.9
release-4.6.8
release-4.6.7
release-4.6.6
release-4.6.5 release-4.6.5
release-4.6.4 release-4.6.4
release-4.6.3 release-4.6.3

View File

@ -3,13 +3,13 @@ pytest-2.3: improved fixtures / better unittest integration
pytest-2.3 comes with many major improvements for fixture/funcarg management pytest-2.3 comes with many major improvements for fixture/funcarg management
and parametrized testing in Python. It is now easier, more efficient and and parametrized testing in Python. It is now easier, more efficient and
more predicatable to re-run the same tests with different fixture more predictable to re-run the same tests with different fixture
instances. Also, you can directly declare the caching "scope" of instances. Also, you can directly declare the caching "scope" of
fixtures so that dependent tests throughout your whole test suite can fixtures so that dependent tests throughout your whole test suite can
re-use database or other expensive fixture objects with ease. Lastly, re-use database or other expensive fixture objects with ease. Lastly,
it's possible for fixture functions (formerly known as funcarg it's possible for fixture functions (formerly known as funcarg
factories) to use other fixtures, allowing for a completely modular and factories) to use other fixtures, allowing for a completely modular and
re-useable fixture design. re-usable fixture design.
For detailed info and tutorial-style examples, see: For detailed info and tutorial-style examples, see:

View File

@ -91,7 +91,7 @@ holger krekel
it might be the cause for other finalizers to fail. it might be the cause for other finalizers to fail.
- fix ordering when mock.patch or other standard decorator-wrappings - fix ordering when mock.patch or other standard decorator-wrappings
are used with test methods. This fixues issue346 and should are used with test methods. This fixes issue346 and should
help with random "xdist" collection failures. Thanks to help with random "xdist" collection failures. Thanks to
Ronny Pfannschmidt and Donald Stufft for helping to isolate it. Ronny Pfannschmidt and Donald Stufft for helping to isolate it.

View File

@ -35,7 +35,7 @@ holger krekel
- fix issue435: make reload() work when assert rewriting is active. - fix issue435: make reload() work when assert rewriting is active.
Thanks Daniel Hahler. Thanks Daniel Hahler.
- fix issue616: conftest.py files and their contained fixutres are now - fix issue616: conftest.py files and their contained fixtures are now
properly considered for visibility, independently from the exact properly considered for visibility, independently from the exact
current working directory and test arguments that are used. current working directory and test arguments that are used.
Many thanks to Eric Siegerman and his PR235 which contains Many thanks to Eric Siegerman and his PR235 which contains

View File

@ -0,0 +1,20 @@
pytest-4.6.6
=======================================
pytest 4.6.6 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
* Bruno Oliveira
* Michael Goerz
Happy testing,
The pytest Development Team

View File

@ -0,0 +1,19 @@
pytest-4.6.7
=======================================
pytest 4.6.7 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:
* Bruno Oliveira
* Daniel Hahler
Happy testing,
The pytest Development Team

View File

@ -0,0 +1,20 @@
pytest-4.6.8
=======================================
pytest 4.6.8 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
* Bruno Oliveira
* Ryan Mast
Happy testing,
The pytest Development Team

View File

@ -0,0 +1,21 @@
pytest-4.6.9
=======================================
pytest 4.6.9 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
* Bruno Oliveira
* Felix Yan
* Hugo
Happy testing,
The pytest Development Team

View File

@ -1,3 +1,5 @@
.. _`changelog`:
========= =========
Changelog Changelog
========= =========
@ -815,6 +817,38 @@ Improved Documentation
- `#5416 <https://github.com/pytest-dev/pytest/issues/5416>`_: Fix PytestUnknownMarkWarning in run/skip example. - `#5416 <https://github.com/pytest-dev/pytest/issues/5416>`_: Fix PytestUnknownMarkWarning in run/skip example.
pytest 4.6.9 (2020-01-04)
=========================
Bug Fixes
---------
- `#6301 <https://github.com/pytest-dev/pytest/issues/6301>`_: Fix assertion rewriting for egg-based distributions and ``editable`` installs (``pip install --editable``).
pytest 4.6.8 (2019-12-19)
=========================
Features
--------
- `#5471 <https://github.com/pytest-dev/pytest/issues/5471>`_: JUnit XML now includes a timestamp and hostname in the testsuite tag.
Bug Fixes
---------
- `#5430 <https://github.com/pytest-dev/pytest/issues/5430>`_: junitxml: Logs for failed test are now passed to junit report in case the test fails during call phase.
Trivial/Internal Changes
------------------------
- `#6345 <https://github.com/pytest-dev/pytest/issues/6345>`_: Pin ``colorama`` to ``0.4.1`` only for Python 3.4 so newer Python versions can still receive colorama updates.
pytest 4.6.7 (2019-12-05) pytest 4.6.7 (2019-12-05)
========================= =========================
@ -5343,7 +5377,7 @@ time or change existing behaviors in order to make them less surprising/more use
Thanks Ronny Pfannschmidt for most of the merging work. Thanks Ronny Pfannschmidt for most of the merging work.
- "-r" option now accepts "a" to include all possible reports, similar - "-r" option now accepts "a" to include all possible reports, similar
to passing "fEsxXw" explicitly (isse960). to passing "fEsxXw" explicitly (issue960).
Thanks Abhijeet Kasurde for the PR. Thanks Abhijeet Kasurde for the PR.
- avoid python3.5 deprecation warnings by introducing version - avoid python3.5 deprecation warnings by introducing version
@ -5633,7 +5667,7 @@ time or change existing behaviors in order to make them less surprising/more use
- fix issue435: make reload() work when assert rewriting is active. - fix issue435: make reload() work when assert rewriting is active.
Thanks Daniel Hahler. Thanks Daniel Hahler.
- fix issue616: conftest.py files and their contained fixutres are now - fix issue616: conftest.py files and their contained fixtures are now
properly considered for visibility, independently from the exact properly considered for visibility, independently from the exact
current working directory and test arguments that are used. current working directory and test arguments that are used.
Many thanks to Eric Siegerman and his PR235 which contains Many thanks to Eric Siegerman and his PR235 which contains
@ -7180,7 +7214,7 @@ Bug fixes:
- streamlined plugin loading: order is now as documented in - streamlined plugin loading: order is now as documented in
customize.html: setuptools, ENV, commandline, conftest. customize.html: setuptools, ENV, commandline, conftest.
also setuptools entry point names are turned to canonical namees ("pytest_*") also setuptools entry point names are turned to canonical names ("pytest_*")
- automatically skip tests that need 'capfd' but have no os.dup - automatically skip tests that need 'capfd' but have no os.dup

View File

@ -66,7 +66,7 @@ master_doc = "contents"
# General information about the project. # General information about the project.
project = "pytest" project = "pytest"
copyright = "20152019, holger krekel and pytest-dev team" copyright = "20152020, holger krekel and pytest-dev team"
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
@ -289,7 +289,7 @@ man_pages = [("usage", "pytest", "pytest usage", ["holger krekel at merlinux eu"
epub_title = "pytest" epub_title = "pytest"
epub_author = "holger krekel at merlinux eu" epub_author = "holger krekel at merlinux eu"
epub_publisher = "holger krekel at merlinux eu" epub_publisher = "holger krekel at merlinux eu"
epub_copyright = "2013, holger krekel et alii" epub_copyright = "2013-2020, holger krekel et alii"
# The language of the text. It defaults to the language option # The language of the text. It defaults to the language option
# or en if the language is not set. # or en if the language is not set.

View File

@ -1035,15 +1035,19 @@ file:
# content of conftest.py # content of conftest.py
import pytest
import tempfile
import os import os
import shutil
import tempfile
import pytest
@pytest.fixture() @pytest.fixture()
def cleandir(): def cleandir():
newpath = tempfile.mkdtemp() newpath = tempfile.mkdtemp()
os.chdir(newpath) os.chdir(newpath)
yield
shutil.rmtree(newpath)
and declare its use in a test module via a ``usefixtures`` marker: and declare its use in a test module via a ``usefixtures`` marker:

View File

@ -111,7 +111,7 @@ More details can be found in the `original PR <https://github.com/pytest-dev/pyt
.. note:: .. note::
in a future major relase of pytest we will introduce class based markers, in a future major release of pytest we will introduce class based markers,
at which point markers will no longer be limited to instances of :py:class:`Mark`. at which point markers will no longer be limited to instances of :py:class:`Mark`.

View File

@ -92,7 +92,7 @@ It provide tools to raise money and share your finances in full transparency.
It is the platform of choice for individuals and companies that want to make one-time or It is the platform of choice for individuals and companies that want to make one-time or
monthly donations directly to the project. monthly donations directly to the project.
See more datails in the `pytest collective`_. See more details in the `pytest collective`_.
.. _Open Collective: https://opencollective.com .. _Open Collective: https://opencollective.com
.. _pytest collective: https://opencollective.com/pytest .. _pytest collective: https://opencollective.com/pytest
@ -120,7 +120,7 @@ Tidelift will coordinate the fix and disclosure.
License License
------- -------
Copyright Holger Krekel and others, 2004-2017. Copyright Holger Krekel and others, 2004-2020.
Distributed under the terms of the `MIT`_ license, pytest is free and open source software. Distributed under the terms of the `MIT`_ license, pytest is free and open source software.

View File

@ -9,7 +9,7 @@ Distributed under the terms of the `MIT`_ license, pytest is free and open sourc
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2004-2019 Holger Krekel and others Copyright (c) 2004-2020 Holger Krekel and others
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in

View File

@ -1,31 +1,97 @@
Python 2.7 and 3.4 support plan Python 2.7 and 3.4 support
=============================== ==========================
Python 2.7 EOL is fast approaching, with It is demanding on the maintainers of an open source project to support many Python versions, as
upstream support `ending in 2020 <https://legacy.python.org/dev/peps/pep-0373/#id4>`__. there's extra cost of keeping code compatible between all versions, while holding back on
Python 3.4's last release is scheduled for features only made possible on newer Python versions.
`March 2019 <https://www.python.org/dev/peps/pep-0429/#release-schedule>`__. pytest is one of
the participating projects of the https://python3statement.org.
The **pytest 4.6** series is the last to support Python 2.7 and 3.4, and was released in In case of Python 2 and 3, the difference between the languages makes it even more prominent,
**June 2019**. **pytest 5.0** and onwards will support only Python 3.5+. because many new Python 3 features cannot be used in a Python 2/3 compatible code base.
Thanks to the `python_requires`_ ``setuptools`` option, Python 2.7 EOL has been reached `in 2020 <https://legacy.python.org/dev/peps/pep-0373/#id4>`__, with
Python 2.7 and Python 3.4 users using a modern ``pip`` version the last release planned for mid-April, 2020.
will install the last pytest ``4.6`` version automatically even if ``5.0`` or later
Python 3.4 EOL has been reached `in 2019 <https://www.python.org/dev/peps/pep-0429/#release-schedule>`__, with the last release made in March, 2019.
For those reasons, in Jun 2019 it was decided that **pytest 4.6** series will be the last to support Python 2.7 and 3.4.
What this means for general users
---------------------------------
Thanks to the `python_requires`_ setuptools option,
Python 2.7 and Python 3.4 users using a modern pip version
will install the last pytest 4.6.X version automatically even if 5.0 or later versions
are available on PyPI. are available on PyPI.
While pytest ``5.0`` will be the new mainstream and development version, until **January 2020** Users should ensure they are using the latest pip and setuptools versions for this to work.
the pytest core team plans to make bug-fix releases of the pytest ``4.6`` series by
back-porting patches to the ``4.6-maintenance`` branch that affect Python 2 users.
**After 2020**, the core team will no longer actively backport patches, but the ``4.6-maintenance`` Maintenance of 4.6.X versions
branch will continue to exist so the community itself can contribute patches. The core team will -----------------------------
be happy to accept those patches and make new ``4.6`` releases **until mid-2020**.
Until January 2020, the pytest core team ported many bug-fixes from the main release into the
``4.6-maintenance`` branch, with several 4.6.X releases being made along the year.
From now on, the core team will **no longer actively backport patches**, but the ``4.6-maintenance``
branch will continue to exist so the community itself can contribute patches.
The core team will be happy to accept those patches, and make new 4.6.X releases **until mid-2020**
(but consider that date as a ballpark, after that date the team might still decide to make new releases
for critical bugs).
.. _`python_requires`: https://packaging.python.org/guides/distributing-packages-using-setuptools/#python-requires .. _`python_requires`: https://packaging.python.org/guides/distributing-packages-using-setuptools/#python-requires
Technical Aspects Technical aspects
----------------- ~~~~~~~~~~~~~~~~~
The technical aspects of the Python 2.7 and 3.4 support plan (such as when releases will occurr, how to backport fixes, etc) is described in issue `#5275 <https://github.com/pytest-dev/pytest/issues/5275>`__. (This section is a transcript from `#5275 <https://github.com/pytest-dev/pytest/issues/5275>`__).
In this section we describe the technical aspects of the Python 2.7 and 3.4 support plan.
What goes into 4.6.X releases
+++++++++++++++++++++++++++++
New 4.6.X releases will contain bug fixes only.
When will 4.6.X releases happen
+++++++++++++++++++++++++++++++
New 4.6.X releases will happen after we have a few bugs in place to release, or if a few weeks have
passed (say a single bug has been fixed a month after the latest 4.6.X release).
No hard rules here, just ballpark.
Who will handle applying bug fixes
++++++++++++++++++++++++++++++++++
We core maintainers expect that people still using Python 2.7/3.4 and being affected by
bugs to step up and provide patches and/or port bug fixes from the active branches.
We will be happy to guide users interested in doing so, so please don't hesitate to ask.
**Backporting changes into 4.6**
Please follow these instructions:
#. ``git fetch --all --prune``
#. ``git checkout origin/4.6-maintenance -b backport-XXXX`` # use the PR number here
#. Locate the merge commit on the PR, in the *merged* message, for example:
nicoddemus merged commit 0f8b462 into pytest-dev:features
#. ``git cherry-pick -m1 REVISION`` # use the revision you found above (``0f8b462``).
#. Open a PR targeting ``4.6-maintenance``:
* Prefix the message with ``[4.6]`` so it is an obvious backport
* Delete the PR body, it usually contains a duplicate commit message.
**Providing new PRs to 4.6**
Fresh pull requests to ``4.6-maintenance`` will be accepted provided that
the equivalent code in the active branches does not contain that bug (for example, a bug is specific
to Python 2 only).
Bug fixes that also happen in the mainstream version should be first fixed
there, and then backported as per instructions above.

View File

@ -1,3 +1,5 @@
.. _`reference`:
API Reference API Reference
============= =============

View File

@ -17,7 +17,7 @@ It provide tools to raise money and share your finances in full transparency.
It is the platform of choice for individuals and companies that want to make one-time or It is the platform of choice for individuals and companies that want to make one-time or
monthly donations directly to the project. monthly donations directly to the project.
See more datails in the `pytest collective`_. See more details in the `pytest collective`_.
.. _Tidelift: https://tidelift.com .. _Tidelift: https://tidelift.com

View File

@ -198,7 +198,7 @@ the regular expression ``".*U.*mode is deprecated"``.
Ensuring code triggers a deprecation warning Ensuring code triggers a deprecation warning
-------------------------------------------- --------------------------------------------
You can also call a global helper for checking You can also use :func:`pytest.deprecated_call` for checking
that a certain function call triggers a ``DeprecationWarning`` or that a certain function call triggers a ``DeprecationWarning`` or
``PendingDeprecationWarning``: ``PendingDeprecationWarning``:
@ -207,13 +207,18 @@ that a certain function call triggers a ``DeprecationWarning`` or
import pytest import pytest
def test_global(): def test_myfunction_deprecated():
pytest.deprecated_call(myfunction, 17) with pytest.deprecated_call():
myfunction(17)
This test will fail if ``myfunction`` does not issue a deprecation warning
when called with a ``17`` argument.
By default, ``DeprecationWarning`` and ``PendingDeprecationWarning`` will not be By default, ``DeprecationWarning`` and ``PendingDeprecationWarning`` will not be
caught when using ``pytest.warns`` or ``recwarn`` because default Python warnings filters hide caught when using :func:`pytest.warns` or :ref:`recwarn <recwarn>` because
them. If you wish to record them in your own code, use the the default Python warnings filters hide
command ``warnings.simplefilter('always')``: them. If you wish to record them in your own code, use
``warnings.simplefilter('always')``:
.. code-block:: python .. code-block:: python
@ -223,19 +228,13 @@ command ``warnings.simplefilter('always')``:
def test_deprecation(recwarn): def test_deprecation(recwarn):
warnings.simplefilter("always") warnings.simplefilter("always")
warnings.warn("deprecated", DeprecationWarning) myfunction(17)
assert len(recwarn) == 1 assert len(recwarn) == 1
assert recwarn.pop(DeprecationWarning) assert recwarn.pop(DeprecationWarning)
You can also use it as a contextmanager:
.. code-block:: python
def test_global():
with pytest.deprecated_call():
myobject.deprecated_method()
The :ref:`recwarn <recwarn>` fixture automatically ensures to reset the warnings
filter at the end of the test, so no global state is leaked.
.. _`asserting warnings`: .. _`asserting warnings`:

View File

@ -6,7 +6,13 @@ This script is meant to be executed after a successful deployment in Travis.
Uses the following environment variables: Uses the following environment variables:
* GIT_TAG: the name of the tag of the current commit. * GIT_TAG: the name of the tag of the current commit.
* GH_RELEASE_NOTES_TOKEN: a personal access token with 'repo' permissions. It should be encrypted using: * GH_RELEASE_NOTES_TOKEN: a personal access token with 'repo' permissions.
Create one at:
https://github.com/settings/tokens
It should be encrypted using:
$travis encrypt GH_RELEASE_NOTES_TOKEN=<token> -r pytest-dev/pytest $travis encrypt GH_RELEASE_NOTES_TOKEN=<token> -r pytest-dev/pytest
@ -33,7 +39,7 @@ def publish_github_release(slug, token, tag_name, body):
def parse_changelog(tag_name): def parse_changelog(tag_name):
p = Path(__file__).parent.parent / "CHANGELOG.rst" p = Path(__file__).parent.parent / "doc/en/changelog.rst"
changelog_lines = p.read_text(encoding="UTF-8").splitlines() changelog_lines = p.read_text(encoding="UTF-8").splitlines()
title_regex = re.compile(r"pytest (\d\.\d+\.\d+) \(\d{4}-\d{2}-\d{2}\)") title_regex = re.compile(r"pytest (\d\.\d+\.\d+) \(\d{4}-\d{2}-\d{2}\)")

View File

@ -143,10 +143,12 @@ class AssertionRewritingHook(importlib.abc.MetaPathFinder):
exec(co, module.__dict__) exec(co, module.__dict__)
def _early_rewrite_bailout(self, name, state): def _early_rewrite_bailout(self, name, state):
"""This is a fast way to get out of rewriting modules. Profiling has """This is a fast way to get out of rewriting modules.
shown that the call to PathFinder.find_spec (inside of the find_spec
from this class) is a major slowdown, so, this method tries to Profiling has shown that the call to PathFinder.find_spec (inside of
filter what we're sure won't be rewritten before getting to it. the find_spec from this class) is a major slowdown, so, this method
tries to filter what we're sure won't be rewritten before getting to
it.
""" """
if self.session is not None and not self._session_paths_checked: if self.session is not None and not self._session_paths_checked:
self._session_paths_checked = True self._session_paths_checked = True

View File

@ -433,9 +433,14 @@ class RunResult:
for line in reversed(self.outlines): for line in reversed(self.outlines):
if rex_session_duration.search(line): if rex_session_duration.search(line):
outcomes = rex_outcome.findall(line) outcomes = rex_outcome.findall(line)
return {noun: int(count) for (count, noun) in outcomes} ret = {noun: int(count) for (count, noun) in outcomes}
break
raise ValueError("Pytest terminal summary report not found") else:
raise ValueError("Pytest terminal summary report not found")
if "errors" in ret:
assert "error" not in ret
ret["error"] = ret.pop("errors")
return ret
def assert_outcomes( def assert_outcomes(
self, self,

View File

@ -6,6 +6,7 @@ import os
import sys import sys
import warnings import warnings
from collections import Counter from collections import Counter
from collections import defaultdict
from collections.abc import Sequence from collections.abc import Sequence
from functools import partial from functools import partial
from textwrap import dedent from textwrap import dedent
@ -1244,14 +1245,23 @@ def idmaker(argnames, parametersets, idfn=None, ids=None, config=None, item=None
_idvalset(valindex, parameterset, argnames, idfn, ids, config=config, item=item) _idvalset(valindex, parameterset, argnames, idfn, ids, config=config, item=item)
for valindex, parameterset in enumerate(parametersets) for valindex, parameterset in enumerate(parametersets)
] ]
if len(set(ids)) != len(ids):
# The ids are not unique # All IDs must be unique!
duplicates = [testid for testid in ids if ids.count(testid) > 1] unique_ids = set(ids)
counters = Counter() if len(unique_ids) != len(ids):
for index, testid in enumerate(ids):
if testid in duplicates: # Record the number of occurrences of each test ID
ids[index] = testid + str(counters[testid]) test_id_counts = Counter(ids)
counters[testid] += 1
# Map the test ID to its next suffix
test_id_suffixes = defaultdict(int)
# Suffix non-unique IDs to make them unique
for index, test_id in enumerate(ids):
if test_id_counts[test_id] > 1:
ids[index] = "{}{}".format(test_id, test_id_suffixes[test_id])
test_id_suffixes[test_id] += 1
return ids return ids

View File

@ -374,8 +374,11 @@ def _report_to_json(report):
] ]
return result return result
def serialize_repr_crash(reprcrash): def serialize_repr_crash(reprcrash: Optional[ReprFileLocation]):
return reprcrash.__dict__.copy() if reprcrash is not None:
return reprcrash.__dict__.copy()
else:
return None
def serialize_longrepr(rep): def serialize_longrepr(rep):
result = { result = {
@ -455,8 +458,11 @@ def _report_kwargs_from_json(reportdict):
] ]
return ReprTraceback(**repr_traceback_dict) return ReprTraceback(**repr_traceback_dict)
def deserialize_repr_crash(repr_crash_dict): def deserialize_repr_crash(repr_crash_dict: Optional[dict]):
return ReprFileLocation(**repr_crash_dict) if repr_crash_dict is not None:
return ReprFileLocation(**repr_crash_dict)
else:
return None
if ( if (
reportdict["longrepr"] reportdict["longrepr"]

View File

@ -676,3 +676,25 @@ def test_run_result_repr():
repr(r) == "<RunResult ret=99 len(stdout.lines)=3" repr(r) == "<RunResult ret=99 len(stdout.lines)=3"
" len(stderr.lines)=4 duration=0.50s>" " len(stderr.lines)=4 duration=0.50s>"
) )
def test_testdir_outcomes_with_multiple_errors(testdir):
p1 = testdir.makepyfile(
"""
import pytest
@pytest.fixture
def bad_fixture():
raise Exception("bad")
def test_error1(bad_fixture):
pass
def test_error2(bad_fixture):
pass
"""
)
result = testdir.runpytest(str(p1))
result.assert_outcomes(error=2)
assert result.parseoutcomes() == {"error": 2}

View File

@ -305,6 +305,8 @@ class TestReportSerialization:
data = report._to_json() data = report._to_json()
loaded_report = report_class._from_json(data) loaded_report = report_class._from_json(data)
assert loaded_report.failed
check_longrepr(loaded_report.longrepr) check_longrepr(loaded_report.longrepr)
# make sure we don't blow up on ``toterminal`` call; we don't test the actual output because it is very # make sure we don't blow up on ``toterminal`` call; we don't test the actual output because it is very
@ -312,6 +314,60 @@ class TestReportSerialization:
# elsewhere and we do check the contents of the longrepr object after loading it. # elsewhere and we do check the contents of the longrepr object after loading it.
loaded_report.longrepr.toterminal(tw_mock) loaded_report.longrepr.toterminal(tw_mock)
def test_chained_exceptions_no_reprcrash(
self, testdir, tw_mock,
):
"""Regression test for tracebacks without a reprcrash (#5971)
This happens notably on exceptions raised by multiprocess.pool: the exception transfer
from subprocess to main process creates an artificial exception, which ExceptionInfo
can't obtain the ReprFileLocation from.
"""
testdir.makepyfile(
"""
from concurrent.futures import ProcessPoolExecutor
def func():
raise ValueError('value error')
def test_a():
with ProcessPoolExecutor() as p:
p.submit(func).result()
"""
)
reprec = testdir.inline_run()
reports = reprec.getreports("pytest_runtest_logreport")
def check_longrepr(longrepr):
assert isinstance(longrepr, ExceptionChainRepr)
assert len(longrepr.chain) == 2
entry1, entry2 = longrepr.chain
tb1, fileloc1, desc1 = entry1
tb2, fileloc2, desc2 = entry2
assert "RemoteTraceback" in str(tb1)
assert "ValueError: value error" in str(tb2)
assert fileloc1 is None
assert fileloc2.message == "ValueError: value error"
# 3 reports: setup/call/teardown: get the call report
assert len(reports) == 3
report = reports[1]
assert report.failed
check_longrepr(report.longrepr)
data = report._to_json()
loaded_report = TestReport._from_json(data)
assert loaded_report.failed
check_longrepr(loaded_report.longrepr)
# for same reasons as previous test, ensure we don't blow up here
loaded_report.longrepr.toterminal(tw_mock)
class TestHooks: class TestHooks:
"""Test that the hooks are working correctly for plugins""" """Test that the hooks are working correctly for plugins"""

View File

@ -468,10 +468,7 @@ reporttypes = [reports.BaseReport, reports.TestReport, reports.CollectReport]
"reporttype", reporttypes, ids=[x.__name__ for x in reporttypes] "reporttype", reporttypes, ids=[x.__name__ for x in reporttypes]
) )
def test_report_extra_parameters(reporttype): def test_report_extra_parameters(reporttype):
if hasattr(inspect, "signature"): args = list(inspect.signature(reporttype.__init__).parameters.keys())[1:]
args = list(inspect.signature(reporttype.__init__).parameters.keys())[1:]
else:
args = inspect.getargspec(reporttype.__init__)[0][1:]
basekw = dict.fromkeys(args, []) basekw = dict.fromkeys(args, [])
report = reporttype(newthing=1, **basekw) report = reporttype(newthing=1, **basekw)
assert report.newthing == 1 assert report.newthing == 1

View File

@ -127,7 +127,7 @@ deps =
towncrier towncrier
commands = python scripts/release.py {posargs} commands = python scripts/release.py {posargs}
[testenv:publish_gh_release_notes] [testenv:publish-gh-release-notes]
description = create GitHub release after deployment description = create GitHub release after deployment
basepython = python3 basepython = python3
usedevelop = True usedevelop = True
@ -135,7 +135,7 @@ passenv = GH_RELEASE_NOTES_TOKEN TRAVIS_TAG TRAVIS_REPO_SLUG
deps = deps =
github3.py github3.py
pypandoc pypandoc
commands = python scripts/publish_gh_release_notes.py commands = python scripts/publish-gh-release-notes.py {posargs}
[pytest] [pytest]