Skip to content
Prev Previous commit
Next Next commit
Speed up ensure_different_files()
  • Loading branch information
barneygale committed Nov 1, 2024
commit 09aff170d392a6f75dedbcded0fdf9b3d9aff111
15 changes: 11 additions & 4 deletions Lib/pathlib/_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,20 @@ def __init__(self, follow_symlinks=True, dirs_exist_ok=False,
self.preserve_metadata = preserve_metadata

@classmethod
def ensure_different_files(cls, source, target):
def ensure_different_files(cls, source, target, dir_entry=None):
"""Raise OSError(EINVAL) if both paths refer to the same file."""
try:
if not target.samefile(source):
return
target_st = target.stat()
try:
source_st = dir_entry.stat()
except AttributeError:
source_st = source.stat()
Comment on lines +113 to +116

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there valid non-None types for dir_entry that don't have stat? Otherwise a is None check is cheaper.

except (OSError, ValueError):
return
if source_st.st_ino != target_st.st_ino:
return # Different inode
if source_st.st_dev != target_st.st_dev:
return # Different device
err = OSError(EINVAL, "Source and target are the same file")
err.filename = str(source)
err.filename2 = str(target)
Expand Down Expand Up @@ -172,7 +179,7 @@ def copy_dir(self, source, target, metadata_keys, dir_entry=None):

def copy_file(self, source, target, metadata_keys, dir_entry=None):
"""Copy the given file to the given target."""
self.ensure_different_files(source, target)
self.ensure_different_files(source, target, dir_entry)
if metadata_keys:
metadata = source._read_metadata(metadata_keys, dir_entry=dir_entry)
else:
Expand Down