From 7385e3c01bc003ffdf77d8f6e842720bd3f6d870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Fri, 24 Jul 2020 07:40:59 +0100 Subject: [PATCH] Use \n instead if \r\n as line separator (#1905) The logging framework will write to a pipe, which then will blindly transform all carriage returns to carriage return plus line feed, when on Windows. So injecting the \r\n leaves us with double carriage return. Signed-off-by: Bernat Gabor --- docs/changelog/1905.bugfix.rst | 2 ++ src/virtualenv/__main__.py | 3 +-- src/virtualenv/config/ini.py | 2 +- tests/unit/config/test___main__.py | 25 ++++++++++++++++++++++--- 4 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 docs/changelog/1905.bugfix.rst diff --git a/docs/changelog/1905.bugfix.rst b/docs/changelog/1905.bugfix.rst new file mode 100644 index 000000000..9f2576aa7 --- /dev/null +++ b/docs/changelog/1905.bugfix.rst @@ -0,0 +1,2 @@ +Use ``\n`` instead if ``\r\n`` as line separator for report (because Python already performs this transformation +automatically upon write to the logging pipe) - by :user:`gaborbernat`. diff --git a/src/virtualenv/__main__.py b/src/virtualenv/__main__.py index e0e25e452..0995e4c18 100644 --- a/src/virtualenv/__main__.py +++ b/src/virtualenv/__main__.py @@ -1,7 +1,6 @@ from __future__ import absolute_import, print_function, unicode_literals import logging -import os import sys from datetime import datetime @@ -52,7 +51,7 @@ def __str__(self): ) if self.session.activators: lines.append(" activators {}".format(",".join(i.__class__.__name__ for i in self.session.activators))) - return os.linesep.join(lines) + return "\n".join(lines) def run_with_catch(args=None): diff --git a/src/virtualenv/config/ini.py b/src/virtualenv/config/ini.py index c8789475d..4dec629a9 100644 --- a/src/virtualenv/config/ini.py +++ b/src/virtualenv/config/ini.py @@ -75,7 +75,7 @@ def __bool__(self): def epilog(self): msg = "{}config file {} {} (change{} via env var {})" return msg.format( - os.linesep, + "\n", self.config_file, self.STATE[self.has_config_file], "d" if self.is_env_var else "", diff --git a/tests/unit/config/test___main__.py b/tests/unit/config/test___main__.py index adf346422..49a3ee63b 100644 --- a/tests/unit/config/test___main__.py +++ b/tests/unit/config/test___main__.py @@ -1,5 +1,6 @@ from __future__ import absolute_import, unicode_literals +import os import re import sys @@ -65,8 +66,13 @@ def test_session_report_full(session_app_data, tmp_path, capsys): r" added seed packages: .*pip==.*, setuptools==.*, wheel==.*", r" activators .*", ] + _match_regexes(lines, regexes) + + +def _match_regexes(lines, regexes): for line, regex in zip(lines, regexes): - assert re.match(regex, line), line + comp_regex = re.compile(r"^{}$".format(regex)) + assert comp_regex.match(line), line def test_session_report_minimal(session_app_data, tmp_path, capsys): @@ -78,5 +84,18 @@ def test_session_report_minimal(session_app_data, tmp_path, capsys): r"created virtual environment .* in \d+ms", r" creator .*", ] - for line, regex in zip(lines, regexes): - assert re.match(regex, line), line + _match_regexes(lines, regexes) + + +def test_session_report_subprocess(session_app_data, tmp_path): + # when called via a subprocess the logging framework should flush and POSIX line normalization happen + out = subprocess.check_output( + [sys.executable, "-m", "virtualenv", str(tmp_path), "--activators", "powershell", "--without-pip"], + ) + lines = out.decode().split(os.linesep) + regexes = [ + r"created virtual environment .* in \d+ms", + r" creator .*", + r" activators .*", + ] + _match_regexes(lines, regexes)