diff --git a/changelog/7781.bugfix.rst b/changelog/7781.bugfix.rst new file mode 100644 index 00000000000..191fcd4daf4 --- /dev/null +++ b/changelog/7781.bugfix.rst @@ -0,0 +1 @@ +Fix writing non-encodable text to log file when using ``--debug``. diff --git a/changelog/7786.bugfix.rst b/changelog/7786.bugfix.rst new file mode 100644 index 00000000000..a83cc5c9845 --- /dev/null +++ b/changelog/7786.bugfix.rst @@ -0,0 +1 @@ +Fix setting of ``PYTEST_CURRENT_TEST`` when the current locale cannot encode the test name. diff --git a/src/_pytest/helpconfig.py b/src/_pytest/helpconfig.py index 348a65edec6..d1e48e7e3b6 100644 --- a/src/_pytest/helpconfig.py +++ b/src/_pytest/helpconfig.py @@ -100,7 +100,7 @@ def pytest_cmdline_parse(): config = outcome.get_result() # type: Config if config.option.debug: path = os.path.abspath("pytestdebug.log") - debugfile = open(path, "w") + debugfile = open(path, "w", encoding="UTF-8") debugfile.write( "versions pytest-%s, py-%s, " "python-%s\ncwd=%s\nargs=%s\n\n" diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index f29d356fe07..79dd6b34eb9 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -189,7 +189,13 @@ def _update_current_test_var( value = "{} ({})".format(item.nodeid, when) # don't allow null bytes on environment variables (see #2644, #2957) value = value.replace("\x00", "(null)") - os.environ[var_name] = value + # if we are running with a locale that cannot encode the test name + # and we're on a system where os.environb is supported, explicitly + # encode using UTF-8 (otherwise we get an EncodeError) + if os.supports_bytes_environ: + os.environb[var_name.encode()] = value.encode() + else: + os.environ[var_name] = value else: os.environ.pop(var_name) diff --git a/testing/test_helpconfig.py b/testing/test_helpconfig.py index 6116242ec0d..d0f6612715b 100644 --- a/testing/test_helpconfig.py +++ b/testing/test_helpconfig.py @@ -108,6 +108,21 @@ def test_debug(testdir): assert "pytest_sessionstart" in p.read() +def test_debug_with_non_ascii_test_name(testdir, monkeypatch): + testdir.makepyfile( + """\ + def test4_чћшђ_čćšđ(): + pass + """ + ) + # force ASCII default io encoding (PYTHONIOENCODING didn't seem to work?) + monkeypatch.setenv("LANG", "C") + result = testdir.runpytest_subprocess("--debug") + assert result.ret == ExitCode.OK + log_contents = testdir.tmpdir.join("pytestdebug.log").read_binary() + assert b"pytest_sessionstart" in log_contents + + def test_PYTEST_DEBUG(testdir, monkeypatch): monkeypatch.setenv("PYTEST_DEBUG", "1") result = testdir.runpytest_subprocess()