Kaydet (Commit) acdc56d0 authored tarafından Ned Deily's avatar Ned Deily

Issue #14662: Prevent shutil failures on OS X when destination does not

support chflag operations.  (Patch by Hynek Schlawack)
üst b79a01f9
...@@ -102,8 +102,10 @@ def copystat(src, dst): ...@@ -102,8 +102,10 @@ def copystat(src, dst):
try: try:
os.chflags(dst, st.st_flags) os.chflags(dst, st.st_flags)
except OSError, why: except OSError, why:
if (not hasattr(errno, 'EOPNOTSUPP') or for err in 'EOPNOTSUPP', 'ENOTSUP':
why.errno != errno.EOPNOTSUPP): if hasattr(errno, err) and why.errno == getattr(errno, err):
break
else:
raise raise
def copy(src, dst): def copy(src, dst):
......
...@@ -7,6 +7,7 @@ import sys ...@@ -7,6 +7,7 @@ import sys
import stat import stat
import os import os
import os.path import os.path
import errno
from os.path import splitdrive from os.path import splitdrive
from distutils.spawn import find_executable, spawn from distutils.spawn import find_executable, spawn
from shutil import (_make_tarball, _make_zipfile, make_archive, from shutil import (_make_tarball, _make_zipfile, make_archive,
...@@ -339,6 +340,35 @@ class TestShutil(unittest.TestCase): ...@@ -339,6 +340,35 @@ class TestShutil(unittest.TestCase):
shutil.rmtree(TESTFN, ignore_errors=True) shutil.rmtree(TESTFN, ignore_errors=True)
shutil.rmtree(TESTFN2, ignore_errors=True) shutil.rmtree(TESTFN2, ignore_errors=True)
@unittest.skipUnless(hasattr(os, 'chflags') and
hasattr(errno, 'EOPNOTSUPP') and
hasattr(errno, 'ENOTSUP'),
"requires os.chflags, EOPNOTSUPP & ENOTSUP")
def test_copystat_handles_harmless_chflags_errors(self):
tmpdir = self.mkdtemp()
file1 = os.path.join(tmpdir, 'file1')
file2 = os.path.join(tmpdir, 'file2')
self.write_file(file1, 'xxx')
self.write_file(file2, 'xxx')
def make_chflags_raiser(err):
ex = OSError()
def _chflags_raiser(path, flags):
ex.errno = err
raise ex
return _chflags_raiser
old_chflags = os.chflags
try:
for err in errno.EOPNOTSUPP, errno.ENOTSUP:
os.chflags = make_chflags_raiser(err)
shutil.copystat(file1, file2)
# assert others errors break it
os.chflags = make_chflags_raiser(errno.EOPNOTSUPP + errno.ENOTSUP)
self.assertRaises(OSError, shutil.copystat, file1, file2)
finally:
os.chflags = old_chflags
@unittest.skipUnless(zlib, "requires zlib") @unittest.skipUnless(zlib, "requires zlib")
def test_make_tarball(self): def test_make_tarball(self):
# creating something to tar # creating something to tar
......
...@@ -60,6 +60,9 @@ Core and Builtins ...@@ -60,6 +60,9 @@ Core and Builtins
Library Library
------- -------
- Issue #14662: Prevent shutil failures on OS X when destination does not
support chflag operations. Patch by Hynek Schlawack.
- Issue #14157: Fix time.strptime failing without a year on February 29th. - Issue #14157: Fix time.strptime failing without a year on February 29th.
Patch by Hynek Schlawack. Patch by Hynek Schlawack.
......
...@@ -783,6 +783,9 @@ initerrno(void) ...@@ -783,6 +783,9 @@ initerrno(void)
#ifdef WSAN #ifdef WSAN
inscode(d, ds, de, "WSAN", WSAN, "Error WSAN"); inscode(d, ds, de, "WSAN", WSAN, "Error WSAN");
#endif #endif
#ifdef ENOTSUP
inscode(d, ds, de, "ENOTSUP", ENOTSUP, "Operation not supported");
#endif
Py_DECREF(de); Py_DECREF(de);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment