diff --git a/src/memray/_memray/sink.cpp b/src/memray/_memray/sink.cpp index a2e346d8d4..848448515b 100644 --- a/src/memray/_memray/sink.cpp +++ b/src/memray/_memray/sink.cpp @@ -137,6 +137,12 @@ FileSink::FileSink(const std::string& file_name, bool overwrite, bool compress) d_fd = ::open(file_name.c_str(), flags, 0644); } while (d_fd < 0 && errno == EINTR); if (d_fd < 0) { + if (errno == EEXIST) { + throw IoError{ + "Output file " + file_name + + " already exists. Memray can overwrite it with the" + " --force CLI argument or the overwrite=True API argument."}; + } throw IoError{"Could not create output file " + file_name + ": " + std::string(strerror(errno))}; } } @@ -436,6 +442,12 @@ BufferedFileSink::BufferedFileSink(const std::string& file_name, bool overwrite, d_fd = ::open(file_name.c_str(), flags, 0644); } while (d_fd < 0 && errno == EINTR); if (d_fd < 0) { + if (errno == EEXIST) { + throw IoError{ + "Output file " + file_name + + " already exists. Memray can overwrite it with the" + " --force CLI argument or the overwrite=True API argument."}; + } throw IoError{"Could not create output file " + file_name + ": " + std::string(strerror(errno))}; } } diff --git a/src/memray/commands/common.py b/src/memray/commands/common.py index 3ce478c90c..514bba66a5 100644 --- a/src/memray/commands/common.py +++ b/src/memray/commands/common.py @@ -136,7 +136,8 @@ def validate_filenames( ) if not overwrite and output_file.exists(): raise MemrayCommandError( - f"File already exists, will not overwrite: {output_file}", + f"File already exists, will not overwrite without --force:" + f" {output_file}", exit_code=1, ) return result_path, output_file diff --git a/src/memray/commands/stats.py b/src/memray/commands/stats.py index cf9799f967..6034dc53c2 100644 --- a/src/memray/commands/stats.py +++ b/src/memray/commands/stats.py @@ -83,7 +83,8 @@ def run(self, args: argparse.Namespace, parser: argparse.ArgumentParser) -> None if not args.force and json_output_file.exists(): raise MemrayCommandError( - f"File already exists, will not overwrite: {json_output_file}", + f"File already exists, will not overwrite without --force:" + f" {json_output_file}", exit_code=1, ) diff --git a/tests/integration/test_main.py b/tests/integration/test_main.py index 5534a826ef..7f72eeca81 100644 --- a/tests/integration/test_main.py +++ b/tests/integration/test_main.py @@ -529,19 +529,21 @@ def test_run_file_that_is_not_python(self, capsys, option): ) @patch("memray.commands.run.os.getpid") - def test_run_file_exists(self, getpid, tmp_path, monkeypatch, capsys): + @pytest.mark.parametrize("flag", [None, "--buffered-file-io"]) + def test_run_file_exists(self, getpid, tmp_path, monkeypatch, capsys, flag): # GIVEN / WHEN getpid.return_value = 0 (tmp_path / "memray-json.tool.0.bin").touch() monkeypatch.chdir(tmp_path) # THEN - assert main(["run", "-m", "json.tool", "-h"]) == 1 + assert main(["run", *([flag] if flag else ()), "-m", "json.tool", "-h"]) == 1 captured = capsys.readouterr() - assert ( - captured.err.strip() - == "Could not create output file memray-json.tool.0.bin: File exists" + expected_error = ( + "Output file memray-json.tool.0.bin already exists. Memray can overwrite it" + " with the --force CLI argument or the overwrite=True API argument." ) + assert captured.err.strip() == expected_error def test_run_output_file_directory_does_not_exist(self, capsys): # GIVEN / WHEN / THEN