Skip to content

Commit

Permalink
fix codecache write_atomic path issue on Windows. (pytorch#138331)
Browse files Browse the repository at this point in the history
Fixes pytorch#138211

`Path.rename` function has Windows OS specific behavior, that will raise `FileExistsError` when the target file existing.
This behavior is not happened on Linux, so I write a small repoduce code to figure out what happened.

After stepping trace the repo code:
```python
import os
import sys
from pathlib import Path

_IS_WINDOWS = sys.platform == "win32"

def test_case():
    cwd = os.getcwd()
    path1 = os.path.join(cwd, "haha1.txt")
    path2 = Path(os.path.join(cwd, "haha2.txt"))

    try:
        path2.rename(path1)
    except FileExistsError as e_file_exist:
        if _IS_WINDOWS:
            # on Windows file exist is expected: https://docs.python.org/3/library/pathlib.html#pathlib.Path.rename
            shutil.copy2(path2, path1)
            os.remove(path2)
        else:
            raise e_file_exist
    except BaseException as e:
        raise e

    print("run here.")

if __name__ == "__main__":
    test_case()
```
We found the code `path2.rename(path1)` can breakdown into:
1. copy file2's content to file1.
2. delete file2.

So, we can implemented equal code on Windows path:
```python
shutil.copy2(src=tmp_path, dst=path)
os.remove(tmp_path)
```

So, we can get current PR.

TODO: need cherry-pick to release/2.5 branch, CC: @atalman .

Pull Request resolved: pytorch#138331
Approved by: https://github.com/malfet

Co-authored-by: Nikita Shulga <[email protected]>
  • Loading branch information
2 people authored and pytorchmergebot committed Oct 19, 2024
1 parent 949b6f6 commit d5035f0
Showing 1 changed file with 11 additions and 1 deletion.
12 changes: 11 additions & 1 deletion torch/_inductor/codecache.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,17 @@ def write_atomic(
write_mode = "w" if isinstance(content, str) else "wb"
with tmp_path.open(write_mode, encoding="utf-8" if encode_utf_8 else None) as f:
f.write(content)
tmp_path.rename(path)
try:
tmp_path.rename(target=path)
except FileExistsError as e_file_exist:
if not _IS_WINDOWS:
raise
# On Windows file exist is expected: https://docs.python.org/3/library/pathlib.html#pathlib.Path.rename
# Below two lines code is equal to `tmp_path.rename(path)` on non-Windows OS.
# 1. Copy tmp_file to Target(Dst) file.
shutil.copy2(src=tmp_path, dst=path)
# 2. Delete tmp_file.
os.remove(tmp_path)


@dataclasses.dataclass
Expand Down

0 comments on commit d5035f0

Please sign in to comment.