Merge master into features
Conflicts: src/_pytest/logging.py
This commit is contained in:
		
						commit
						7f1af84f47
					
				| 
						 | 
					@ -47,33 +47,6 @@ Bug Fixes
 | 
				
			||||||
- `#5902 <https://github.com/pytest-dev/pytest/issues/5902>`_: Fix warnings about deprecated ``cmp`` attribute in ``attrs>=19.2``.
 | 
					- `#5902 <https://github.com/pytest-dev/pytest/issues/5902>`_: Fix warnings about deprecated ``cmp`` attribute in ``attrs>=19.2``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pytest 4.6.6 (2019-10-11)
 | 
					 | 
				
			||||||
=========================
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Bug Fixes
 | 
					 | 
				
			||||||
---------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- `#5523 <https://github.com/pytest-dev/pytest/issues/5523>`_: Fixed using multiple short options together in the command-line (for example ``-vs``) in Python 3.8+.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- `#5537 <https://github.com/pytest-dev/pytest/issues/5537>`_: Replace ``importlib_metadata`` backport with ``importlib.metadata`` from the
 | 
					 | 
				
			||||||
  standard library on Python 3.8+.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- `#5806 <https://github.com/pytest-dev/pytest/issues/5806>`_: Fix "lexer" being used when uploading to bpaste.net from ``--pastebin`` to "text".
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- `#5902 <https://github.com/pytest-dev/pytest/issues/5902>`_: Fix warnings about deprecated ``cmp`` attribute in ``attrs>=19.2``.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Trivial/Internal Changes
 | 
					 | 
				
			||||||
------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- `#5801 <https://github.com/pytest-dev/pytest/issues/5801>`_: Fixes python version checks (detected by ``flake8-2020``) in case python4 becomes a thing.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pytest 5.2.0 (2019-09-28)
 | 
					pytest 5.2.0 (2019-09-28)
 | 
				
			||||||
=========================
 | 
					=========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -544,6 +517,32 @@ 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.6 (2019-10-11)
 | 
				
			||||||
 | 
					=========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Bug Fixes
 | 
				
			||||||
 | 
					---------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `#5523 <https://github.com/pytest-dev/pytest/issues/5523>`_: Fixed using multiple short options together in the command-line (for example ``-vs``) in Python 3.8+.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `#5537 <https://github.com/pytest-dev/pytest/issues/5537>`_: Replace ``importlib_metadata`` backport with ``importlib.metadata`` from the
 | 
				
			||||||
 | 
					  standard library on Python 3.8+.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `#5806 <https://github.com/pytest-dev/pytest/issues/5806>`_: Fix "lexer" being used when uploading to bpaste.net from ``--pastebin`` to "text".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `#5902 <https://github.com/pytest-dev/pytest/issues/5902>`_: Fix warnings about deprecated ``cmp`` attribute in ``attrs>=19.2``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Trivial/Internal Changes
 | 
				
			||||||
 | 
					------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `#5801 <https://github.com/pytest-dev/pytest/issues/5801>`_: Fixes python version checks (detected by ``flake8-2020``) in case python4 becomes a thing.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pytest 4.6.5 (2019-08-05)
 | 
					pytest 4.6.5 (2019-08-05)
 | 
				
			||||||
=========================
 | 
					=========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,7 @@ import sys
 | 
				
			||||||
import traceback
 | 
					import traceback
 | 
				
			||||||
from inspect import CO_VARARGS
 | 
					from inspect import CO_VARARGS
 | 
				
			||||||
from inspect import CO_VARKEYWORDS
 | 
					from inspect import CO_VARKEYWORDS
 | 
				
			||||||
 | 
					from io import StringIO
 | 
				
			||||||
from traceback import format_exception_only
 | 
					from traceback import format_exception_only
 | 
				
			||||||
from types import CodeType
 | 
					from types import CodeType
 | 
				
			||||||
from types import TracebackType
 | 
					from types import TracebackType
 | 
				
			||||||
| 
						 | 
					@ -867,7 +868,7 @@ class TerminalRepr:
 | 
				
			||||||
    def __str__(self):
 | 
					    def __str__(self):
 | 
				
			||||||
        # FYI this is called from pytest-xdist's serialization of exception
 | 
					        # FYI this is called from pytest-xdist's serialization of exception
 | 
				
			||||||
        # information.
 | 
					        # information.
 | 
				
			||||||
        io = py.io.TextIO()
 | 
					        io = StringIO()
 | 
				
			||||||
        tw = py.io.TerminalWriter(file=io)
 | 
					        tw = py.io.TerminalWriter(file=io)
 | 
				
			||||||
        self.toterminal(tw)
 | 
					        self.toterminal(tw)
 | 
				
			||||||
        return io.getvalue().strip()
 | 
					        return io.getvalue().strip()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,13 +2,12 @@
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
import re
 | 
					import re
 | 
				
			||||||
