Merge pull request #2945 from nicoddemus/release-3.3.0

Release 3.3.0
This commit is contained in:
Bruno Oliveira 2017-11-27 19:37:19 -02:00 committed by GitHub
commit 67ad0fa364
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
56 changed files with 461 additions and 124 deletions

View File

@ -8,6 +8,186 @@
.. towncrier release notes start
Pytest 3.3.0 (2017-11-23)
=========================
Deprecations and Removals
-------------------------
- Pytest no longer supports Python **2.6** and **3.3**. Those Python versions
are EOL for some time now and incur maintenance and compatibility costs on
the pytest core team, and following up with the rest of the community we
decided that they will no longer be supported starting on this version. Users
which still require those versions should pin pytest to ``<3.3``. (`#2812
<https://github.com/pytest-dev/pytest/issues/2812>`_)
- Remove internal ``_preloadplugins()`` function. This removal is part of the
``pytest_namespace()`` hook deprecation. (`#2236
<https://github.com/pytest-dev/pytest/issues/2236>`_)
- Internally change ``CallSpec2`` to have a list of marks instead of a broken
mapping of keywords. This removes the keywords attribute of the internal
``CallSpec2`` class. (`#2672
<https://github.com/pytest-dev/pytest/issues/2672>`_)
- Remove ParameterSet.deprecated_arg_dict - its not a public api and the lack
of the underscore was a naming error. (`#2675
<https://github.com/pytest-dev/pytest/issues/2675>`_)
- Remove the internal multi-typed attribute ``Node._evalskip`` and replace it
with the boolean ``Node._skipped_by_mark``. (`#2767
<https://github.com/pytest-dev/pytest/issues/2767>`_)
Features
--------
- ``pytest_fixture_post_finalizer`` hook can now receive a ``request``
argument. (`#2124 <https://github.com/pytest-dev/pytest/issues/2124>`_)
- Replace the old introspection code in compat.py that determines the available
arguments of fixtures with inspect.signature on Python 3 and
funcsigs.signature on Python 2. This should respect ``__signature__``
declarations on functions. (`#2267
<https://github.com/pytest-dev/pytest/issues/2267>`_)
- Report tests with global ``pytestmark`` variable only once. (`#2549
<https://github.com/pytest-dev/pytest/issues/2549>`_)
- Now pytest displays the total progress percentage while running tests. The
previous output style can be set by configuring the ``console_output_style``
setting to ``classic``. (`#2657 <https://github.com/pytest-dev/pytest/issues/2657>`_)
- Match ``warns`` signature to ``raises`` by adding ``match`` keyword. (`#2708
<https://github.com/pytest-dev/pytest/issues/2708>`_)
- Pytest now captures and displays output from the standard `logging` module.
The user can control the logging level to be captured by specifying options
in ``pytest.ini``, the command line and also during individual tests using
markers. Also, a ``caplog`` fixture is available that enables users to test
the captured log during specific tests (similar to ``capsys`` for example).
For more information, please see the `logging docs
<https://docs.pytest.org/en/latest/logging.html>`_. This feature was
introduced by merging the popular `pytest-catchlog
<https://pypi.org/project/pytest-catchlog/>`_ plugin, thanks to `Thomas Hisch
<https://github.com/thisch>`_. Be advised that during the merging the
backward compatibility interface with the defunct ``pytest-capturelog`` has
been dropped. (`#2794 <https://github.com/pytest-dev/pytest/issues/2794>`_)
- Add ``allow_module_level`` kwarg to ``pytest.skip()``, enabling to skip the
whole module. (`#2808 <https://github.com/pytest-dev/pytest/issues/2808>`_)
- Allow setting ``file_or_dir``, ``-c``, and ``-o`` in PYTEST_ADDOPTS. (`#2824
<https://github.com/pytest-dev/pytest/issues/2824>`_)
- Return stdout/stderr capture results as a ``namedtuple``, so ``out`` and
``err`` can be accessed by attribute. (`#2879
<https://github.com/pytest-dev/pytest/issues/2879>`_)
- Add ``capfdbinary``, a version of ``capfd`` which returns bytes from
``readouterr()``. (`#2923
<https://github.com/pytest-dev/pytest/issues/2923>`_)
- Add ``capsysbinary`` a version of ``capsys`` which returns bytes from
``readouterr()``. (`#2934
<https://github.com/pytest-dev/pytest/issues/2934>`_)
- Implement feature to skip ``setup.py`` files when run with
``--doctest-modules``. (`#502
<https://github.com/pytest-dev/pytest/issues/502>`_)
Bug Fixes
---------
- Resume output capturing after ``capsys/capfd.disabled()`` context manager.
(`#1993 <https://github.com/pytest-dev/pytest/issues/1993>`_)
- ``pytest_fixture_setup`` and ``pytest_fixture_post_finalizer`` hooks are now
called for all ``conftest.py`` files. (`#2124
<https://github.com/pytest-dev/pytest/issues/2124>`_)
- If an exception happens while loading a plugin, pytest no longer hides the
original traceback. In python2 it will show the original traceback with a new
message that explains in which plugin. In python3 it will show 2 canonized
exceptions, the original exception while loading the plugin in addition to an
exception that PyTest throws about loading a plugin. (`#2491
<https://github.com/pytest-dev/pytest/issues/2491>`_)
- ``capsys`` and ``capfd`` can now be used by other fixtures. (`#2709
<https://github.com/pytest-dev/pytest/issues/2709>`_)
- Internal ``pytester`` plugin properly encodes ``bytes`` arguments to
``utf-8``. (`#2738 <https://github.com/pytest-dev/pytest/issues/2738>`_)
- ``testdir`` now uses use the same method used by ``tmpdir`` to create its
temporary directory. This changes the final structure of the ``testdir``
directory slightly, but should not affect usage in normal scenarios and
avoids a number of potential problems. (`#2751
<https://github.com/pytest-dev/pytest/issues/2751>`_)
- Pytest no longer complains about warnings with unicode messages being
non-ascii compatible even for ascii-compatible messages. As a result of this,
warnings with unicode messages are converted first to an ascii representation
for safety. (`#2809 <https://github.com/pytest-dev/pytest/issues/2809>`_)
- Change return value of pytest command when ``--maxfail`` is reached from
``2`` (interrupted) to ``1`` (failed). (`#2845
<https://github.com/pytest-dev/pytest/issues/2845>`_)
- Fix issue in assertion rewriting which could lead it to rewrite modules which
should not be rewritten. (`#2939
<https://github.com/pytest-dev/pytest/issues/2939>`_)
- Handle marks without description in ``pytest.ini``. (`#2942
<https://github.com/pytest-dev/pytest/issues/2942>`_)
Trivial/Internal Changes
------------------------
- pytest now depends on `attrs <https://pypi.org/project/attrs/>`_ for internal
structures to ease code maintainability. (`#2641
<https://github.com/pytest-dev/pytest/issues/2641>`_)
- Refactored internal Python 2/3 compatibility code to use ``six``. (`#2642
<https://github.com/pytest-dev/pytest/issues/2642>`_)
- Stop vendoring ``pluggy`` - we're missing out on its latest changes for not
much benefit (`#2719 <https://github.com/pytest-dev/pytest/issues/2719>`_)
- Internal refactor: simplify ascii string escaping by using the
backslashreplace error handler in newer Python 3 versions. (`#2734
<https://github.com/pytest-dev/pytest/issues/2734>`_)
- Remove unnecessary mark evaluator in unittest plugin (`#2767
<https://github.com/pytest-dev/pytest/issues/2767>`_)
- Calls to ``Metafunc.addcall`` now emit a deprecation warning. This function
is scheduled to be removed in ``pytest-4.0``. (`#2876
<https://github.com/pytest-dev/pytest/issues/2876>`_)
- Internal move of the parameterset extraction to a more maintainable place.
(`#2877 <https://github.com/pytest-dev/pytest/issues/2877>`_)
- Internal refactoring to simplify scope node lookup. (`#2910
<https://github.com/pytest-dev/pytest/issues/2910>`_)
- Configure ``pytest`` to prevent pip from installing pytest in unsupported
Python versions. (`#2922
<https://github.com/pytest-dev/pytest/issues/2922>`_)
Pytest 3.2.5 (2017-11-15)
=========================
Bug Fixes
---------
- Remove ``py<1.5`` restriction from ``pytest`` as this can cause version
conflicts in some installations. (`#2926
<https://github.com/pytest-dev/pytest/issues/2926>`_)
Pytest 3.2.4 (2017-11-13)
=========================
@ -28,6 +208,8 @@ Bug Fixes
failed example in the docstring is < 9. (`#2882
<https://github.com/pytest-dev/pytest/issues/2882>`_)
- Match fixture paths against actual path segments in order to avoid matching folders which share a prefix.
(`#2836 <https://github.com/pytest-dev/pytest/issues/2836>`_)
Improved Documentation
----------------------
@ -179,7 +361,7 @@ Deprecations and Removals
-------------------------
- ``pytest.approx`` no longer supports ``>``, ``>=``, ``<`` and ``<=``
operators to avoid surprising/inconsistent behavior. See `the docs
operators to avoid surprising/inconsistent behavior. See `the approx docs
<https://docs.pytest.org/en/latest/builtin.html#pytest.approx>`_ for more
information. (`#2003 <https://github.com/pytest-dev/pytest/issues/2003>`_)

