commit
39066d5a42
|
@ -18,6 +18,26 @@ with advance notice in the **Deprecations** section of releases.
|
|||
|
||||
.. 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)
|
||||
=========================
|
||||
|
||||
|
|
22
README.rst
22
README.rst
|
@ -111,14 +111,28 @@ Consult the `Changelog <https://docs.pytest.org/en/latest/changelog.html>`__ pag
|
|||
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,
|
||||
with professional grade assurances from the experts who know it best, while seamlessly integrating with existing tools.
|
||||
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
|
||||
|
||||
|
||||
.. _`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
|
||||
^^^^^^^^
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Fix crash with ``KeyboardInterrupt`` during ``--setup-show``.
|
|
@ -1 +0,0 @@
|
|||
Fixed issue when parametrizing fixtures with numpy arrays (and possibly other sequence-like types).
|
|
@ -12,6 +12,7 @@
|
|||
<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('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('contact') }}">Contact Channels</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -6,6 +6,7 @@ Release announcements
|
|||
:maxdepth: 2
|
||||
|
||||
|
||||
release-5.2.2
|
||||
release-5.2.1
|
||||
release-5.2.0
|
||||
release-5.1.3
|
||||
|
|
|
@ -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
|
|
@ -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::
|
||||
|
||||
* caplog.messages -> list of format-interpolated log messages
|
||||
* caplog.text -> string containing formatted log output
|
||||
* caplog.records -> list of logging.LogRecord instances
|
||||
* caplog.record_tuples -> list of (logger_name, level, message) tuples
|
||||
|
|
|
@ -277,7 +277,60 @@ You can always peek at the content of the cache using the
|
|||
'test_caching.py::test_function': True,
|
||||
'test_foocompare.py::test_compare': True}
|
||||
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:
|
||||
[]
|
||||
example/value contains:
|
||||
|
|
|
@ -38,19 +38,24 @@ Full pytest documentation
|
|||
customize
|
||||
example/index
|
||||
bash-completion
|
||||
faq
|
||||
|
||||
backwards-compatibility
|
||||
deprecations
|
||||
py27-py34-deprecation
|
||||
historical-notes
|
||||
license
|
||||
|
||||
contributing
|
||||
development_guide
|
||||
|
||||
sponsor
|
||||
tidelift
|
||||
license
|
||||
contact
|
||||
|
||||
historical-notes
|
||||
talks
|
||||
projects
|
||||
faq
|
||||
contact
|
||||
sponsor
|
||||
|
||||
|
||||
.. only:: html
|
||||
|
||||
|
|
|
@ -83,6 +83,39 @@ Changelog
|
|||
|
||||
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
|
||||
-------
|
||||
|
|
|
@ -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)
|
||||
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
|
||||
--------------
|
||||
|
||||
|
@ -32,7 +20,6 @@ monthly donations directly to the project.
|
|||
See more datails in the `pytest collective`_.
|
||||
|
||||
|
||||
|
||||
.. _Tidelift: https://tidelift.com
|
||||
.. _Tidelift subscription: https://tidelift.com/subscription/pkg/pypi-pytest
|
||||
.. _Open Collective: https://opencollective.com
|
||||
|
|
|
@ -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
|
|
@ -270,8 +270,8 @@ class NFPlugin:
|
|||
def pytest_collection_modifyitems(
|
||||
self, session: Session, config: Config, items: List[nodes.Item]
|
||||
) -> None:
|
||||
new_items = OrderedDict() # type: OrderedDict[str, nodes.Item]
|
||||
if self.active:
|
||||
new_items = OrderedDict() # type: OrderedDict[str, nodes.Item]
|
||||
other_items = OrderedDict() # type: OrderedDict[str, nodes.Item]
|
||||
for item in items:
|
||||
if item.nodeid not in self.cached_nodeids:
|
||||
|
@ -282,7 +282,11 @@ class NFPlugin:
|
|||
items[:] = self._get_increasing_order(
|
||||
new_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):
|
||||
return sorted(items, key=lambda item: item.fspath.mtime(), reverse=True)
|
||||
|
|
|
@ -38,21 +38,35 @@ def ensure_reset_dir(path):
|
|||
path.mkdir()
|
||||
|
||||
|
||||
def on_rm_rf_error(func, path: str, exc, *, start_path):
|
||||
"""Handles known read-only errors during rmtree."""
|
||||
excvalue = exc[1]
|
||||
def on_rm_rf_error(func, path: str, exc, *, start_path) -> bool:
|
||||
"""Handles known read-only errors during rmtree.
|
||||
|
||||
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):
|
||||
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):
|
||||
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.
|
||||
import stat
|
||||
|
@ -73,6 +87,7 @@ def on_rm_rf_error(func, path: str, exc, *, start_path):
|
|||
chmod_rw(str(path))
|
||||
|
||||
func(path)
|
||||
return True
|
||||
|
||||
|
||||
def rm_rf(path: Path):
|
||||
|
|
|
@ -982,8 +982,13 @@ class TestNewFirst:
|
|||
)
|
||||
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(
|
||||
[
|
||||
"*test_1/test_1.py::test_1[3*",
|
||||
|
|
|
@ -383,6 +383,10 @@ class TestRmRf:
|
|||
on_rm_rf_error(os.unlink, str(fn), exc_info, start_path=tmp_path)
|
||||
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
|
||||
with pytest.warns(pytest.PytestWarning):
|
||||
exc_info = (None, PermissionError(), None)
|
||||
|
|
Loading…
Reference in New Issue