diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 3a4631e7c657fe..1968f0dcf75a51 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -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 ` 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 ` or path names given as strings. If *follow_symlinks* is false, and *src* and *dst* both @@ -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* @@ -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. @@ -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. @@ -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 diff --git a/Lib/shutil.py b/Lib/shutil.py index 8d8fe145567822..266b64fcebbbb6 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -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. @@ -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) @@ -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 @@ -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):