View File

@ -168,7 +168,7 @@ class AssertionRewritingHook(object):
return True
for marked in self._must_rewrite:
if name.startswith(marked):
if name == marked or name.startswith(marked + '.'):
state.trace("matched marked file %r (from %r)" % (name, marked))
return True

View File

@ -242,6 +242,10 @@ class PytestPluginManager(PluginManager):
return opts
def register(self, plugin, name=None):
if name == 'pytest_catchlog':
self._warn('pytest-catchlog plugin has been merged into the core, '
'please remove it from your requirements.')
return
ret = super(PytestPluginManager, self).register(plugin, name)
if ret:
self.hook.pytest_plugin_registered.call_historic(
@ -931,7 +935,7 @@ class Config(object):
fslocation=fslocation, nodeid=nodeid))
def get_terminal_writer(self):
return self.pluginmanager.get_plugin("terminalreporter").writer
return self.pluginmanager.get_plugin("terminalreporter")._tw
def pytest_cmdline_parse(self, pluginmanager, args):
# REF1 assert self == pluginmanager.config, (self, pluginmanager.config)

View File

@ -83,7 +83,7 @@ def _enter_pdb(node, excinfo, rep):
# XXX we re-use the TerminalReporter's terminalwriter
# because this seems to avoid some encoding related troubles
# for not completely clear reasons.
tw = node.config.pluginmanager.getplugin("terminalreporter").writer
tw = node.config.pluginmanager.getplugin("terminalreporter")._tw
tw.line()
tw.sep(">", "traceback")
rep.toterminal(tw)