from contextlib import contextmanager
 | 
					from contextlib import contextmanager
 | 
				
			||||||
 | 
					from io import StringIO
 | 
				
			||||||
from typing import AbstractSet
 | 
					from typing import AbstractSet
 | 
				
			||||||
from typing import Dict
 | 
					from typing import Dict
 | 
				
			||||||
from typing import List
 | 
					from typing import List
 | 
				
			||||||
from typing import Mapping
 | 
					from typing import Mapping
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import py
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
from _pytest.compat import nullcontext
 | 
					from _pytest.compat import nullcontext
 | 
				
			||||||
from _pytest.config import create_terminal_writer
 | 
					from _pytest.config import create_terminal_writer
 | 
				
			||||||
| 
						 | 
					@ -223,7 +222,7 @@ class LogCaptureHandler(logging.StreamHandler):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self) -> None:
 | 
					    def __init__(self) -> None:
 | 
				
			||||||
        """Creates a new log handler."""
 | 
					        """Creates a new log handler."""
 | 
				
			||||||
        logging.StreamHandler.__init__(self, py.io.TextIO())
 | 
					        logging.StreamHandler.__init__(self, StringIO())
 | 
				
			||||||
        self.records = []  # type: List[logging.LogRecord]
 | 
					        self.records = []  # type: List[logging.LogRecord]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def emit(self, record: logging.LogRecord) -> None:
 | 
					    def emit(self, record: logging.LogRecord) -> None:
 | 
				
			||||||
| 
						 | 
					@ -233,7 +232,7 @@ class LogCaptureHandler(logging.StreamHandler):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def reset(self) -> None:
 | 
					    def reset(self) -> None:
 | 
				
			||||||
        self.records = []
 | 
					        self.records = []
 | 
				
			||||||
        self.stream = py.io.TextIO()
 | 
					        self.stream = StringIO()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LogCaptureFixture:
 | 
					class LogCaptureFixture:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,6 +10,7 @@ import time
 | 
				
			||||||
import traceback
 | 
					import traceback
 | 
				
			||||||
from collections.abc import Sequence
 | 
					from collections.abc import Sequence
 | 
				
			||||||
from fnmatch import fnmatch
 | 
					from fnmatch import fnmatch
 | 
				
			||||||
 | 
					from io import StringIO
 | 
				
			||||||
from weakref import WeakKeyDictionary
 | 
					from weakref import WeakKeyDictionary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import py
 | 
					import py
 | 
				
			||||||
| 
						 | 
					@ -1221,7 +1222,7 @@ def getdecoded(out):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LineComp:
 | 
					class LineComp:
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        self.stringio = py.io.TextIO()
 | 
					        self.stringio = StringIO()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def assert_contains_lines(self, lines2):
 | 
					    def assert_contains_lines(self, lines2):
 | 
				
			||||||
        """Assert that lines2 are contained (linearly) in lines1.
 | 
					        """Assert that lines2 are contained (linearly) in lines1.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,4 @@
 | 
				
			||||||
 | 
					from io import StringIO
 | 
				
			||||||
from pprint import pprint
 | 
					from pprint import pprint
 | 
				
			||||||
from typing import Optional
 | 
					from typing import Optional
 | 
				
			||||||
from typing import Union
 | 
					from typing import Union
 | 
				
			||||||
| 
						 | 
					@ -180,7 +181,7 @@ class BaseReport:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _report_unserialization_failure(type_name, report_class, reportdict):
 | 
					def _report_unserialization_failure(type_name, report_class, reportdict):
 | 
				
			||||||
    url = "https://github.com/pytest-dev/pytest/issues"
 | 
					    url = "https://github.com/pytest-dev/pytest/issues"
 | 
				
			||||||
    stream = py.io.TextIO()
 | 
					    stream = StringIO()
 | 
				
			||||||
    pprint("-" * 100, stream=stream)
 | 
					    pprint("-" * 100, stream=stream)
 | 
				
			||||||
    pprint("INTERNALERROR: Unknown entry type returned: %s" % type_name, stream=stream)
 | 
					    pprint("INTERNALERROR: Unknown entry type returned: %s" % type_name, stream=stream)
 | 
				
			||||||
    pprint("report_name: %s" % report_class, stream=stream)
 | 
					    pprint("report_name: %s" % report_class, stream=stream)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
