Skip to content

shutil.copyfile should use ReFS block-level linking on Windows (by invoking CopyFileW) #137074

Description

@Dico200

Bug report

Bug description:

shutil.copyfile("./scratch.txt", "./target.txt")

copyfile for copies within a single ReFS volume (or Dev Drive) on Windows 11 does not take advantage of block-level linking capability present in ReFS file system. On the other hand, the kernel automatically does so when you invoke CopyFileW these days. C#/.NET use kernel functions for file copy APIs and automatically take advantage of this too.

Python does not offer an API that takes advantage of block-level linking except for directly invoking CopyFileW using windlls.kernel32 from ctypes.

https://docs.python.org/3/library/shutil.html#shutil-platform-dependent-efficient-copy-operations
CopyFileW should be used instead of streaming data from one file to another, at least in circumstances where block-level linking is possible.

Relevant code:

with open(src, 'rb') as fsrc:

CPython versions tested on:

3.9

Operating systems tested on:

Windows

Activity

  1. added
    stdlibStandard Library Python modules in the Lib/ directory
    type-featureA feature request or enhancement
    and removed
    type-bugAn unexpected behavior, bug, or error
    on Jul 24, 2025
  2. cmaloney commented on Jul 24, 2025

    @cmaloney
    Contributor

    This was looked at in 2018 and decided against in gh-77852 which added the platform-specific optimizations because it was slower (see: #77852 (comment) high level, for details see: #7160 (comment) and the comments starting at #7160 (comment)).

    In 2019 it looks like more discussion of CopyFileW occured (gh-83087) with the leaning "use CopyFile" everywhere. It sounds like in newer Windows this might be faster (so this should be gated by a windows version potentially), would need benchmarks to validate.

  3. zooba commented on Jul 28, 2025

    @zooba
    Member

    copy2 already uses the more efficient way, because the default copy API on Windows includes metadata. copyfile unfortunately is not supposed to copy metadata, and so it can't use the fast option.

    If we can change the definition of copyfile to allow it to copy metadata without breaking anyone, then we can make it faster. Otherwise, we're stuck trying to imitate POSIX semantics.

  4. Dico200 commented on Aug 11, 2025

    @Dico200
    Author

    @zooba based on testing I can confirm that copy2 is affected by this issue.
    Metadata can be changed after invoking CopyFileW.

  5. zooba commented on Aug 12, 2025

    @zooba
    Member

    copy2 is affected by this issue

    What does this mean? Are you saying that copy2 doesn't use copy-on-write? Or that it does?

  6. Dico200 commented on Aug 24, 2025

    @Dico200
    Author

    copy2 is affected by this issue

    What does this mean? Are you saying that copy2 doesn't use copy-on-write? Or that it does?

    I am saying that copy2 does NOT use copy-on-write. I replaced copy2 with a call to CopyFileW via ctypes and it saves loads of space on ReFS drives with the change to CopyFileW.

  7. zooba commented on Aug 25, 2025

    @zooba
    Member

    That surprises me, they should both be calling through to the same underlying API with the same settings (based on how we're calling it from _winapi).

    Can you share your test scripts and system configuration (OS version, in particular)?

  8. Dico200 commented on Sep 7, 2025

    @Dico200
    Author

    It is Windows 11 version 26100, python 3.5.2 I think running a script that was converted by pyinstaller and invoking shutil.copy2.
    When I looked at the code (linked in the issue) it appeared unimplemented, if you're positive that it is for copy2 then feel free to close.

  9. Dico200 commented on Sep 7, 2025

    @Dico200
    Author
    • I can see the part of copy2 that should cover this case (it appears to call CopyFile2 from winapi). I'll assume this is a python version thing and close the issue. I don't have a minimal test case, just many filled up hard drives, but we have a solution now with ctypes CopyFileW that works great.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    OS-windowsstdlibStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions