Copy data from src to dst in the most efficient way possible. If follow_symlinks is not set and src is a symbolic link, a new symlink will be created instead of copying the file it points to.
(src, dst, *, follow_symlinks=True)
| 224 | return fn.is_symlink() if isinstance(fn, os.DirEntry) else os.path.islink(fn) |
| 225 | |
| 226 | def copyfile(src, dst, *, follow_symlinks=True): |
| 227 | """Copy data from src to dst in the most efficient way possible. |
| 228 | |
| 229 | If follow_symlinks is not set and src is a symbolic link, a new |
| 230 | symlink will be created instead of copying the file it points to. |
| 231 | |
| 232 | """ |
| 233 | sys.audit("shutil.copyfile", src, dst) |
| 234 | |
| 235 | if _samefile(src, dst): |
| 236 | raise SameFileError("{!r} and {!r} are the same file".format(src, dst)) |
| 237 | |
| 238 | file_size = 0 |
| 239 | for i, fn in enumerate([src, dst]): |
| 240 | try: |
| 241 | st = _stat(fn) |
| 242 | except OSError: |
| 243 | # File most likely does not exist |
| 244 | pass |
| 245 | else: |
| 246 | # XXX What about other special files? (sockets, devices...) |
| 247 | if stat.S_ISFIFO(st.st_mode): |
| 248 | fn = fn.path if isinstance(fn, os.DirEntry) else fn |
| 249 | raise SpecialFileError("`%s` is a named pipe" % fn) |
| 250 | if _WINDOWS and i == 0: |
| 251 | file_size = st.st_size |
| 252 | |
| 253 | if not follow_symlinks and _islink(src): |
| 254 | os.symlink(os.readlink(src), dst) |
| 255 | else: |
| 256 | with open(src, 'rb') as fsrc: |
| 257 | try: |
| 258 | with open(dst, 'wb') as fdst: |
| 259 | # macOS |
| 260 | if _HAS_FCOPYFILE: |
| 261 | try: |
| 262 | _fastcopy_fcopyfile(fsrc, fdst, posix._COPYFILE_DATA) |
| 263 | return dst |
| 264 | except _GiveupOnFastCopy: |
| 265 | pass |
| 266 | # Linux |
| 267 | elif _USE_CP_SENDFILE: |
| 268 | try: |
| 269 | _fastcopy_sendfile(fsrc, fdst) |
| 270 | return dst |
| 271 | except _GiveupOnFastCopy: |
| 272 | pass |
| 273 | # Windows, see: |
| 274 | # https://github.com/python/cpython/pull/7160#discussion_r195405230 |
| 275 | elif _WINDOWS and file_size > 0: |
| 276 | _copyfileobj_readinto(fsrc, fdst, min(file_size, COPY_BUFSIZE)) |
| 277 | return dst |
| 278 | |
| 279 | copyfileobj(fsrc, fdst) |
| 280 | |
| 281 | # Issue 43219, raise a less confusing exception |
| 282 | except IsADirectoryError as e: |
| 283 | if not os.path.exists(dst): |
no test coverage detected