This commit is contained in:
Bénédikt Tran 2025-12-08 06:12:18 +02:00 committed by GitHub
commit 5ba346fc6f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 31 additions and 16 deletions

View file

@ -122,12 +122,15 @@ Directory and files operations
.. versionchanged:: 3.3 .. versionchanged:: 3.3
Added *follow_symlinks* argument. Added *follow_symlinks* argument.
.. function:: copystat(src, dst, *, follow_symlinks=True) .. function:: copystat(src, dst, *, follow_symlinks=True, preserve_timestamps=True)
Copy the permission bits, last access time, last modification time, and Copy the permission bits and flags from *src* to *dst*; the last access
flags from *src* to *dst*. On Linux, :func:`copystat` also copies the time and last modification time are also copied if *preserve_timestamps*
"extended attributes" where possible. The file contents, owner, and is true (on Windows platforms, *preserve_timestamps* is ignored).
group are unaffected. *src* and *dst* are :term:`path-like objects <path-like object>` or path On Linux, :func:`copystat` also copies the "extended attributes"
where possible. The file contents, owner, and group are unaffected.
*src* and *dst* are :term:`path-like objects <path-like object>` or path
names given as strings. names given as strings.
If *follow_symlinks* is false, and *src* and *dst* both If *follow_symlinks* is false, and *src* and *dst* both
@ -169,6 +172,9 @@ Directory and files operations
.. versionchanged:: 3.3 .. versionchanged:: 3.3
Added *follow_symlinks* argument and support for Linux extended attributes. Added *follow_symlinks* argument and support for Linux extended attributes.
.. versionchanged:: next
Added the *preserve_timestamps* argument.
.. function:: copy(src, dst, *, follow_symlinks=True) .. function:: copy(src, dst, *, follow_symlinks=True)
Copies the file *src* to the file or directory *dst*. *src* and *dst* Copies the file *src* to the file or directory *dst*. *src* and *dst*
@ -201,7 +207,7 @@ Directory and files operations
copy the file more efficiently. See copy the file more efficiently. See
:ref:`shutil-platform-dependent-efficient-copy-operations` section. :ref:`shutil-platform-dependent-efficient-copy-operations` section.
.. function:: copy2(src, dst, *, follow_symlinks=True) .. function:: copy2(src, dst, *, follow_symlinks=True, preserve_timestamps=True)
Identical to :func:`~shutil.copy` except that :func:`copy2` Identical to :func:`~shutil.copy` except that :func:`copy2`
also attempts to preserve file metadata. also attempts to preserve file metadata.
@ -215,6 +221,9 @@ Directory and files operations
it can; :func:`copy2` never raises an exception because it it can; :func:`copy2` never raises an exception because it
cannot preserve file metadata. cannot preserve file metadata.
On non-Windows platforms, if *preserve_timestamps* is false,
the last access time and last modification time are not copied.
:func:`copy2` uses :func:`copystat` to copy the file metadata. :func:`copy2` uses :func:`copystat` to copy the file metadata.
Please see :func:`copystat` for more information Please see :func:`copystat` for more information
about platform support for modifying symbolic link metadata. about platform support for modifying symbolic link metadata.
@ -233,6 +242,9 @@ Directory and files operations
copy the file more efficiently. See copy the file more efficiently. See
:ref:`shutil-platform-dependent-efficient-copy-operations` section. :ref:`shutil-platform-dependent-efficient-copy-operations` section.
.. versionadded:: next
Added the *preserve_timestamps* argument.
.. function:: ignore_patterns(*patterns) .. function:: ignore_patterns(*patterns)
This factory function creates a function that can be used as a callable for This factory function creates a function that can be used as a callable for

View file

@ -406,14 +406,15 @@ def _copyxattr(src, dst, *, follow_symlinks=True):
def _copyxattr(*args, **kwargs): def _copyxattr(*args, **kwargs):
pass pass
def copystat(src, dst, *, follow_symlinks=True): def copystat(src, dst, *, follow_symlinks=True, preserve_timestamps=True):
"""Copy file metadata """Copy file metadata
Copy the permission bits, last access time, last modification time, and Copy the permission bits and flags from `src` to `dst`; the last access
flags from `src` to `dst`. On Linux, copystat() also copies the "extended time and last modification time are also copied if `preserve_timestamps`
attributes" where possible. The file contents, owner, and group are is true. On Linux, copystat() also copies the "extended attributes" where
unaffected. `src` and `dst` are path-like objects or path names given as possible. The file contents, owner, and group are unaffected.
strings.
`src` and `dst` are path-like objects or path names given as strings.
If the optional flag `follow_symlinks` is not set, symlinks aren't If the optional flag `follow_symlinks` is not set, symlinks aren't
followed if and only if both `src` and `dst` are symlinks. followed if and only if both `src` and `dst` are symlinks.
@ -443,8 +444,9 @@ def lookup(name):
else: else:
st = lookup("stat")(src, follow_symlinks=follow) st = lookup("stat")(src, follow_symlinks=follow)
mode = stat.S_IMODE(st.st_mode) mode = stat.S_IMODE(st.st_mode)
lookup("utime")(dst, ns=(st.st_atime_ns, st.st_mtime_ns), if preserve_timestamps:
follow_symlinks=follow) lookup("utime")(dst, ns=(st.st_atime_ns, st.st_mtime_ns),
follow_symlinks=follow)
# We must copy extended attributes before the file is (potentially) # We must copy extended attributes before the file is (potentially)
# chmod()'ed read-only, otherwise setxattr() will error with -EACCES. # chmod()'ed read-only, otherwise setxattr() will error with -EACCES.
_copyxattr(src, dst, follow_symlinks=follow) _copyxattr(src, dst, follow_symlinks=follow)
@ -490,7 +492,7 @@ def copy(src, dst, *, follow_symlinks=True):
copymode(src, dst, follow_symlinks=follow_symlinks) copymode(src, dst, follow_symlinks=follow_symlinks)
return dst return dst
def copy2(src, dst, *, follow_symlinks=True): def copy2(src, dst, *, follow_symlinks=True, preserve_timestamps=True):
"""Copy data and metadata. Return the file's destination. """Copy data and metadata. Return the file's destination.
Metadata is copied with copystat(). Please see the copystat function Metadata is copied with copystat(). Please see the copystat function
@ -527,7 +529,8 @@ def copy2(src, dst, *, follow_symlinks=True):
raise raise
copyfile(src, dst, follow_symlinks=follow_symlinks) copyfile(src, dst, follow_symlinks=follow_symlinks)
copystat(src, dst, follow_symlinks=follow_symlinks) copystat(src, dst, follow_symlinks=follow_symlinks,
preserve_timestamps=preserve_timestamps)
return dst return dst
def ignore_patterns(*patterns): def ignore_patterns(*patterns):