Merge remote-tracking branch 'upstream/master' into mm

Conflicts:
- 	src/_pytest/cacheprovider.py
This commit is contained in:
Bruno Oliveira 2019-10-24 21:13:43 -03:00
commit fb0e8b99d1
17 changed files with 250 additions and 35 deletions

View File

@ -18,6 +18,26 @@ with advance notice in the **Deprecations** section of releases.
.. towncrier release notes start .. towncrier release notes start
pytest 5.2.2 (2019-10-24)
=========================
Bug Fixes
---------
- `#5206 <https://github.com/pytest-dev/pytest/issues/5206>`_: Fix ``--nf`` to not forget about known nodeids with partial test selection.
- `#5906 <https://github.com/pytest-dev/pytest/issues/5906>`_: Fix crash with ``KeyboardInterrupt`` during ``--setup-show``.
- `#5946 <https://github.com/pytest-dev/pytest/issues/5946>`_: Fixed issue when parametrizing fixtures with numpy arrays (and possibly other sequence-like types).
- `#6044 <https://github.com/pytest-dev/pytest/issues/6044>`_: Properly ignore ``FileNotFoundError`` exceptions when trying to remove old temporary directories,
for instance when multiple processes try to remove the same directory (common with ``pytest-xdist``
for example).
pytest 5.2.1 (2019-10-06) pytest 5.2.1 (2019-10-06)
========================= =========================

View File

@ -111,14 +111,28 @@ Consult the `Changelog <https://docs.pytest.org/en/latest/changelog.html>`__ pag
Support pytest Support pytest
-------------- --------------
You can support pytest by obtaining a `Tidelift subscription`_. `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.
Tidelift gives software development teams a single source for purchasing and maintaining their software, It is the platform of choice for individuals and companies that want to make one-time or
with professional grade assurances from the experts who know it best, while seamlessly integrating with existing tools. monthly donations directly to the project.
See more datails in the `pytest collective`_.
.. _Open Collective: https://opencollective.com
.. _pytest collective: https://opencollective.com/pytest
.. _`Tidelift subscription`: https://tidelift.com/subscription/pkg/pypi-pytest?utm_source=pypi-pytest&utm_medium=referral&utm_campaign=readme pytest for enterprise
---------------------
Available as part of the Tidelift Subscription.
The maintainers of pytest and thousands of other packages are working with Tidelift to deliver commercial support and
maintenance for the open source dependencies you use to build your applications.
Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use.
`Learn more. <https://tidelift.com/subscription/pkg/pypi-pytest?utm_source=pypi-pytest&utm_medium=referral&utm_campaign=enterprise&utm_term=repo>`_
Security Security
^^^^^^^^ ^^^^^^^^

View File

@ -1 +0,0 @@
Fix crash with ``KeyboardInterrupt`` during ``--setup-show``.

View File

@ -1 +0,0 @@
Fixed issue when parametrizing fixtures with numpy arrays (and possibly other sequence-like types).

View File

@ -12,6 +12,7 @@
<li><a href="{{ pathto('backwards-compatibility') }}">Backwards Compatibility</a></li> <li><a href="{{ pathto('backwards-compatibility') }}">Backwards Compatibility</a></li>
<li><a href="{{ pathto('py27-py34-deprecation') }}">Python 2.7 and 3.4 Support</a></li> <li><a href="{{ pathto('py27-py34-deprecation') }}">Python 2.7 and 3.4 Support</a></li>
<li><a href="{{ pathto('sponsor') }}">Sponsor</a></li> <li><a href="{{ pathto('sponsor') }}">Sponsor</a></li>
<li><a href="{{ pathto('tidelift') }}">pytest for Enterprise</a></li>
<li><a href="{{ pathto('license') }}">License</a></li> <li><a href="{{ pathto('license') }}">License</a></li>
<li><a href="{{ pathto('contact') }}">Contact Channels</a></li> <li><a href="{{ pathto('contact') }}">Contact Channels</a></li>
</ul> </ul>

View File

@ -6,6 +6,7 @@ Release announcements
:maxdepth: 2 :maxdepth: 2
release-5.2.2
release-5.2.1 release-5.2.1
release-5.2.0 release-5.2.0
release-5.1.3 release-5.1.3

View File

@ -0,0 +1,29 @@
pytest-5.2.2
=======================================
pytest 5.2.2 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:
* Albert Tugushev
* Andrzej Klajnert
* Anthony Sottile
* Bruno Oliveira
* Daniel Hahler
* Florian Bruhin
* Nattaphoom Chaipreecha
* Oliver Bestwalter
* Philipp Loose
* Ran Benita
* Victor Maryama
* Yoav Caspi
Happy testing,
The pytest Development Team

View File

@ -104,6 +104,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
Captured logs are available through the following properties/methods:: Captured logs are available through the following properties/methods::
* caplog.messages -> list of format-interpolated log messages
* caplog.text -> string containing formatted log output * caplog.text -> string containing formatted log output
* caplog.records -> list of logging.LogRecord instances * caplog.records -> list of logging.LogRecord instances
* caplog.record_tuples -> list of (logger_name, level, message) tuples * caplog.record_tuples -> list of (logger_name, level, message) tuples

View File

@ -277,7 +277,60 @@ You can always peek at the content of the cache using the
'test_caching.py::test_function': True, 'test_caching.py::test_function': True,
'test_foocompare.py::test_compare': True} 'test_foocompare.py::test_compare': True}
cache/nodeids contains: cache/nodeids contains:
['test_caching.py::test_function'] ['test_assert1.py::test_function',
'test_assert2.py::test_set_comparison',
'test_foocompare.py::test_compare',
'test_50.py::test_num[0]',
'test_50.py::test_num[1]',
'test_50.py::test_num[2]',
'test_50.py::test_num[3]',
'test_50.py::test_num[4]',
'test_50.py::test_num[5]',
'test_50.py::test_num[6]',
'test_50.py::test_num[7]',
'test_50.py::test_num[8]',
'test_50.py::test_num[9]',
'test_50.py::test_num[10]',
'test_50.py::test_num[11]',
'test_50.py::test_num[12]',
'test_50.py::test_num[13]',
'test_50.py::test_num[14]',
'test_50.py::test_num[15]',
'test_50.py::test_num[16]',
'test_50.py::test_num[17]',
'test_50.py::test_num[18]',
'test_50.py::test_num[19]',
'test_50.py::test_num[20]',
'test_50.py::test_num[21]',
'test_50.py::test_num[22]',
'test_50.py::test_num[23]',
'test_50.py::test_num[24]',
'test_50.py::test_num[25]',
'test_50.py::test_num[26]',
'test_50.py::test_num[27]',
'test_50.py::test_num[28]',
'test_50.py::test_num[29]',
'test_50.py::test_num[30]',
'test_50.py::test_num[31]',
'test_50.py::test_num[32]',
'test_50.py::test_num[33]',
'test_50.py::test_num[34]',
'test_50.py::test_num[35]',
'test_50.py::test_num[36]',
'test_50.py::test_num[37]',
'test_50.py::test_num[38]',
'test_50.py::test_num[39]',
'test_50.py::test_num[40]',
'test_50.py::test_num[41]',
'test_50.py::test_num[42]',
'test_50.py::test_num[43]',
'test_50.py::test_num[44]',
'test_50.py::test_num[45]',
'test_50.py::test_num[46]',
'test_50.py::test_num[47]',
'test_50.py::test_num[48]',
'test_50.py::test_num[49]',
'test_caching.py::test_function']
cache/stepwise contains: cache/stepwise contains:
[] []
example/value contains: example/value contains:

View File

@ -38,19 +38,24 @@ Full pytest documentation
customize customize
example/index example/index
bash-completion bash-completion
faq
backwards-compatibility backwards-compatibility
deprecations deprecations
py27-py34-deprecation py27-py34-deprecation
historical-notes
license
contributing contributing
development_guide development_guide
sponsor
tidelift
license
contact
historical-notes
talks talks
projects projects
faq
contact
sponsor
.. only:: html .. only:: html

View File

@ -83,6 +83,39 @@ Changelog
Consult the :ref:`Changelog <changelog>` page for fixes and enhancements of each version. Consult the :ref:`Changelog <changelog>` page for fixes and enhancements of each version.
Support pytest
--------------
`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 is the platform of choice for individuals and companies that want to make one-time or
monthly donations directly to the project.
See more datails in the `pytest collective`_.
.. _Open Collective: https://opencollective.com
.. _pytest collective: https://opencollective.com/pytest
pytest for enterprise
---------------------
Available as part of the Tidelift Subscription.
The maintainers of pytest and thousands of other packages are working with Tidelift to deliver commercial support and
maintenance for the open source dependencies you use to build your applications.
Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use.
`Learn more. <https://tidelift.com/subscription/pkg/pypi-pytest?utm_source=pypi-pytest&utm_medium=referral&utm_campaign=enterprise&utm_term=repo>`_
Security
^^^^^^^^
pytest has never been associated with a security vunerability, but in any case, to report a
security vulnerability please use the `Tidelift security contact <https://tidelift.com/security>`_.
Tidelift will coordinate the fix and disclosure.
License License
------- -------