View File

@ -107,7 +107,7 @@ def pytest_cmdline_main(config):
def showhelp(config):
reporter = config.pluginmanager.get_plugin('terminalreporter')
tw = reporter.writer
tw = reporter._tw
tw.write(config._parser.optparser.format_help())
tw.line()
tw.line()

View File

@ -141,7 +141,9 @@ def pytest_cmdline_main(config):
config._do_configure()
tw = _pytest.config.create_terminal_writer(config)
for line in config.getini("markers"):
name, rest = line.split(":", 1)
parts = line.split(":", 1)
name = parts[0]
rest = parts[1] if len(parts) == 2 else ''
tw.write("@pytest.mark.%s:" % name, bold=True)
tw.line(rest)
tw.line()
@ -298,7 +300,7 @@ class MarkGenerator:
pass
self._markers = values = set()
for line in self._config.getini("markers"):
marker, _ = line.split(":", 1)
marker = line.split(":", 1)[0]
marker = marker.rstrip()
x = marker.split("(", 1)[0]
values.add(x)

View File

@ -25,7 +25,7 @@ def pytest_configure(config):
if tr is not None:
# pastebin file will be utf-8 encoded binary file
config._pastebinfile = tempfile.TemporaryFile('w+b')
oldwrite = tr.writer.write
oldwrite = tr._tw.write
def tee_write(s, **kwargs):
oldwrite(s, **kwargs)
@ -33,7 +33,7 @@ def pytest_configure(config):
s = s.encode('utf-8')
config._pastebinfile.write(s)
tr.writer.write = tee_write
tr._tw.write = tee_write
def pytest_unconfigure(config):
@ -45,7 +45,7 @@ def pytest_unconfigure(config):
del config._pastebinfile
# undo our patching in the terminal reporter
tr = config.pluginmanager.getplugin('terminalreporter')
del tr.writer.__dict__['write']
del tr._tw.__dict__['write']
# write summary
tr.write_sep("=", "Sending information to Paste Service")
pastebinurl = create_new_paste(sessionlog)

View File

@ -308,9 +308,9 @@ def pytest_terminal_summary(terminalreporter):
show_simple(terminalreporter, lines, 'passed', "PASSED %s")
if lines:
tr.writer.sep("=", "short test summary info")
tr._tw.sep("=", "short test summary info")
for line in lines:
tr.writer.line(line)
tr._tw.line(line)
def show_simple(terminalreporter, lines, stat, format):

View File

@ -8,7 +8,6 @@ import itertools
import platform
import sys
import time
import warnings
import pluggy
import py
@ -145,25 +144,15 @@ class TerminalReporter:
self.startdir = py.path.local()
if file is None:
file = sys.stdout
self._writer = _pytest.config.create_terminal_writer(config, file)
self._screen_width = self.writer.fullwidth
self._tw = _pytest.config.create_terminal_writer(config, file)
self._screen_width = self._tw.fullwidth
self.currentfspath = None
self.reportchars = getreportopt(config)
self.hasmarkup = self.writer.hasmarkup
self.hasmarkup = self._tw.hasmarkup
self.isatty = file.isatty()
self._progress_items_reported = 0
self._show_progress_info = self.config.getini('console_output_style') == 'progress'
@property
def writer(self):
return self._writer
@property
def _tw(self):
warnings.warn(DeprecationWarning('TerminalReporter._tw is deprecated, use TerminalReporter.writer instead'),
stacklevel=2)
return self.writer
def hasopt(self, char):
char = {'xfailed': 'x', 'skipped': 's'}.get(char, char)
return char in self.reportchars
@ -175,33 +164,33 @@ class TerminalReporter:
self._write_progress_information_filling_space()
self.currentfspath = fspath
fspath = self.startdir.bestrelpath(fspath)
self.writer.line()
self.writer.write(fspath + " ")
self.writer.write(res)
self._tw.line()
self._tw.write(fspath + " ")
self._tw.write(res)
def write_ensure_prefix(self, prefix, extra="", **kwargs):
if self.currentfspath != prefix:
self.writer.line()
self._tw.line()
self.currentfspath = prefix
self.writer.write(prefix)
self._tw.write(prefix)
if extra:
self.writer.write(extra, **kwargs)
self._tw.write(extra, **kwargs)
self.currentfspath = -2
self._write_progress_information_filling_space()
def ensure_newline(self):
if self.currentfspath:
self.writer.line()
self._tw.line()
self.currentfspath = None
def write(self, content, **markup):
self.writer.write(content, **markup)
self._tw.write(content, **markup)
def write_line(self, line, **markup):
if not isinstance(line, six.text_type):
line = six.text_type(line, errors="replace")
self.ensure_newline()
self.writer.line(line, **markup)
self._tw.line(line, **markup)
def rewrite(self, line, **markup):
"""
@ -214,22 +203,22 @@ class TerminalReporter:
"""
erase = markup.pop('erase', False)
if erase:
fill_count = self.writer.fullwidth - len(line) - 1
fill_count = self._tw.fullwidth - len(line) - 1
fill = ' ' * fill_count
else:
fill = ''
line = str(line)
self.writer.write("\r" + line + fill, **markup)
self._tw.write("\r" + line + fill, **markup)
def write_sep(self, sep, title=None, **markup):
self.ensure_newline()
self.writer.sep(sep, title, **markup)
self._tw.sep(sep, title, **markup)
def section(self, title, sep="=", **kw):
self.writer.sep(sep, title, **kw)
self._tw.sep(sep, title, **kw)
def line(self, msg, **kw):
self.writer.line(msg, **kw)
self._tw.line(msg, **kw)
def pytest_internalerror(self, excrepr):
for line in six.text_type(excrepr).split("\n"):
@ -282,7 +271,7 @@ class TerminalReporter:
if not running_xdist and self.showfspath:
self.write_fspath_result(rep.nodeid, letter)
else:
self.writer.write(letter)
self._tw.write(letter)
self._write_progress_if_past_edge()
else:
if markup is None:
@ -299,13 +288,13 @@ class TerminalReporter:
self.write_ensure_prefix(line, word, **markup)
else:
self.ensure_newline()
self.writer.write("[%s]" % rep.node.gateway.id)
self._tw.write("[%s]" % rep.node.gateway.id)
if self._show_progress_info:
self.writer.write(self._get_progress_information_message() + " ", cyan=True)
self._tw.write(self._get_progress_information_message() + " ", cyan=True)
else:
self.writer.write(' ')
self.writer.write(word, **markup)
self.writer.write(" " + line)
self._tw.write(' ')
self._tw.write(word, **markup)
self._tw.write(" " + line)
self.currentfspath = -2
def _write_progress_if_past_edge(self):
@ -316,10 +305,10 @@ class TerminalReporter:
self._write_progress_information_filling_space()
return
past_edge = self.writer.chars_on_current_line + self._PROGRESS_LENGTH + 1 >= self._screen_width
past_edge = self._tw.chars_on_current_line + self._PROGRESS_LENGTH + 1 >= self._screen_width
if past_edge:
msg = self._get_progress_information_message()
self.writer.write(msg + '\n', cyan=True)
self._tw.write(msg + '\n', cyan=True)
_PROGRESS_LENGTH = len(' [100%]')
@ -331,7 +320,7 @@ class TerminalReporter:
if not self._show_progress_info:
return
msg = self._get_progress_information_message()
fill = ' ' * (self.writer.fullwidth - self.writer.chars_on_current_line - len(msg) - 1)
fill = ' ' * (self._tw.fullwidth - self._tw.chars_on_current_line - len(msg) - 1)
self.write(fill + msg, cyan=True)
def pytest_collection(self):
@ -418,9 +407,9 @@ class TerminalReporter:
if self.config.option.collectonly:
self._printcollecteditems(session.items)
if self.stats.get('failed'):
self.writer.sep("!", "collection failures")
self._tw.sep("!", "collection failures")
for rep in self.stats.get('failed'):
rep.toterminal(self.writer)
rep.toterminal(self._tw)
return 1
return 0
lines = self.config.hook.pytest_report_collectionfinish(
@ -438,12 +427,12 @@ class TerminalReporter:
name = item.nodeid.split('::', 1)[0]
counts[name] = counts.get(name, 0) + 1
for name, count in sorted(counts.items()):
self.writer.line("%s: %d" % (name, count))
self._tw.line("%s: %d" % (name, count))
else:
for item in items:
nodeid = item.nodeid
nodeid = nodeid.replace("::()::", "::")
self.writer.line(nodeid)
self._tw.line(nodeid)
return
stack = []
indent = ""
@ -458,13 +447,13 @@ class TerminalReporter:
# if col.name == "()":
# continue
indent = (len(stack) - 1) * " "
self.writer.line("%s%s" % (indent, col))
self._tw.line("%s%s" % (indent, col))
@pytest.hookimpl(hookwrapper=True)
def pytest_sessionfinish(self, exitstatus):
outcome = yield
outcome.get_result()
self.writer.line("")
self._tw.line("")
summary_exit_codes = (
EXIT_OK, EXIT_TESTSFAILED, EXIT_INTERRUPTED, EXIT_USAGEERROR,
EXIT_NOTESTSCOLLECTED)
@ -494,10 +483,10 @@ class TerminalReporter:
self.write_sep("!", msg)
if "KeyboardInterrupt" in msg:
if self.config.option.fulltrace:
excrepr.toterminal(self.writer)
excrepr.toterminal(self._tw)
else:
self.writer.line("to show a full traceback on KeyboardInterrupt use --fulltrace", yellow=True)
excrepr.reprcrash.toterminal(self.writer)
self._tw.line("to show a full traceback on KeyboardInterrupt use --fulltrace", yellow=True)
excrepr.reprcrash.toterminal(self._tw)
def _locationline(self, nodeid, fspath, lineno, domain):
def mkrel(nodeid):
@ -554,13 +543,13 @@ class TerminalReporter:
self.write_sep("=", "warnings summary", yellow=True, bold=False)
for location, warning_records in grouped:
self.writer.line(str(location) or '<undetermined location>')
self._tw.line(str(location) or '<undetermined location>')
for w in warning_records:
lines = w.message.splitlines()
indented = '\n'.join(' ' + x for x in lines)
self.writer.line(indented)
self.writer.line()
self.writer.line('-- Docs: http://doc.pytest.org/en/latest/warnings.html')
self._tw.line(indented)
self._tw.line()
self._tw.line('-- Docs: http://doc.pytest.org/en/latest/warnings.html')
def summary_passes(self):
if self.config.option.tbstyle != "no":
@ -577,10 +566,10 @@ class TerminalReporter:
def print_teardown_sections(self, rep):
for secname, content in rep.sections:
if 'teardown' in secname:
self.writer.sep('-', secname)
self._tw.sep('-', secname)
if content[-1:] == "\n":
content = content[:-1]
self.writer.line(content)
self._tw.line(content)
def summary_failures(self):
if self.config.option.tbstyle != "no":
@ -620,12 +609,12 @@ class TerminalReporter:
self._outrep_summary(rep)
def _outrep_summary(self, rep):
rep.toterminal(self.writer)
rep.toterminal(self._tw)
for secname, content in rep.sections:
self.writer.sep("-", secname)
self._tw.sep("-", secname)
if content[-1:] == "\n":
content = content[:-1]
self.writer.line(content)
self._tw.line(content)
def summary_stats(self):
session_duration = time.time() - self._sessionstarttime

View File

@ -1 +0,0 @@
Resume output capturing after ``capsys/capfd.disabled()`` context manager.

View File

@ -1 +0,0 @@
``pytest_fixture_setup`` and ``pytest_fixture_post_finalizer`` hooks are now called for all ``conftest.py`` files.

View File

@ -1 +0,0 @@
``pytest_fixture_post_finalizer`` hook can now receive a ``request`` argument.

View File

@ -1 +0,0 @@
- Remove internal ``_preloadplugins()`` function. This removal is part of the ``pytest_namespace()`` hook deprecation.

View File

@ -1,4 +0,0 @@
Replace the old introspection code in compat.py that determines the
available arguments of fixtures with inspect.signature on Python 3 and
funcsigs.signature on Python 2. This should respect __signature__
declarations on functions.

View File

@ -1,4 +0,0 @@
If an exception happens while loading a plugin, pytest no longer hides the original traceback.
In python2 it will show the original traceback with a new message that explains in which plugin.
In python3 it will show 2 canonized exceptions, the original exception while loading the plugin
in addition to an exception that PyTest throws about loading a plugin.

View File

@ -1 +0,0 @@
Report only once tests with global ``pytestmark`` variable.

View File

@ -1 +0,0 @@
pytest now depends on `attrs <https://pypi.org/project/attrs/>`_ for internal structures to ease code maintainability.

View File

@ -1 +0,0 @@
Refactored internal Python 2/3 compatibility code to use ``six``.

View File

@ -1 +0,0 @@
Now pytest displays the total progress percentage while running tests. The previous output style can be set by setting the new ``console_output_style`` to ``classic``.

View File

@ -1,2 +0,0 @@
Internally change ``CallSpec2`` to have a list of marks instead of a broken mapping of keywords.
This removes the keywords attribute of the internal ``CallSpec2`` class.

View File

@ -1 +0,0 @@
remove ParameterSet.deprecated_arg_dict - its not a public api and the lack of the underscore was a naming error.

View File

@ -1 +0,0 @@
Match ``warns`` signature to ``raises`` by adding ``match`` keyworkd.

View File

@ -1 +0,0 @@
``capsys`` and ``capfd`` can now be used by other fixtures.

View File

@ -1 +0,0 @@
Stop vendoring ``pluggy`` - we're missing out on it's latest changes for not much benefit

View File

@ -1 +0,0 @@
Internal refactor: simplify ascii string escaping by using the backslashreplace error handler in newer Python 3 versions.

View File

@ -1 +0,0 @@
Internal ``pytester`` plugin properly encodes ``bytes`` arguments to ``utf-8``.

View File

@ -1 +0,0 @@
``testdir`` now uses use the same method used by ``tmpdir`` to create its temporary directory. This changes the final structure of the ``testdir`` directory slightly, but should not affect usage in normal scenarios and avoids a number of potential problems.

View File

@ -1 +0,0 @@
Remove the internal multi-typed attribute ``Node._evalskip`` and replace it with the boolean ``Node._skipped_by_mark``.

View File

@ -1 +0,0 @@
* remove unnecessary mark evaluator in unittest plugin

View File

@ -1,3 +0,0 @@
Pytest now captures and displays output from the standard `logging` module. The user can control the logging level to be captured by specifying options in ``pytest.ini``, the command line and also during individual tests using markers. Also, a ``caplog`` fixture is available that enables users to test the captured log during specific tests (similar to ``capsys`` for example). For more information, please see the `docs <https://docs.pytest.org/en/latest/logging.html>`_.
This feature was introduced by merging the popular `pytest-catchlog <https://pypi.org/project/pytest-catchlog/>`_ plugin, thanks to `Thomas Hisch <https://github.com/thisch>`_. Be advised that during the merging the backward compatibility interface with the defunct ``pytest-capturelog`` has been dropped.

View File

@ -1 +0,0 @@
``TerminalReporter._tw`` has been deprecated in favor of ``TerminalReporter.writer`` and will be removed in a future version. Also, ``TerminalReporter.writer`` is now read-only.

View File

@ -1 +0,0 @@
Add ``allow_module_level`` kwarg to ``pytest.skip()``, enabling to skip the whole module.

View File

@ -1 +0,0 @@
Pytest no longer complains about warnings with unicode messages being non-ascii compatible even for ascii-compatible messages. As a result of this, warnings with unicode messages are converted first to an ascii representation for safety.

View File

@ -1 +0,0 @@
Pytest no longer supports Python **2.6** and **3.3**. Those Python versions are EOL for some time now and incurr maintanance and compatibility costs on the pytest core team, and following up with the rest of the community we decided that they will no longer be supported starting on this version. Users which still require those versions should pin pytest to ``<3.3``.

View File

@ -1 +0,0 @@
Allow setting ``file_or_dir``, ``-c``, and ``-o`` in PYTEST_ADDOPTS.

View File

@ -1 +0,0 @@
Match fixture paths against actual path segments in order to avoid matching folders which share a prefix.

View File

@ -1 +0,0 @@
Change return value of pytest command when ``--maxfail`` is reached from ``2`` (interrupted) to ``1`` (failed).

View File

@ -1 +0,0 @@
Calls to ``Metafunc.addcall`` now emit a deprecation warning. This function is scheduled to be removed in ``pytest-4.0``.

View File

@ -1 +0,0 @@
Internal move of the parameterset extraction to a more maintainable place.

View File

@ -1 +0,0 @@
Return stdout/stderr capture results as a ``namedtuple``, so ``out`` and ``err`` can be accessed by attribute.

View File

@ -1 +0,0 @@
Internal refactoring to simplify scope node lookup.

View File

@ -1 +0,0 @@
Configure ``pytest`` to prevent pip from installing pytest in unsupported Python versions.

View File

@ -1,2 +0,0 @@
Add ``capfdbinary`` a version of ``capfd`` which returns bytes from
``readouterr()``.

View File

@ -1,2 +0,0 @@
Add ``capsysbinary`` a version of ``capsys`` which returns bytes from
``readouterr()``.

View File

@ -1 +0,0 @@
Implement feature to skip ``setup.py`` files when ran with ``--doctest-modules``.

View File

@ -6,6 +6,8 @@ Release announcements
:maxdepth: 2
release-3.3.0
release-3.2.5
release-3.2.4
release-3.2.3
release-3.2.2

View File

@ -0,0 +1,18 @@
pytest-3.2.5
=======================================
pytest 3.2.5 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 http://doc.pytest.org/en/latest/changelog.html.
Thanks to all who contributed to this release, among them:
* Bruno Oliveira
Happy testing,
The pytest Development Team

View File

@ -0,0 +1,50 @@
pytest-3.3.0
=======================================
The pytest team is proud to announce the 3.3.0 release!
pytest is a mature Python testing tool with more than a 1600 tests
against itself, passing on many different interpreters and platforms.
This release contains a number of bugs fixes and improvements, so users are encouraged
to take a look at the CHANGELOG:
http://doc.pytest.org/en/latest/changelog.html
For complete documentation, please visit:
http://docs.pytest.org
As usual, you can upgrade from pypi via:
pip install -U pytest
Thanks to all who contributed to this release, among them:
* Anthony Sottile
* Bruno Oliveira
* Ceridwen
* Daniel Hahler
* Dirk Thomas
* Dmitry Malinovsky
* Florian Bruhin
* George Y. Kussumoto
* Hugo
* Jesús Espino
* Joan Massich
* Ofir
* OfirOshir
* Ronny Pfannschmidt
* Samuel Dion-Girardeau
* Srinivas Reddy Thatiparthy
* Sviatoslav Abakumov
* Tarcisio Fischer
* Thomas Hisch
* Tyler Goodlet
* hugovk
* je
* prokaktus
Happy testing,
The Pytest Development Team

View File

@ -10,3 +10,96 @@ With the pytest 3.0 release we introduced a clear communication scheme for when
To communicate changes we are already issuing deprecation warnings, but they are not displayed by default. In pytest 3.0 we changed the default setting so that pytest deprecation warnings are displayed if not explicitly silenced (with ``--disable-pytest-warnings``).
We will only remove deprecated functionality in major releases (e.g. if we deprecate something in 3.0 we will remove it in 4.0), and keep it around for at least two minor releases (e.g. if we deprecate something in 3.9 and 4.0 is the next release, we will not remove it in 4.0 but in 5.0).
Deprecation Roadmap
-------------------
This page lists deprecated features and when we plan to remove them. It is important to list the feature, the version where it got deprecated and the version we plan to remove it.
Following our deprecation policy, we should aim to keep features for *at least* two minor versions after it was considered deprecated.
Future Releases
~~~~~~~~~~~~~~~
3.4
^^^
**Old style classes**
Issue: `#2147 <https://github.com/pytest-dev/pytest/issues/2147>`_.
Deprecated in ``3.2``.
4.0
^^^
**Yield tests**
Deprecated in ``3.0``.
**pytest-namespace hook**
deprecated in ``3.2``.
**Marks in parameter sets**
Deprecated in ``3.2``.
**--result-log**
Deprecated in ``3.0``.
See `#830 <https://github.com/pytest-dev/pytest/issues/830>`_ for more information. Suggested alternative: `pytest-tap <https://pypi.python.org/pypi/pytest-tap>`_.
**metafunc.addcall**
Issue: `#2876 <https://github.com/pytest-dev/pytest/issues/2876>`_.
Deprecated in ``3.3``.
**pytest_plugins in non-toplevel conftests**
There is a deep conceptual confusion as ``conftest.py`` files themselves are activated/deactivated based on path, but the plugins they depend on aren't.
Issue: `#2639 <https://github.com/pytest-dev/pytest/issues/2639>`_.
Not yet officially deprecated.
**passing a single string to pytest.main()**
Pass a list of strings to ``pytest.main()`` instead.
Deprecated in ``3.1``.
**[pytest] section in setup.cfg**
Use ``[tool:pytest]`` instead for compatibility with other tools.
Deprecated in ``3.0``.
Past Releases
~~~~~~~~~~~~~
3.0
^^^
* The following deprecated commandline options were removed:
* ``--genscript``: no longer supported;
* ``--no-assert``: use ``--assert=plain`` instead;
* ``--nomagic``: use ``--assert=plain`` instead;
* ``--report``: use ``-r`` instead;
* Removed all ``py.test-X*`` entry points. The versioned, suffixed entry points
were never documented and a leftover from a pre-virtualenv era. These entry
points also created broken entry points in wheels, so removing them also
removes a source of confusion for users.
3.3
^^^
* Dropped support for EOL Python 2.6 and 3.3.

View File

@ -411,11 +411,8 @@ is to be run with different sets of arguments for its three arguments:
Running it results in some skips if we don't have all the python interpreters installed and otherwise runs all combinations (5 interpreters times 5 interpreters times 3 objects to serialize/deserialize)::
. $ pytest -rs -q multipython.py
ssssssssssssssssssssssss... [100%]
========================= short test summary info ==========================
SKIP [12] $REGENDOC_TMPDIR/CWD/multipython.py:24: 'python2.7' not found
SKIP [12] $REGENDOC_TMPDIR/CWD/multipython.py:24: 'python3.4' not found
3 passed, 24 skipped in 0.12 seconds
........................... [100%]
27 passed in 0.12 seconds
Indirect parametrization of optional implementations/imports
--------------------------------------------------------------------

View File

@ -53,7 +53,7 @@ def main():
# 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.5,<0.6')
install_requires.append('pluggy>=0.5,<0.7')
if has_environment_marker_support():
extras_require[':python_version<"3.0"'] = ['funcsigs']
extras_require[':sys_platform=="win32"'] = ['colorama']

View File

@ -4,10 +4,9 @@ Invoke tasks to help with pytest development and release process.
import invoke
from . import generate, vendoring
from . import generate
ns = invoke.Collection(
generate,
vendoring
)

View File

@ -99,3 +99,16 @@ def test_metafunc_addcall_deprecated(testdir):
"*Metafunc.addcall is deprecated*",
"*2 passed, 2 warnings*",
])
def test_pytest_catchlog_deprecated(testdir):
testdir.makepyfile("""
def test_func(pytestconfig):
pytestconfig.pluginmanager.register(None, 'pytest_catchlog')
""")
res = testdir.runpytest()
assert res.ret == 0
res.stdout.fnmatch_lines([
"*pytest-catchlog plugin has been merged into the core*",
"*1 passed, 1 warnings*",
])

View File

@ -129,6 +129,24 @@ class TestImportHookInstallation(object):
result = testdir.runpytest_subprocess('--assert=rewrite')
assert result.ret == 0
def test_pytest_plugins_rewrite_module_names_correctly(self, testdir):
"""Test that we match files correctly when they are marked for rewriting (#2939)."""
contents = {
'conftest.py': """
pytest_plugins = "ham"
""",
'ham.py': "",
'hamster.py': "",
'test_foo.py': """
def test_foo(pytestconfig):
assert pytestconfig.pluginmanager.rewrite_hook.find_module('ham') is not None
assert pytestconfig.pluginmanager.rewrite_hook.find_module('hamster') is None
""",
}
testdir.makepyfile(**contents)
result = testdir.runpytest_subprocess('--assert=rewrite')
assert result.ret == 0
@pytest.mark.parametrize('mode', ['plain', 'rewrite'])
@pytest.mark.parametrize('plugin_state', ['development', 'installed'])
def test_installed_plugin_rewrite(self, testdir, mode, plugin_state):

View File

@ -161,11 +161,13 @@ def test_markers_option(testdir):
markers =
a1: this is a webtest marker
a1some: another marker
nodescription
""")
result = testdir.runpytest("--markers", )
result.stdout.fnmatch_lines([
"*a1*this is a webtest*",
"*a1some*another marker",
"*nodescription*",
])
@ -186,6 +188,21 @@ def test_ini_markers_whitespace(testdir):
rec.assertoutcome(passed=1)
def test_marker_without_description(testdir):
testdir.makefile(".cfg", setup="""
[tool:pytest]
markers=slow
""")
testdir.makeconftest("""
import pytest
pytest.mark.xfail('FAIL')
""")
ftdir = testdir.mkdir("ft1_dummy")
testdir.tmpdir.join("conftest.py").move(ftdir.join("conftest.py"))
rec = testdir.runpytest_subprocess("--strict")
rec.assert_outcomes()
def test_markers_option_with_plugin_in_current_dir(testdir):
testdir.makeconftest('pytest_plugins = "flip_flop"')
testdir.makepyfile(flip_flop="""\
@ -576,7 +593,7 @@ class TestFunctional(object):
request.applymarker(pytest.mark.hello)
def pytest_terminal_summary(terminalreporter):
values = terminalreporter.stats['passed']
terminalreporter.writer.line("keyword: %s" % values[0].keywords)
terminalreporter._tw.line("keyword: %s" % values[0].keywords)
""")
testdir.makepyfile("""
def test_func(arg):

View File

@ -219,7 +219,7 @@ class TestTerminal(object):
f = py.io.TextIO()
monkeypatch.setattr(f, 'isatty', lambda *args: True)
tr = TerminalReporter(config, f)
tr.writer.fullwidth = 10
tr._tw.fullwidth = 10
tr.write('hello')
tr.rewrite('hey', erase=True)
assert f.getvalue() == 'hello' + '\r' + 'hey' + (6 * ' ')