def copystat(src, dst, follow_symlinks=True): """Copy all stat info (mode bits, atime, mtime, flags) from src to dst. If the optional flag `follow_symlinks` is not set, symlinks aren't followed if and only if both `src` and `dst` are symlinks. """ def _nop(*args, **kwargs): # pylint: disable=unused-argument pass # follow symlinks (aka don't not follow symlinks) follow = follow_symlinks or not (os.path.islink(src) and os.path.islink(dst)) if follow: # use the real function if it exists def lookup(name): return getattr(os, name, _nop) else: # use the real function only if it exists # *and* it supports follow_symlinks def lookup(name): fn = getattr(os, name, _nop) # pylint: disable=invalid-name if fn in os.supports_follow_symlinks: # pylint: disable=no-member return fn return _nop st = lookup("stat")(src, follow_symlinks=follow) # pylint: disable=invalid-name mode = stat.S_IMODE(st.st_mode) try: lookup("utime")(dst, ns=(st.st_atime_ns, st.st_mtime_ns), follow_symlinks=follow) except OSError: pass try: lookup("chmod")(dst, mode, follow_symlinks=follow) except NotImplementedError: # if we got a NotImplementedError, it's because # * follow_symlinks=False, # * lchown() is unavailable, and # * either # * fchownat() is unavailable or # * fchownat() doesn't implement AT_SYMLINK_NOFOLLOW. # (it returned ENOSUP.) # therefore we're out of options--we simply cannot chown the # symlink. give up, suppress the error. # (which is what shutil always did in this circumstance.) pass except OSError: pass if hasattr(st, "st_flags"): try: lookup("chflags")(dst, st.st_flags, follow_symlinks=follow) except OSError: pass try: _copyxattr(src, dst, follow_symlinks=follow) except OSError: pass
def copystat(src, dst, follow_symlinks=True): """Copy all stat info (mode bits, atime, mtime, flags) from src to dst. If the optional flag `follow_symlinks` is not set, symlinks aren't followed if and only if both `src` and `dst` are symlinks. """ def _nop(*args, **kwargs): # pylint: disable=unused-argument pass # follow symlinks (aka don't not follow symlinks) follow = follow_symlinks or not (os.path.islink(src) and os.path.islink(dst)) if follow: # use the real function if it exists def lookup(name): return getattr(os, name, _nop) else: # use the real function only if it exists # *and* it supports follow_symlinks def lookup(name): fn = getattr(os, name, _nop) # pylint: disable=invalid-name if fn in os.supports_follow_symlinks: # pylint: disable=no-member return fn return _nop st = lookup("stat")(src, follow_symlinks=follow) # pylint: disable=invalid-name mode = stat.S_IMODE(st.st_mode) try: lookup("utime")(dst, ns=(st.st_atime_ns, st.st_mtime_ns), follow_symlinks=follow) except OSError: pass try: lookup("chmod")(dst, mode, follow_symlinks=follow) except NotImplementedError: # if we got a NotImplementedError, it's because # * follow_symlinks=False, # * lchown() is unavailable, and # * either # * fchownat() is unavailable or # * fchownat() doesn't implement AT_SYMLINK_NOFOLLOW. # (it returned ENOSUP.) # therefore we're out of options--we simply cannot chown the # symlink. give up, suppress the error. # (which is what shutil always did in this circumstance.) pass except OSError: pass if hasattr(st, 'st_flags'): try: lookup("chflags")(dst, st.st_flags, follow_symlinks=follow) except OSError: pass try: _copyxattr(src, dst, follow_symlinks=follow) except OSError: pass
def set_owner_mode_xattr(src, dst, follow_symlinks=False): if isinstance(src, DirEntry): src_stat = src.stat(follow_symlinks=follow_symlinks) else: src = Path(src) if src.is_symlink(): src_stat = src.stat() if (follow_symlinks and src.exists()) else src.lstat() else: src_stat = src.stat() if isinstance(dst, DirEntry): dst_stat = dst.stat(follow_symlinks=follow_symlinks) else: dst = Path(dst) # this can raise file not found for .stat() when target to symlink # doesn't exist handle this by adding option ignore dangling links if dst.is_symlink(): dst_stat = dst.stat() if (follow_symlinks and dst.exists()) else dst.lstat() else: dst_stat = dst.stat() # set mode and extra attributes if not (src_stat.st_mode == dst_stat.st_mode): # try except not necessary? os.chmod(dst, mode=src_stat.st_mode) shutil._copyxattr(src, dst, follow_symlinks=follow_symlinks) # set time atime, mtime src_times = (src_stat.st_atime_ns, src_stat.st_mtime_ns) dst_times = (dst_stat.st_atime_ns, dst_stat.st_mtime_ns) if not src_times == dst_times: os.utime(dst, ns=(src_stat.st_atime_ns, src_stat.st_mtime_ns), follow_symlinks=follow_symlinks) # change ownership isuser = (src_stat.st_uid == os.getuid()) isgroup = (src_stat.st_gid == os.getgid()) # if file is not owned by user running the program if not (isuser and isgroup): try: os.chown(dst, src_stat.st_uid, src_stat.st_gid, follow_symlinks=follow_symlinks) except PermissionError as ex: raise PermissionError(f"Mismatch: {ex.filename} " "ownership cannot be assigned.")
def update_event(self, inp=-1): self.set_output_val(0, shutil._copyxattr())