@@ -106,13 +106,20 @@ def __init__(self, follow_symlinks=True, dirs_exist_ok=False,
106106 self .preserve_metadata = preserve_metadata
107107
108108 @classmethod
109- def ensure_different_files (cls , source , target ):
109+ def ensure_different_files (cls , source , target , dir_entry = None ):
110110 """Raise OSError(EINVAL) if both paths refer to the same file."""
111111 try :
112- if not target .samefile (source ):
113- return
112+ target_st = target .stat ()
113+ try :
114+ source_st = dir_entry .stat ()
115+ except AttributeError :
116+ source_st = source .stat ()
114117 except (OSError , ValueError ):
115118 return
119+ if source_st .st_ino != target_st .st_ino :
120+ return # Different inode
121+ if source_st .st_dev != target_st .st_dev :
122+ return # Different device
116123 err = OSError (EINVAL , "Source and target are the same file" )
117124 err .filename = str (source )
118125 err .filename2 = str (target )
@@ -172,7 +179,7 @@ def copy_dir(self, source, target, metadata_keys, dir_entry=None):
172179
173180 def copy_file (self , source , target , metadata_keys , dir_entry = None ):
174181 """Copy the given file to the given target."""
175- self .ensure_different_files (source , target )
182+ self .ensure_different_files (source , target , dir_entry )
176183 if metadata_keys :
177184 metadata = source ._read_metadata (metadata_keys , dir_entry = dir_entry )
178185 else :
0 commit comments