From 5bd5b8c68aed33ad6b74f79208ef012e0b16c232 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Fri, 29 Jun 2018 11:35:43 +0200 Subject: [PATCH 1/7] fix #3631 - don't store legacy markinfo when its impossible --- changelog/3631.bugfix.rst | 1 + src/_pytest/mark/structures.py | 2 +- testing/test_mark.py | 13 +++++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 changelog/3631.bugfix.rst diff --git a/changelog/3631.bugfix.rst b/changelog/3631.bugfix.rst new file mode 100644 index 000000000..261c41ccd --- /dev/null +++ b/changelog/3631.bugfix.rst @@ -0,0 +1 @@ +No longer raise AttributeError when legacy marks can't be stored. diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py index d416e422b..3fb15bbc2 100644 --- a/src/_pytest/mark/structures.py +++ b/src/_pytest/mark/structures.py @@ -259,7 +259,7 @@ def store_legacy_markinfo(func, mark): if holder is None: holder = MarkInfo.for_mark(mark) setattr(func, mark.name, holder) - else: + elif isinstance(holder, MarkInfo): holder.add_mark(mark) diff --git a/testing/test_mark.py b/testing/test_mark.py index f87a4eded..e3d28189c 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -63,6 +63,19 @@ class TestMark(object): mark.hello(f) assert f.hello + def test_mark_legacy_ignore_fail(self): + def add_attribute(func): + func.foo = 1 + return func + + @pytest.mark.foo + @add_attribute + def test_fun(): + pass + + assert test_fun.foo == 1 + assert test_fun.pytestmark + @ignore_markinfo def test_pytest_mark_keywords(self): mark = Mark() From 342f2cdc17d5030ddc59d88b647fbc4c732c502d Mon Sep 17 00:00:00 2001 From: Victor Date: Fri, 29 Jun 2018 16:09:39 +0200 Subject: [PATCH 2/7] Fixes #3630 --- src/_pytest/logging.py | 4 +++- testing/logging/test_reporting.py | 34 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/_pytest/logging.py b/src/_pytest/logging.py index 70b6592c4..ae1a80c50 100644 --- a/src/_pytest/logging.py +++ b/src/_pytest/logging.py @@ -392,7 +392,9 @@ class LoggingPlugin(object): config, "log_file_date_format", "log_date_format" ) # Each pytest runtests session will write to a clean logfile - self.log_file_handler = logging.FileHandler(log_file, mode="w") + self.log_file_handler = logging.FileHandler( + log_file, mode="w", encoding="UTF-8" + ) log_file_formatter = logging.Formatter( log_file_format, datefmt=log_file_date_format ) diff --git a/testing/logging/test_reporting.py b/testing/logging/test_reporting.py index 0a8a58506..0bd12f0a3 100644 --- a/testing/logging/test_reporting.py +++ b/testing/logging/test_reporting.py @@ -827,6 +827,40 @@ def test_log_file_ini_level(testdir): assert "This log message won't be shown" not in contents +def test_log_file_unicode(testdir): + log_file = testdir.tmpdir.join("pytest.log").strpath + + testdir.makeini( + """ + [pytest] + log_file={} + log_file_level = INFO + """.format( + log_file + ) + ) + testdir.makepyfile( + """ + import logging + def test_log_file(): + logging.getLogger('catchlog').info("Normal message") + logging.getLogger('catchlog').info("\u251c") + logging.getLogger('catchlog').info("Another normal message") + """ + ) + + result = testdir.runpytest() + + # make sure that that we get a '0' exit code for the testsuite + assert result.ret == 0 + assert os.path.isfile(log_file) + with open(log_file, encoding="utf-8") as rfh: + contents = rfh.read() + assert "Normal message" in contents + assert "\u251c" in contents + assert "Another normal message" in contents + + @pytest.mark.parametrize("has_capture_manager", [True, False]) def test_live_logging_suspends_capture(has_capture_manager, request): """Test that capture manager is suspended when we emitting messages for live logging. From 738933938a51f324187bef3188eb2d8ea69e83b9 Mon Sep 17 00:00:00 2001 From: Victor Date: Fri, 29 Jun 2018 16:18:16 +0200 Subject: [PATCH 3/7] Added changelog. --- changelog/3630.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/3630.bugfix.rst diff --git a/changelog/3630.bugfix.rst b/changelog/3630.bugfix.rst new file mode 100644 index 000000000..505bcb8fd --- /dev/null +++ b/changelog/3630.bugfix.rst @@ -0,0 +1 @@ +Log messages with unicode characters would not appear in the output log file. From a6636fddcdcbb198e750f4097d5d0c08442e1f00 Mon Sep 17 00:00:00 2001 From: Victor Date: Fri, 29 Jun 2018 17:04:30 +0200 Subject: [PATCH 4/7] Fixed open function with encoding in python 2.7 --- testing/logging/test_reporting.py | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/logging/test_reporting.py b/testing/logging/test_reporting.py index 0bd12f0a3..1f961d94a 100644 --- a/testing/logging/test_reporting.py +++ b/testing/logging/test_reporting.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import re import os +from io import open import six From 3a1c15316b55656ed57355dec27d223e378bf481 Mon Sep 17 00:00:00 2001 From: Victor Date: Sat, 30 Jun 2018 16:11:20 +0200 Subject: [PATCH 5/7] Updated test for python 2.7 --- testing/logging/test_reporting.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/testing/logging/test_reporting.py b/testing/logging/test_reporting.py index 1f961d94a..925821d2e 100644 --- a/testing/logging/test_reporting.py +++ b/testing/logging/test_reporting.py @@ -842,10 +842,13 @@ def test_log_file_unicode(testdir): ) testdir.makepyfile( """ + # -*- coding: utf-8 -*- + from __future__ import unicode_literals import logging + def test_log_file(): logging.getLogger('catchlog').info("Normal message") - logging.getLogger('catchlog').info("\u251c") + logging.getLogger('catchlog').info("├") logging.getLogger('catchlog').info("Another normal message") """ ) @@ -858,7 +861,7 @@ def test_log_file_unicode(testdir): with open(log_file, encoding="utf-8") as rfh: contents = rfh.read() assert "Normal message" in contents - assert "\u251c" in contents + assert six.unichr(0x251c) in contents assert "Another normal message" in contents From dad3e773198a95e49a0b5a1e805bd0318c508996 Mon Sep 17 00:00:00 2001 From: victor Date: Sat, 30 Jun 2018 18:57:24 +0200 Subject: [PATCH 6/7] Improve test readability. --- testing/logging/test_reporting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/logging/test_reporting.py b/testing/logging/test_reporting.py index 925821d2e..07c092191 100644 --- a/testing/logging/test_reporting.py +++ b/testing/logging/test_reporting.py @@ -861,7 +861,7 @@ def test_log_file_unicode(testdir): with open(log_file, encoding="utf-8") as rfh: contents = rfh.read() assert "Normal message" in contents - assert six.unichr(0x251c) in contents + assert u"├" in contents assert "Another normal message" in contents From a43205b4bc572aad746b9fbd6f6701722d86bce1 Mon Sep 17 00:00:00 2001 From: "T.E.A de Souza" Date: Mon, 2 Jul 2018 21:01:41 +0800 Subject: [PATCH 7/7] Fix monkeypatch doc `delenv` is incorrectly documented. --- src/_pytest/monkeypatch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_pytest/monkeypatch.py b/src/_pytest/monkeypatch.py index e6928f96b..22ffffd4c 100644 --- a/src/_pytest/monkeypatch.py +++ b/src/_pytest/monkeypatch.py @@ -22,7 +22,7 @@ def monkeypatch(): monkeypatch.setitem(mapping, name, value) monkeypatch.delitem(obj, name, raising=True) monkeypatch.setenv(name, value, prepend=False) - monkeypatch.delenv(name, value, raising=True) + monkeypatch.delenv(name, raising=True) monkeypatch.syspath_prepend(path) monkeypatch.chdir(path)