This is the script that is actually frozen into an executable: simply executes
 | 
					This is the script that is actually frozen into an executable: simply executes
 | 
				
			||||||
py.test main().
 | 
					pytest main().
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,12 +5,11 @@ import pickle
 | 
				
			||||||
import subprocess
 | 
					import subprocess
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
import textwrap
 | 
					import textwrap
 | 
				
			||||||
 | 
					from io import StringIO
 | 
				
			||||||
from io import UnsupportedOperation
 | 
					from io import UnsupportedOperation
 | 
				
			||||||
from typing import List
 | 
					from typing import List
 | 
				
			||||||
from typing import TextIO
 | 
					from typing import TextIO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import py
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
from _pytest import capture
 | 
					from _pytest import capture
 | 
				
			||||||
from _pytest.capture import CaptureManager
 | 
					from _pytest.capture import CaptureManager
 | 
				
			||||||
| 
						 | 
					@ -894,10 +893,10 @@ def test_dupfile_on_bytesio():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_dupfile_on_textio():
 | 
					def test_dupfile_on_textio():
 | 
				
			||||||
    tio = py.io.TextIO()
 | 
					    sio = StringIO()
 | 
				
			||||||
    f = capture.safe_text_dupfile(tio, "wb")
 | 
					    f = capture.safe_text_dupfile(sio, "wb")
 | 
				
			||||||
    f.write("hello")
 | 
					    f.write("hello")
 | 
				
			||||||
    assert tio.getvalue() == "hello"
 | 
					    assert sio.getvalue() == "hello"
 | 
				
			||||||
    assert not hasattr(f, "name")
 | 
					    assert not hasattr(f, "name")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -133,17 +133,17 @@ class TestReportSerialization:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        reprec = testdir.inline_runsource(
 | 
					        reprec = testdir.inline_runsource(
 | 
				
			||||||
            """
 | 
					            """
 | 
				
			||||||
            import py
 | 
					            import pytest
 | 
				
			||||||
            def test_pass(): pass
 | 
					            def test_pass(): pass
 | 
				
			||||||
            def test_fail(): 0/0
 | 
					            def test_fail(): 0/0
 | 
				
			||||||
            @py.test.mark.skipif("True")
 | 
					            @pytest.mark.skipif("True")
 | 
				
			||||||
            def test_skip(): pass
 | 
					            def test_skip(): pass
 | 
				
			||||||
            def test_skip_imperative():
 | 
					            def test_skip_imperative():
 | 
				
			||||||
                py.test.skip("hello")
 | 
					                pytest.skip("hello")
 | 
				
			||||||
            @py.test.mark.xfail("True")
 | 
					            @pytest.mark.xfail("True")
 | 
				
			||||||
            def test_xfail(): 0/0
 | 
					            def test_xfail(): 0/0
 | 
				
			||||||
            def test_xfail_imperative():
 | 
					            def test_xfail_imperative():
 | 
				
			||||||
                py.test.xfail("hello")
 | 
					                pytest.xfail("hello")
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        reports = reprec.getreports("pytest_runtest_logreport")
 | 
					        reports = reprec.getreports("pytest_runtest_logreport")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,5 @@
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
 | 
					from io import StringIO
 | 
				
			||||||
import py
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import _pytest._code
 | 
					import _pytest._code
 | 
				
			||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
| 
						 | 
					@ -13,7 +12,7 @@ pytestmark = pytest.mark.filterwarnings("ignore:--result-log is deprecated")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_write_log_entry():
 | 
					def test_write_log_entry():
 | 
				
			||||||
    reslog = ResultLog(None, None)
 | 
					    reslog = ResultLog(None, None)
 | 
				
			||||||
    reslog.logfile = py.io.TextIO()
 | 
					    reslog.logfile = StringIO()
 | 
				
			||||||
    reslog.write_log_entry("name", ".", "")
 | 
					    reslog.write_log_entry("name", ".", "")
 | 
				
			||||||
    entry = reslog.logfile.getvalue()
 | 
					    entry = reslog.logfile.getvalue()
 | 
				
			||||||
    assert entry[-1] == "\n"
 | 
					    assert entry[-1] == "\n"
 | 
				
			||||||
| 
						 | 
					@ -21,7 +20,7 @@ def test_write_log_entry():
 | 
				
			||||||
    assert len(entry_lines) == 1
 | 
					    assert len(entry_lines) == 1
 | 
				
			||||||
    assert entry_lines[0] == ". name"
 | 
					    assert entry_lines[0] == ". name"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    reslog.logfile = py.io.TextIO()
 | 
					    reslog.logfile = StringIO()
 | 
				
			||||||
    reslog.write_log_entry("name", "s", "Skipped")
 | 
					    reslog.write_log_entry("name", "s", "Skipped")
 | 
				
			||||||
    entry = reslog.logfile.getvalue()
 | 
					    entry = reslog.logfile.getvalue()
 | 
				
			||||||
    assert entry[-1] == "\n"
 | 
					    assert entry[-1] == "\n"
 | 
				
			||||||
| 
						 | 
					@ -30,7 +29,7 @@ def test_write_log_entry():
 | 
				
			||||||
    assert entry_lines[0] == "s name"
 | 
					    assert entry_lines[0] == "s name"
 | 
				
			||||||
    assert entry_lines[1] == " Skipped"
 | 
					    assert entry_lines[1] == " Skipped"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    reslog.logfile = py.io.TextIO()
 | 
					    reslog.logfile = StringIO()
 | 
				
			||||||
    reslog.write_log_entry("name", "s", "Skipped\n")
 | 
					    reslog.write_log_entry("name", "s", "Skipped\n")
 | 
				
			||||||
    entry = reslog.logfile.getvalue()
 | 
					    entry = reslog.logfile.getvalue()
 | 
				
			||||||
    assert entry[-1] == "\n"
 | 
					    assert entry[-1] == "\n"
 | 
				
			||||||
| 
						 | 
					@ -39,7 +38,7 @@ def test_write_log_entry():
 | 
				
			||||||
    assert entry_lines[0] == "s name"
 | 
					    assert entry_lines[0] == "s name"
 | 
				
			||||||
    assert entry_lines[1] == " Skipped"
 | 
					    assert entry_lines[1] == " Skipped"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    reslog.logfile = py.io.TextIO()
 | 
					    reslog.logfile = StringIO()
 | 
				
			||||||
    longrepr = " tb1\n tb 2\nE tb3\nSome Error"
 | 
					    longrepr = " tb1\n tb 2\nE tb3\nSome Error"
 | 
				
			||||||
    reslog.write_log_entry("name", "F", longrepr)
 | 
					    reslog.write_log_entry("name", "F", longrepr)
 | 
				
			||||||
    entry = reslog.logfile.getvalue()
 | 
					    entry = reslog.logfile.getvalue()
 | 
				
			||||||
| 
						 | 
					@ -118,7 +117,7 @@ class TestWithFunctionIntegration:
 | 
				
			||||||
            raise ValueError
 | 
					            raise ValueError
 | 
				
			||||||
        except ValueError:
 | 
					        except ValueError:
 | 
				
			||||||
            excinfo = _pytest._code.ExceptionInfo.from_current()
 | 
					            excinfo = _pytest._code.ExceptionInfo.from_current()
 | 
				
			||||||
        reslog = ResultLog(None, py.io.TextIO())
 | 
					        reslog = ResultLog(None, StringIO())
 | 
				
			||||||
        reslog.pytest_internalerror(excinfo.getrepr(style=style))
 | 
					        reslog.pytest_internalerror(excinfo.getrepr(style=style))
 | 
				
			||||||
        entry = reslog.logfile.getvalue()
 | 
					        entry = reslog.logfile.getvalue()
 | 
				
			||||||
        entry_lines = entry.splitlines()
 | 
					        entry_lines = entry.splitlines()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,7 @@ import collections
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
import textwrap
 | 
					import textwrap
 | 
				
			||||||
 | 
					from io import StringIO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import pluggy
 | 
					import pluggy
 | 
				
			||||||
import py
 | 
					import py
 | 
				
			||||||
| 
						 | 
					@ -268,7 +269,7 @@ class TestTerminal:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_rewrite(self, testdir, monkeypatch):
 | 
					    def test_rewrite(self, testdir, monkeypatch):
 | 
				
			||||||
        config = testdir.parseconfig()
 | 
					        config = testdir.parseconfig()
 | 
				
			||||||
        f = py.io.TextIO()
 | 
					        f = StringIO()
 | 
				
			||||||
        monkeypatch.setattr(f, "isatty", lambda *args: True)
 | 
					        monkeypatch.setattr(f, "isatty", lambda *args: True)
 | 
				
			||||||
        tr = TerminalReporter(config, f)
 | 
					        tr = TerminalReporter(config, f)
 | 
				
			||||||
        tr._tw.fullwidth = 10
 | 
					        tr._tw.fullwidth = 10
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue