diff --git a/changelog/7336.breaking.rst b/changelog/7336.breaking.rst new file mode 100644 index 00000000000..dc48bab92e5 --- /dev/null +++ b/changelog/7336.breaking.rst @@ -0,0 +1 @@ +The pytest ``log_file`` ini marker is now relative to the configs ``inifile`` directory, as it was always the intention. It was originally introduced as relative to the current working directory unintentionally. diff --git a/src/_pytest/logging.py b/src/_pytest/logging.py index 0163554bae4..e26991c7669 100644 --- a/src/_pytest/logging.py +++ b/src/_pytest/logging.py @@ -560,6 +560,12 @@ def __init__(self, config: Config) -> None: if not os.path.isdir(directory): os.makedirs(directory) + # Log file should be relative to invocation location when passed as a cli argument + # and relative to the config file otherwise. + is_inifile_argument = "--log-file" not in config.invocation_params.args + if config.inipath is not None and is_inifile_argument: + log_file = os.path.join(config.inipath.parent, log_file) + self.log_file_handler = _FileHandler(log_file, mode="w", encoding="UTF-8") log_file_format = get_option_ini(config, "log_file_format", "log_format") log_file_date_format = get_option_ini( diff --git a/testing/logging/test_reporting.py b/testing/logging/test_reporting.py index 323ff7b2446..736ec3a5bde 100644 --- a/testing/logging/test_reporting.py +++ b/testing/logging/test_reporting.py @@ -1165,3 +1165,92 @@ def test_log_file_cli_subdirectories_are_successfully_created( result = pytester.runpytest("--log-file=foo/bar/logf.log") assert "logf.log" in os.listdir(expected) assert result.ret == ExitCode.OK + + +def test_log_file_in_root_dir_when_pytest_invoked_in_subdir(pytester, monkeypatch): + """Issue #7336 - log_file should be relative to the config file when it contains the log_file option.""" + pytester.makeini( + """ + [pytest] + log_file = pytest.log + """ + ) + + subdir = pytester.mkdir("subdir") + testfile = pytester.makepyfile( + """ + def test_this(): + pass + """ + ) + testfile.replace(subdir / testfile) + + monkeypatch.chdir(subdir) + pytester.runpytest() + pytester.chdir() # Restore the initial cwd. + + files_in_root_dir = set(os.listdir()) + assert {"pytest.log", "tox.ini"}.issubset(files_in_root_dir) + + +def test_log_file_in_subdir_when_specified_and_pytest_invoked_in_subdir( + pytester, monkeypatch +): + """Issue #7336 - log_file should be relative to the config file when it contains the log_file option.""" + pytester.makeini( + """ + [pytest] + log_file = subdir/pytest.log + """ + ) + + subdir = pytester.mkdir("subdir") + testfile = pytester.makepyfile( + """ + def test_this(): + pass + """ + ) + testfile.replace(subdir / testfile) + + monkeypatch.chdir(subdir) + pytester.runpytest() + + files_in_subdir = set(os.listdir()) + assert "pytest.log" in files_in_subdir + assert "tox.ini" not in files_in_subdir + + +def test_log_file_relative_to_invocation_dir_when_passed_as_cli_argument( + pytester, monkeypatch +): + """PR #7350 comment related to issue #7350 (https://github.com/pytest-dev/pytest/pull/7350#pullrequestreview-429803796). + + Log_file should be relative to the invocation dir when passed as a commandline argument. + """ + pytester.makeini( + """ + [pytest] + """ + ) + + subdir = pytester.mkdir("subdir") + testfile = pytester.makepyfile( + """ + def test_this(): + pass + """ + ) + testfile.replace(subdir / testfile) + + monkeypatch.chdir(subdir) + pytester.runpytest("--log-file", "pytest.log") + + files_in_subdir = set(os.listdir()) + assert "pytest.log" in files_in_subdir + assert "tox.ini" not in files_in_subdir + + pytester.chdir() # Restore the initial cwd. + files_in_root_dir = set(os.listdir()) + assert "pytest.log" not in files_in_root_dir + assert "tox.ini" in files_in_root_dir