View File

@ -8,18 +8,6 @@ compensation when possible is welcome to justify time away from friends, family
Money is also used to fund local sprints, merchandising (stickers to distribute in conferences for example) Money is also used to fund local sprints, merchandising (stickers to distribute in conferences for example)
and every few years a large sprint involving all members. and every few years a large sprint involving all members.
If you or your company benefit from pytest and would like to contribute to the project financially,
we are members of two online donation platforms to better suit your needs.
Tidelift
--------
`Tidelift`_ aims to make Open Source sustainable by offering subscriptions to companies which rely
on Open Source packages. This subscription allows it to pay maintainers of those Open Source
packages to aid sustainability of the work.
You can help pytest and the ecosystem by obtaining a `Tidelift subscription`_.
OpenCollective OpenCollective
-------------- --------------
@ -32,7 +20,6 @@ monthly donations directly to the project.
See more datails in the `pytest collective`_. See more datails in the `pytest collective`_.
.. _Tidelift: https://tidelift.com .. _Tidelift: https://tidelift.com
.. _Tidelift subscription: https://tidelift.com/subscription/pkg/pypi-pytest .. _Tidelift subscription: https://tidelift.com/subscription/pkg/pypi-pytest
.. _Open Collective: https://opencollective.com .. _Open Collective: https://opencollective.com

45
doc/en/tidelift.rst Normal file
View File

@ -0,0 +1,45 @@
pytest for enterprise
=====================
`Tidelift`_ is working with the maintainers of pytest and thousands of other
open source projects to deliver commercial support and maintenance for the open source dependencies you use
to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the
exact dependencies you use.
`Get more details <https://tidelift.com/subscription/pkg/pypi-pytest?utm_source=pypi-pytest&utm_medium=referral&utm_campaign=enterprise>`_
The Tidelift Subscription is a managed open source subscription for application dependencies covering millions of open source projects across JavaScript, Python, Java, PHP, Ruby, .NET, and more.
Your subscription includes:
* **Security updates**
- Tidelift's security response team coordinates patches for new breaking security vulnerabilities and alerts immediately through a private channel, so your software supply chain is always secure.
* **Licensing verification and indemnification**
- Tidelift verifies license information to enable easy policy enforcement and adds intellectual property indemnification to cover creators and users in case something goes wrong. You always have a 100% up-to-date bill of materials for your dependencies to share with your legal team, customers, or partners.
* **Maintenance and code improvement**
- Tidelift ensures the software you rely on keeps working as long as you need it to work. Your managed dependencies are actively maintained and we recruit additional maintainers where required.
* **Package selection and version guidance**
- Tidelift helps you choose the best open source packages from the start—and then guide you through updates to stay on the best releases as new issues arise.
* **Roadmap input**
- Take a seat at the table with the creators behind the software you use. Tidelift's participating maintainers earn more income as their software is used by more subscribers, so they're interested in knowing what you need.
* **Tooling and cloud integration**
- Tidelift works with GitHub, GitLab, BitBucket, and every cloud platform (and other deployment targets, too).
The end result? All of the capabilities you expect from commercial-grade software, for the full breadth of open
source you use. That means less time grappling with esoteric open source trivia, and more time building your own
applications—and your business.
`Request a demo <https://tidelift.com/subscription/request-a-demo?utm_source=pypi-pytest&utm_medium=referral&utm_campaign=enterprise>`_
.. _Tidelift: https://tidelift.com

View File

@ -270,8 +270,8 @@ class NFPlugin:
def pytest_collection_modifyitems( def pytest_collection_modifyitems(
self, session: Session, config: Config, items: List[nodes.Item] self, session: Session, config: Config, items: List[nodes.Item]
) -> None: ) -> None:
new_items = OrderedDict() # type: OrderedDict[str, nodes.Item]
if self.active: if self.active:
new_items = OrderedDict() # type: OrderedDict[str, nodes.Item]
other_items = OrderedDict() # type: OrderedDict[str, nodes.Item] other_items = OrderedDict() # type: OrderedDict[str, nodes.Item]
for item in items: for item in items:
if item.nodeid not in self.cached_nodeids: if item.nodeid not in self.cached_nodeids:
@ -282,7 +282,11 @@ class NFPlugin:
items[:] = self._get_increasing_order( items[:] = self._get_increasing_order(
new_items.values() new_items.values()
) + self._get_increasing_order(other_items.values()) ) + self._get_increasing_order(other_items.values())
self.cached_nodeids = [x.nodeid for x in items if isinstance(x, pytest.Item)] else:
for item in items:
if item.nodeid not in self.cached_nodeids:
new_items[item.nodeid] = item
self.cached_nodeids.extend(new_items)
def _get_increasing_order(self, items): def _get_increasing_order(self, items):
return sorted(items, key=lambda item: item.fspath.mtime(), reverse=True) return sorted(items, key=lambda item: item.fspath.mtime(), reverse=True)

View File

@ -38,21 +38,35 @@ def ensure_reset_dir(path):
path.mkdir() path.mkdir()
def on_rm_rf_error(func, path: str, exc, *, start_path): def on_rm_rf_error(func, path: str, exc, *, start_path) -> bool:
"""Handles known read-only errors during rmtree.""" """Handles known read-only errors during rmtree.
excvalue = exc[1]
The returned value is used only by our own tests.
"""
exctype, excvalue = exc[:2]
# another process removed the file in the middle of the "rm_rf" (xdist for example)
# more context: https://github.com/pytest-dev/pytest/issues/5974#issuecomment-543799018
if isinstance(excvalue, FileNotFoundError):
return False
if not isinstance(excvalue, PermissionError): if not isinstance(excvalue, PermissionError):
warnings.warn( warnings.warn(
PytestWarning("(rm_rf) error removing {}: {}".format(path, excvalue)) PytestWarning(
"(rm_rf) error removing {}\n{}: {}".format(path, exctype, excvalue)
)
) )
return return False
if func not in (os.rmdir, os.remove, os.unlink): if func not in (os.rmdir, os.remove, os.unlink):
warnings.warn( warnings.warn(
PytestWarning("(rm_rf) error removing {}: {}".format(path, excvalue)) PytestWarning(
"(rm_rf) unknown function {} when removing {}:\n{}: {}".format(
path, func, exctype, excvalue
)
)
) )
return return False
# Chmod + retry. # Chmod + retry.
import stat import stat
@ -73,6 +87,7 @@ def on_rm_rf_error(func, path: str, exc, *, start_path):
chmod_rw(str(path)) chmod_rw(str(path))
func(path) func(path)
return True
def rm_rf(path: Path): def rm_rf(path: Path):

View File

@ -982,8 +982,13 @@ class TestNewFirst:
) )
testdir.tmpdir.join("test_1/test_1.py").setmtime(1) testdir.tmpdir.join("test_1/test_1.py").setmtime(1)
result = testdir.runpytest("-v", "--nf") # Running only a subset does not forget about existing ones.
result = testdir.runpytest("-v", "--nf", "test_2/test_2.py")
result.stdout.fnmatch_lines(
["*test_2/test_2.py::test_1[1*", "*test_2/test_2.py::test_1[2*"]
)
result = testdir.runpytest("-v", "--nf")
result.stdout.fnmatch_lines( result.stdout.fnmatch_lines(
[ [
"*test_1/test_1.py::test_1[3*", "*test_1/test_1.py::test_1[3*",

View File

@ -383,6 +383,10 @@ class TestRmRf:
on_rm_rf_error(os.unlink, str(fn), exc_info, start_path=tmp_path) on_rm_rf_error(os.unlink, str(fn), exc_info, start_path=tmp_path)
assert fn.is_file() assert fn.is_file()
# we ignore FileNotFoundError
exc_info = (None, FileNotFoundError(), None)
assert not on_rm_rf_error(None, str(fn), exc_info, start_path=tmp_path)
# unknown function # unknown function
with pytest.warns(pytest.PytestWarning): with pytest.warns(pytest.PytestWarning):
exc_info = (None, PermissionError(), None) exc_info = (None, PermissionError(), None)