Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions Doc/library/shutil.rst
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,15 @@ Directory and files operations
.. versionchanged:: 3.3
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
flags from *src* to *dst*. 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
Copy the permission bits and flags from *src* to *dst*; the last access
time and last modification time are also copied if *preserve_timestamps*
is true (on Windows platforms, *preserve_timestamps* is ignored).
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.

If *follow_symlinks* is false, and *src* and *dst* both
Expand Down Expand Up @@ -169,6 +172,9 @@ Directory and files operations
.. versionchanged:: 3.3
Added *follow_symlinks* argument and support for Linux extended attributes.

.. versionchanged:: next
Added the *preserve_timestamps* argument.

.. function:: copy(src, dst, *, follow_symlinks=True)

Copies the file *src* to the file or directory *dst*. *src* and *dst*
Expand Down Expand Up @@ -201,7 +207,7 @@ Directory and files operations
copy the file more efficiently. See
: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`
also attempts to preserve file metadata.
Expand All @@ -215,6 +221,9 @@ Directory and files operations
it can; :func:`copy2` never raises an exception because it
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.
Please see :func:`copystat` for more information
about platform support for modifying symbolic link metadata.
Expand All @@ -233,6 +242,9 @@ Directory and files operations
copy the file more efficiently. See
:ref:`shutil-platform-dependent-efficient-copy-operations` section.

.. versionadded:: next
Added the *preserve_timestamps* argument.

.. function:: ignore_patterns(*patterns)

This factory function creates a function that can be used as a callable for
Expand Down
23 changes: 13 additions & 10 deletions Lib/shutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,14 +406,15 @@ def _copyxattr(src, dst, *, follow_symlinks=True):
def _copyxattr(*args, **kwargs):
pass

def copystat(src, dst, *, follow_symlinks=True):
def copystat(src, dst, *, follow_symlinks=True, preserve_timestamps=True):
"""Copy file metadata

Copy the permission bits, last access time, last modification time, and
flags from `src` to `dst`. On Linux, copystat() also copies the "extended
attributes" where possible. The file contents, owner, and group are
unaffected. `src` and `dst` are path-like objects or path names given as
strings.
Copy the permission bits and flags from `src` to `dst`; the last access
time and last modification time are also copied if `preserve_timestamps`
is true. On Linux, copystat() also copies the "extended attributes" where
possible. The file contents, owner, and group are unaffected.

`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
followed if and only if both `src` and `dst` are symlinks.
Expand Down Expand Up @@ -443,8 +444,9 @@ def lookup(name):
else:
st = lookup("stat")(src, follow_symlinks=follow)
mode = stat.S_IMODE(st.st_mode)
lookup("utime")(dst, ns=(st.st_atime_ns, st.st_mtime_ns),
follow_symlinks=follow)
if preserve_timestamps:
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)
# chmod()'ed read-only, otherwise setxattr() will error with -EACCES.
_copyxattr(src, dst, follow_symlinks=follow)
Expand Down Expand Up @@ -490,7 +492,7 @@ def copy(src, dst, *, follow_symlinks=True):
copymode(src, dst, follow_symlinks=follow_symlinks)
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.

Metadata is copied with copystat(). Please see the copystat function
Expand Down Expand Up @@ -527,7 +529,8 @@ def copy2(src, dst, *, follow_symlinks=True):
raise

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

def ignore_patterns(*patterns):
Expand Down
Loading