Compare commits

...

23 Commits

Author SHA1 Message Date
pytest bot
09b1d7cc99 Prepare release version 6.0.2 2020-09-04 21:48:44 +00:00
Ran Benita
ea65ea877e Merge pull request #7717 from bluetech/backport-7614
[6.0.x] Properly remove log_print
2020-09-04 21:53:05 +03:00
Ran Benita
f4f30d7073 Merge pull request #7716 from bluetech/backport-7697
[6.0.x] Add missing File reference to the docs
2020-09-04 21:52:51 +03:00
Ran Benita
309810ac2c Merge pull request #7715 from bluetech/backport-7651
[6.0.x] capture: fix disabled()/global_and_fixture_disabled() enabling capturing when it was disabled
2020-09-04 21:52:29 +03:00
Bruno Oliveira
e63fac3aec Merge pull request #7614 from The-Compiler/log-print
Properly remove log_print

(cherry picked from commit d688fefecb)
2020-09-04 21:28:41 +03:00
Bruno Oliveira
cb91c5033e Merge pull request #7697 from nicoddemus/file-docs
(cherry picked from commit 21aa6c42b7)
2020-09-04 21:23:53 +03:00
Ran Benita
9a879ee23e Merge pull request #7651 from bluetech/capture-safe-disable
capture: fix disabled()/global_and_fixture_disabled() enabling capturing when it was disabled

(cherry picked from commit bb38ae9c52)
2020-09-04 21:16:07 +03:00
Bruno Oliveira
e9d18bd8ac Merge pull request #7711 from nicoddemus/backport-7708
[6.0] Merge pull request #7708 from nicoddemus/repr-line-7707
2020-09-04 12:41:17 -03:00
Bruno Oliveira
912870d33e Merge pull request #7708 from nicoddemus/repr-line-7707
Fix handle of exceptions in ReprEntry with tb=line
2020-09-04 12:06:38 -03:00
Bruno Oliveira
0115b716c0 Merge pull request #7688 from nicoddemus/backport-7687 2020-08-25 21:23:41 -03:00
Bruno Oliveira
9a91b67eeb Merge pull request #7687 from bluetech/idval-notset
python: fix empty parametrize() leading to "NotSetType.token" id
2020-08-25 19:57:06 -03:00
Ran Benita
79d0d3eff4 Merge pull request #7676 from bluetech/backport-7673
[6.0.x] logging: fix handler level restored incorrectly if caplog.set_level is called more than once
2020-08-23 12:24:50 +03:00
Ran Benita
834f55eddb Merge pull request #7673 from bluetech/logging-fix-handler-restore
logging: fix handler level restored incorrectly if caplog.set_level is called more than once
(cherry picked from commit 143e3ab846)
2020-08-23 12:07:24 +03:00
Bruno Oliveira
6110f84f78 Merge pull request #7588 from nicoddemus/backport-7557
Merge pull request #7557 from nicoddemus/announce-templates
2020-07-30 12:07:53 -03:00
Bruno Oliveira
5a339f0d74 Merge pull request #7557 from nicoddemus/announce-templates
(cherry picked from commit c7216ae0f6)
2020-07-30 12:04:36 -03:00
Bruno Oliveira
022bff27a7 Merge pull request #7584 from pytest-dev/release-6.0.1
Prepare release 6.0.1
2020-07-30 09:45:40 -03:00
pytest bot
92af2e22d2 Prepare release version 6.0.1 2020-07-30 11:50:12 +00:00
Ran Benita
0307213254 Merge pull request #7582 from bluetech/backport-7581
[6.0.x] Add missing changelog for issue 7569
2020-07-30 14:19:29 +03:00
Ran Benita
df7b26704d Merge pull request #7581 from bluetech/logging-setlevel-handler-restore
Add missing changelog for issue 7569

(cherry picked from commit 645cbc91fc)
2020-07-30 13:41:54 +03:00
Bruno Oliveira
1516780829 Merge pull request #7578 from nicoddemus/backport-7555
[6.0.x] Warn about --basetemp removing the entire directory (#7555)
2020-07-29 12:13:16 -03:00
Bruno Oliveira
b945b39b0b Merge pull request #7577 from nicoddemus/backport-7427
[6.0.x] Fix --help crash on add_ini(.., help='') and improve message on help=None (#7427)
2020-07-29 12:10:42 -03:00
Mattreex
2d5b8a85c2 Warn about --basetemp removing the entire directory (#7555)
Co-authored-by: mattreex <mattreex.9@gail.com>
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
(cherry picked from commit 1e66ed0b1c)
2020-07-29 11:58:52 -03:00
hp310780
8963644da3 Fix --help crash on add_ini(.., help='') and improve message on help=None (#7427) 2020-07-29 11:49:09 -03:00
23 changed files with 255 additions and 75 deletions

View File

@@ -1,2 +0,0 @@
Fix pylint ``not-callable`` lint on ``pytest.mark.parametrize()`` and the other builtin marks:
``skip``, ``skipif``, ``xfail``, ``usefixtures``, ``filterwarnings``.

View File

@@ -1 +0,0 @@
Fix regression in plugins using ``TestReport.longreprtext`` (such as ``pytest-html``) when ``TestReport.longrepr`` is not a string.

View File

@@ -6,6 +6,8 @@ Release announcements
:maxdepth: 2
release-6.0.2
release-6.0.1
release-6.0.0
release-6.0.0rc1
release-5.4.3

View File

@@ -0,0 +1,21 @@
pytest-6.0.1
=======================================
pytest 6.0.1 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
* Mattreex
* Ran Benita
* hp310780
Happy testing,
The pytest Development Team

View File

@@ -0,0 +1,19 @@
pytest-6.0.2
=======================================
pytest 6.0.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/stable/changelog.html.
Thanks to all of the contributors to this release:
* Bruno Oliveira
* Ran Benita
Happy testing,
The pytest Development Team

View File

@@ -28,6 +28,45 @@ with advance notice in the **Deprecations** section of releases.
.. towncrier release notes start
pytest 6.0.2 (2020-09-04)
=========================
Bug Fixes
---------
- `#7148 <https://github.com/pytest-dev/pytest/issues/7148>`_: Fixed ``--log-cli`` potentially causing unrelated ``print`` output to be swallowed.
- `#7672 <https://github.com/pytest-dev/pytest/issues/7672>`_: Fixed log-capturing level restored incorrectly if ``caplog.set_level`` is called more than once.
- `#7686 <https://github.com/pytest-dev/pytest/issues/7686>`_: Fixed `NotSetType.token` being used as the parameter ID when the parametrization list is empty.
Regressed in pytest 6.0.0.
- `#7707 <https://github.com/pytest-dev/pytest/issues/7707>`_: Fix internal error when handling some exceptions that contain multiple lines or the style uses multiple lines (``--tb=line`` for example).
pytest 6.0.1 (2020-07-30)
=========================
Bug Fixes
---------
- `#7394 <https://github.com/pytest-dev/pytest/issues/7394>`_: Passing an empty ``help`` value to ``Parser.add_option`` is now accepted instead of crashing when running ``pytest --help``.
Passing ``None`` raises a more informative ``TypeError``.
- `#7558 <https://github.com/pytest-dev/pytest/issues/7558>`_: Fix pylint ``not-callable`` lint on ``pytest.mark.parametrize()`` and the other builtin marks:
``skip``, ``skipif``, ``xfail``, ``usefixtures``, ``filterwarnings``.
- `#7559 <https://github.com/pytest-dev/pytest/issues/7559>`_: Fix regression in plugins using ``TestReport.longreprtext`` (such as ``pytest-html``) when ``TestReport.longrepr`` is not a string.
- `#7569 <https://github.com/pytest-dev/pytest/issues/7569>`_: Fix logging capture handler's level not reset on teardown after a call to ``caplog.set_level()``.
pytest 6.0.0 (2020-07-28)
=========================
@@ -192,9 +231,9 @@ Breaking Changes
- `#7224 <https://github.com/pytest-dev/pytest/issues/7224>`_: The `item.catch_log_handler` and `item.catch_log_handlers` attributes, set by the
logging plugin and never meant to be public , are no longer available.
logging plugin and never meant to be public, are no longer available.
The deprecated ``--no-print-logs`` option is removed. Use ``--show-capture`` instead.
The deprecated ``--no-print-logs`` option and ``log_print`` ini option are removed. Use ``--show-capture`` instead.
- `#7226 <https://github.com/pytest-dev/pytest/issues/7226>`_: Removed the unused ``args`` parameter from ``pytest.Function.__init__``.

View File

@@ -51,9 +51,10 @@ a public API and may break in the future.
.. versionremoved:: 6.0
Option ``--no-print-logs`` is removed. If you used ``--no-print-logs``, please use ``--show-capture`` instead.
The ``--no-print-logs`` option and ``log_print`` ini setting are removed. If
you used them, please use ``--show-capture`` instead.
``--show-capture`` command-line option was added in ``pytest 3.5.0`` and allows to specify how to
A ``--show-capture`` command-line option was added in ``pytest 3.5.0`` which allows to specify how to
display captured output when tests fail: ``no``, ``stdout``, ``stderr``, ``log`` or ``all`` (the default).

View File

@@ -28,7 +28,7 @@ Install ``pytest``
.. code-block:: bash
$ pytest --version
pytest 6.0.0
pytest 6.0.2
.. _`simpletest`:

View File

@@ -783,12 +783,19 @@ ExceptionInfo
:members:
pytest.ExitCode
~~~~~~~~~~~~~~~
ExitCode
~~~~~~~~
.. autoclass:: _pytest.config.ExitCode
:members:
File
~~~~
.. autoclass:: _pytest.nodes.File()
:members:
:show-inheritance:
FixtureDef
~~~~~~~~~~
@@ -1466,20 +1473,6 @@ passed multiple times. The expected format is ``name=value``. For example::
For more information, see :ref:`logging`.
.. confval:: log_print
If set to ``False``, will disable displaying captured logging messages for failed tests.
.. code-block:: ini
[pytest]
log_print = False
For more information, see :ref:`logging`.
.. confval:: markers
When the ``--strict-markers`` or ``--strict`` command-line arguments are used,

View File

@@ -192,8 +192,13 @@ You can override the default temporary directory setting like this:
pytest --basetemp=mydir
When distributing tests on the local machine, ``pytest`` takes care to
configure a basetemp directory for the sub processes such that all temporary
.. warning::
The contents of ``mydir`` will be completely removed, so make sure to use a directory
for that purpose only.
When distributing tests on the local machine using ``pytest-xdist``, care is taken to
automatically configure a basetemp directory for the sub processes such that all temporary
data lands below a single per-test run basetemp directory.
.. _`py.path.local`: https://py.readthedocs.io/en/latest/path.html

View File

@@ -3,23 +3,20 @@ pytest-{version}
The pytest team is proud to announce the {version} release!
pytest is a mature Python testing tool with more than a 2000 tests
against itself, passing on many different interpreters and platforms.
This release contains new features, improvements, bug fixes, and breaking changes, so users
are encouraged to take a look at the CHANGELOG carefully:
This release contains a number of bug fixes and improvements, so users are encouraged
to take a look at the CHANGELOG:
https://docs.pytest.org/en/latest/changelog.html
https://docs.pytest.org/en/stable/changelog.html
For complete documentation, please visit:
https://docs.pytest.org/en/latest/
https://docs.pytest.org/en/stable/
As usual, you can upgrade from PyPI via:
pip install -U pytest
Thanks to all who contributed to this release, among them:
Thanks to all of the contributors to this release:
{contributors}

View File

@@ -7,9 +7,9 @@ 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.
The full changelog is available at https://docs.pytest.org/en/stable/changelog.html.
Thanks to all who contributed to this release, among them:
Thanks to all of the contributors to this release:
{contributors}

View File

@@ -1038,25 +1038,21 @@ class ReprEntry(TerminalRepr):
# such as "> assert 0"
fail_marker = "{} ".format(FormattedExcinfo.fail_marker)
indent_size = len(fail_marker)
indents = []
source_lines = []
failure_lines = []
seeing_failures = False
for line in self.lines:
is_source_line = not line.startswith(fail_marker)
if is_source_line:
assert not seeing_failures, (
"Unexpected failure lines between source lines:\n"
+ "\n".join(self.lines)
)
indents = [] # type: List[str]
source_lines = [] # type: List[str]
failure_lines = [] # type: List[str]
for index, line in enumerate(self.lines):
is_failure_line = line.startswith(fail_marker)
if is_failure_line:
# from this point on all lines are considered part of the failure
failure_lines.extend(self.lines[index:])
break
else:
if self.style == "value":
source_lines.append(line)
else:
indents.append(line[:indent_size])
source_lines.append(line[indent_size:])
else:
seeing_failures = True
failure_lines.append(line)
tw._write_source(source_lines, indents)

View File

@@ -537,7 +537,7 @@ class MultiCapture:
self._in_suspended = True
def resume_capturing(self) -> None:
self._state = "resumed"
self._state = "started"
if self.out:
self.out.resume()
if self.err:
@@ -558,6 +558,10 @@ class MultiCapture:
if self.in_:
self.in_.done()
def is_started(self) -> bool:
"""Whether actively capturing -- not suspended or stopped."""
return self._state == "started"
def readouterr(self) -> CaptureResult:
if self.out:
out = self.out.snap()
@@ -697,11 +701,19 @@ class CaptureManager:
@contextlib.contextmanager
def global_and_fixture_disabled(self) -> Generator[None, None, None]:
"""Context manager to temporarily disable global and current fixture capturing."""
self.suspend()
do_fixture = self._capture_fixture and self._capture_fixture._is_started()
if do_fixture:
self.suspend_fixture()
do_global = self._global_capturing and self._global_capturing.is_started()
if do_global:
self.suspend_global_capture()
try:
yield
finally:
self.resume()
if do_global:
self.resume_global_capture()
if do_fixture:
self.resume_fixture()
@contextlib.contextmanager
def item_capture(self, when: str, item: Item) -> Generator[None, None, None]:
@@ -810,6 +822,12 @@ class CaptureFixture:
if self._capture is not None:
self._capture.resume_capturing()
def _is_started(self) -> bool:
"""Whether actively capturing -- not disabled or closed."""
if self._capture is not None:
return self._capture.is_started()
return False
@contextlib.contextmanager
def disabled(self) -> Generator[None, None, None]:
"""Temporarily disables capture while inside the 'with' block."""

View File

@@ -170,6 +170,8 @@ def showhelp(config: Config) -> None:
help, type, default = config._parser._inidict[name]
if type is None:
type = "string"
if help is None:
raise TypeError("help argument cannot be None for {}".format(name))
spec = "{} ({}):".format(name, type)
tw.write(" %s" % spec)
spec_len = len(spec)
@@ -191,9 +193,10 @@ def showhelp(config: Config) -> None:
tw.write(" " * (indent_len - spec_len - 2))
wrapped = textwrap.wrap(help, columns - indent_len, break_on_hyphens=False)
tw.line(wrapped[0])
for line in wrapped[1:]:
tw.line(indent + line)
if wrapped:
tw.line(wrapped[0])
for line in wrapped[1:]:
tw.line(indent + line)
tw.line()
tw.line("environment variables:")

View File

@@ -437,7 +437,8 @@ class LogCaptureFixture:
# save the original log-level to restore it during teardown
self._initial_logger_levels.setdefault(logger, logger_obj.level)
logger_obj.setLevel(level)
self._initial_handler_level = self.handler.level
if self._initial_handler_level is None:
self._initial_handler_level = self.handler.level
self.handler.setLevel(level)
@contextmanager

View File

@@ -604,7 +604,10 @@ class FSCollector(Collector):
class File(FSCollector):
""" base class for collecting tests from a file. """
"""Base class for collecting tests from a file.
:ref:`non-python tests`.
"""
class Item(Node):

View File

@@ -1254,6 +1254,9 @@ def _idval(
return str(val)
elif isinstance(val, REGEX_TYPE):
return ascii_escaped(val.pattern)
elif val is NOTSET:
# Fallback to default. Note that NOTSET is an enum.Enum.
pass
elif isinstance(val, enum.Enum):
return str(val)
elif isinstance(getattr(val, "__name__", None), str):

View File

@@ -4,6 +4,8 @@ import os
import queue
import sys
import textwrap
from typing import Any
from typing import Dict
from typing import Tuple
from typing import Union
@@ -1045,28 +1047,34 @@ raise ValueError()
@pytest.mark.parametrize(
"reproptions",
[
{
"style": style,
"showlocals": showlocals,
"funcargs": funcargs,
"tbfilter": tbfilter,
}
for style in ("long", "short", "no")
pytest.param(
{
"style": style,
"showlocals": showlocals,
"funcargs": funcargs,
"tbfilter": tbfilter,
},
id="style={},showlocals={},funcargs={},tbfilter={}".format(
style, showlocals, funcargs, tbfilter
),
)
for style in ["long", "short", "line", "no", "native", "value", "auto"]
for showlocals in (True, False)
for tbfilter in (True, False)
for funcargs in (True, False)
],
)
def test_format_excinfo(self, importasmod, reproptions):
mod = importasmod(
"""
def g(x):
raise ValueError(x)
def f():
g(3)
"""
)
excinfo = pytest.raises(ValueError, mod.f)
def test_format_excinfo(self, reproptions: Dict[str, Any]) -> None:
def bar():
assert False, "some error"
def foo():
bar()
# using inline functions as opposed to importasmod so we get source code lines
# in the tracebacks (otherwise getinspect doesn't find the source code).
with pytest.raises(AssertionError) as excinfo:
foo()
file = io.StringIO()
tw = TerminalWriter(file=file)
repr = excinfo.getrepr(**reproptions)

View File

@@ -65,6 +65,7 @@ def test_change_level_undos_handler_level(testdir: Testdir) -> None:
def test1(caplog):
assert caplog.handler.level == 0
caplog.set_level(9999)
caplog.set_level(41)
assert caplog.handler.level == 41

View File

@@ -19,6 +19,7 @@ from hypothesis import strategies
import pytest
from _pytest import fixtures
from _pytest import python
from _pytest.compat import NOTSET
from _pytest.outcomes import fail
from _pytest.pytester import Testdir
from _pytest.python import _idval
@@ -363,6 +364,14 @@ class TestMetafunc:
for val, expected in values:
assert _idval(val, "a", 6, None, nodeid=None, config=None) == expected
def test_notset_idval(self) -> None:
"""Test that a NOTSET value (used by an empty parameterset) generates
a proper ID.
Regression test for #7686.
"""
assert _idval(NOTSET, "a", 0, None, nodeid=None, config=None) == "a0"
def test_idmaker_autoname(self) -> None:
"""#250"""
result = idmaker(

View File

@@ -16,6 +16,7 @@ from _pytest.capture import _get_multicapture
from _pytest.capture import CaptureManager
from _pytest.capture import MultiCapture
from _pytest.config import ExitCode
from _pytest.pytester import Testdir
# note: py.io capture tests where copied from
# pylib 1.4.20.dev2 (rev 13d9af95547e)
@@ -633,6 +634,34 @@ class TestCaptureFixture:
else:
result.stdout.no_fnmatch_line("*test_normal executed*")
def test_disabled_capture_fixture_twice(self, testdir: Testdir) -> None:
"""Test that an inner disabled() exit doesn't undo an outer disabled().
Issue #7148.
"""
testdir.makepyfile(
"""
def test_disabled(capfd):
print('captured before')
with capfd.disabled():
print('while capture is disabled 1')
with capfd.disabled():
print('while capture is disabled 2')
print('while capture is disabled 1 after')
print('captured after')
assert capfd.readouterr() == ('captured before\\ncaptured after\\n', '')
"""
)
result = testdir.runpytest_subprocess()
result.stdout.fnmatch_lines(
[
"*while capture is disabled 1",
"*while capture is disabled 2",
"*while capture is disabled 1 after",
],
consecutive=True,
)
@pytest.mark.parametrize("fixture", ["capsys", "capfd"])
def test_fixture_use_by_other_fixtures(self, testdir, fixture):
"""

View File

@@ -38,6 +38,41 @@ def test_help(testdir):
)
def test_none_help_param_raises_exception(testdir):
"""Tests a None help param raises a TypeError.
"""
testdir.makeconftest(
"""
def pytest_addoption(parser):
parser.addini("test_ini", None, default=True, type="bool")
"""
)
result = testdir.runpytest("--help")
result.stderr.fnmatch_lines(
["*TypeError: help argument cannot be None for test_ini*"]
)
def test_empty_help_param(testdir):
"""Tests an empty help param is displayed correctly.
"""
testdir.makeconftest(
"""
def pytest_addoption(parser):
parser.addini("test_ini", "", default=True, type="bool")
"""
)
result = testdir.runpytest("--help")
assert result.ret == 0
lines = [
" required_plugins (args):",
" plugins that must be present for pytest to run*",
" test_ini (bool):*",
"environment variables:",
]
result.stdout.fnmatch_lines(lines, consecutive=True)
def test_hookvalidation_unknown(testdir):
testdir.makeconftest(
"""