You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
pathlib fast-copy can silently produce an empty destination after a zero-byte syscall #159395
The fast-copy helpers in pathlib._os treat an initial zero-byte result from os.copy_file_range() or os.sendfile() as normal EOF, even when no data was copied.
Some filesystems can return zero for an unsuccessful fast copy. The existing shutil._fastcopy_copy_file_range() code already guards against this case by falling back when zero is returned before any data has been copied (see Lib/shutil.py and the Linux filesystem discussion).
A nonempty Path.copy() source can therefore produce an empty destination without raising an exception. This also affects Path.move() across devices: its fallback copies the source and then deletes it, so the zero-byte result could cause data loss.
Reproducer (Linux, current main)
The example uses fault injection to simulate a zero-byte syscall result. It does not establish that the issue occurs on every filesystem.
frompathlibimportPathfromtempfileimportTemporaryDirectoryfromunittest.mockimportpatchimportpathlib._oswithTemporaryDirectory() asdirectory:
source=Path(directory, "source")
target=Path(directory, "target")
source.write_bytes(b"important data")
with (
patch("pathlib._os._ficlone", None),
patch("pathlib._os._fcopyfile", None),
patch("pathlib._os.os.copy_file_range", return_value=0),
patch("pathlib._os.os.sendfile", return_value=0),
):
source.copy(target)
print("source:", source.read_bytes())
print("target:", target.read_bytes())
# Before the fix, target is b''.
The proposed fix treats zero bytes copied on the first fast-copy call as a reason to try the next mechanism, eventually using buffered copying if needed. A zero-byte return after some data was copied still ends the fast-copy loop. A truly empty source remains supported.
Environment and validation
Affects the implementation in CPython main (also relevant to versions with Path.copy()).
The behavior was reproduced with the extracted fast-copy logic on Python 3.13 under Linux and mocked syscall results.
The complete CPython development-branch test suite has not yet been run locally.
Activity
pythongh-159395: add NEWS entry for pathlib fast-copy fallback