summaryrefslogtreecommitdiffstats
path: root/Lib/shutil.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/shutil.py')
-rw-r--r--Lib/shutil.py16
1 files changed, 14 insertions, 2 deletions
diff --git a/Lib/shutil.py b/Lib/shutil.py
index cae65a3..eecc4be 100644
--- a/Lib/shutil.py
+++ b/Lib/shutil.py
@@ -298,11 +298,15 @@ def copymode(src, dst, *, follow_symlinks=True):
sys.audit("shutil.copymode", src, dst)
if not follow_symlinks and _islink(src) and os.path.islink(dst):
- if hasattr(os, 'lchmod'):
+ if os.name == 'nt':
+ stat_func, chmod_func = os.lstat, os.chmod
+ elif hasattr(os, 'lchmod'):
stat_func, chmod_func = os.lstat, os.lchmod
else:
return
else:
+ if os.name == 'nt' and os.path.islink(dst):
+ dst = os.path.realpath(dst, strict=True)
stat_func, chmod_func = _stat, os.chmod
st = stat_func(src)
@@ -378,8 +382,16 @@ def copystat(src, dst, *, follow_symlinks=True):
# 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)
+ _chmod = lookup("chmod")
+ if os.name == 'nt':
+ if follow:
+ if os.path.islink(dst):
+ dst = os.path.realpath(dst, strict=True)
+ else:
+ def _chmod(*args, **kwargs):
+ os.chmod(*args)
try:
- lookup("chmod")(dst, mode, follow_symlinks=follow)
+ _chmod(dst, mode, follow_symlinks=follow)
except NotImplementedError:
# if we got a NotImplementedError, it's because
# * follow_symlinks=False,