Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(201663)

Delta Between Two Patch Sets: Lib/test/test_shutil.py

Issue 16510: Using appropriate checks in tests
Left Patch Set: Created 7 years ago
Right Patch Set: Created 5 years, 10 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Lib/test/test_selectors.py ('k') | Lib/test/test_slice.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # Copyright (C) 2003 Python Software Foundation 1 # Copyright (C) 2003 Python Software Foundation
2 2
3 import unittest 3 import unittest
4 import shutil 4 import shutil
5 import tempfile 5 import tempfile
6 import sys 6 import sys
7 import stat 7 import stat
8 import os 8 import os
9 import os.path 9 import os.path
10 import errno 10 import errno
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 120
121 @support.skip_unless_symlink 121 @support.skip_unless_symlink
122 def test_rmtree_fails_on_symlink(self): 122 def test_rmtree_fails_on_symlink(self):
123 tmp = self.mkdtemp() 123 tmp = self.mkdtemp()
124 dir_ = os.path.join(tmp, 'dir') 124 dir_ = os.path.join(tmp, 'dir')
125 os.mkdir(dir_) 125 os.mkdir(dir_)
126 link = os.path.join(tmp, 'link') 126 link = os.path.join(tmp, 'link')
127 os.symlink(dir_, link) 127 os.symlink(dir_, link)
128 self.assertRaises(OSError, shutil.rmtree, link) 128 self.assertRaises(OSError, shutil.rmtree, link)
129 self.assertTrue(os.path.exists(dir_)) 129 self.assertTrue(os.path.exists(dir_))
130 self.assertTrue(os.path.lexists(link))
131 errors = []
132 def onerror(*args):
133 errors.append(args)
134 shutil.rmtree(link, onerror=onerror)
135 self.assertEqual(len(errors), 1)
136 self.assertIs(errors[0][0], os.path.islink)
137 self.assertEqual(errors[0][1], link)
138 self.assertIsInstance(errors[0][2][1], OSError)
130 139
131 @support.skip_unless_symlink 140 @support.skip_unless_symlink
132 def test_rmtree_works_on_symlinks(self): 141 def test_rmtree_works_on_symlinks(self):
133 tmp = self.mkdtemp() 142 tmp = self.mkdtemp()
134 dir1 = os.path.join(tmp, 'dir1') 143 dir1 = os.path.join(tmp, 'dir1')
135 dir2 = os.path.join(dir1, 'dir2') 144 dir2 = os.path.join(dir1, 'dir2')
136 dir3 = os.path.join(tmp, 'dir3') 145 dir3 = os.path.join(tmp, 'dir3')
137 for d in dir1, dir2, dir3: 146 for d in dir1, dir2, dir3:
138 os.mkdir(d) 147 os.mkdir(d)
139 file1 = os.path.join(tmp, 'file1') 148 file1 = os.path.join(tmp, 'file1')
140 write_file(file1, 'foo') 149 write_file(file1, 'foo')
141 link1 = os.path.join(dir1, 'link1') 150 link1 = os.path.join(dir1, 'link1')
142 os.symlink(dir2, link1) 151 os.symlink(dir2, link1)
143 link2 = os.path.join(dir1, 'link2') 152 link2 = os.path.join(dir1, 'link2')
144 os.symlink(dir3, link2) 153 os.symlink(dir3, link2)
145 link3 = os.path.join(dir1, 'link3') 154 link3 = os.path.join(dir1, 'link3')
146 os.symlink(file1, link3) 155 os.symlink(file1, link3)
147 # make sure symlinks are removed but not followed 156 # make sure symlinks are removed but not followed
148 shutil.rmtree(dir1) 157 shutil.rmtree(dir1)
149 self.assertFalse(os.path.exists(dir1)) 158 self.assertFalse(os.path.exists(dir1))
150 self.assertTrue(os.path.exists(dir3)) 159 self.assertTrue(os.path.exists(dir3))
151 self.assertTrue(os.path.exists(file1)) 160 self.assertTrue(os.path.exists(file1))
152 161
153 def test_rmtree_errors(self): 162 def test_rmtree_errors(self):
154 # filename is guaranteed not to exist 163 # filename is guaranteed not to exist
155 filename = tempfile.mktemp() 164 filename = tempfile.mktemp()
156 self.assertRaises(OSError, shutil.rmtree, filename) 165 self.assertRaises(FileNotFoundError, shutil.rmtree, filename)
157 166 # test that ignore_errors option is honored
158 # See bug #1071513 for why we don't run this on cygwin 167 shutil.rmtree(filename, ignore_errors=True)
159 # and bug #1076467 for why we don't run this as root. 168
160 if (hasattr(os, 'chmod') and sys.platform[:6] != 'cygwin' 169 # existing file
161 and not (hasattr(os, 'geteuid') and os.geteuid() == 0)): 170 tmpdir = self.mkdtemp()
162 def test_on_error(self): 171 write_file((tmpdir, "tstfile"), "")
163 self.errorState = 0 172 filename = os.path.join(tmpdir, "tstfile")
164 os.mkdir(TESTFN) 173 with self.assertRaises(NotADirectoryError) as cm:
165 self.addCleanup(shutil.rmtree, TESTFN) 174 shutil.rmtree(filename)
166 175 # The reason for this rather odd construct is that Windows sprinkles
167 self.child_file_path = os.path.join(TESTFN, 'a') 176 # a \*.* at the end of file names. But only sometimes on some buildbots
168 self.child_dir_path = os.path.join(TESTFN, 'b') 177 possible_args = [filename, os.path.join(filename, '*.*')]
169 support.create_empty_file(self.child_file_path) 178 self.assertIn(cm.exception.filename, possible_args)
170 os.mkdir(self.child_dir_path) 179 self.assertTrue(os.path.exists(filename))
171 old_dir_mode = os.stat(TESTFN).st_mode 180 # test that ignore_errors option is honored
172 old_child_file_mode = os.stat(self.child_file_path).st_mode 181 shutil.rmtree(filename, ignore_errors=True)
173 old_child_dir_mode = os.stat(self.child_dir_path).st_mode 182 self.assertTrue(os.path.exists(filename))
174 # Make unwritable. 183 errors = []
175 new_mode = stat.S_IREAD|stat.S_IEXEC 184 def onerror(*args):
176 os.chmod(self.child_file_path, new_mode) 185 errors.append(args)
177 os.chmod(self.child_dir_path, new_mode) 186 shutil.rmtree(filename, onerror=onerror)
178 os.chmod(TESTFN, new_mode) 187 self.assertEqual(len(errors), 2)
179 188 self.assertIs(errors[0][0], os.listdir)
180 self.addCleanup(os.chmod, TESTFN, old_dir_mode) 189 self.assertEqual(errors[0][1], filename)
181 self.addCleanup(os.chmod, self.child_file_path, old_child_file_mode) 190 self.assertIsInstance(errors[0][2][1], NotADirectoryError)
182 self.addCleanup(os.chmod, self.child_dir_path, old_child_dir_mode) 191 self.assertIn(errors[0][2][1].filename, possible_args)
183 192 self.assertIs(errors[1][0], os.rmdir)
184 shutil.rmtree(TESTFN, onerror=self.check_args_to_onerror) 193 self.assertEqual(errors[1][1], filename)
185 # Test whether onerror has actually been called. 194 self.assertIsInstance(errors[1][2][1], NotADirectoryError)
186 self.assertEqual(self.errorState, 3, 195 self.assertIn(errors[1][2][1].filename, possible_args)
187 "Expected call to onerror function did not " 196
188 "happen.") 197
198 @unittest.skipUnless(hasattr(os, 'chmod'), 'requires os.chmod()')
199 @unittest.skipIf(sys.platform[:6] == 'cygwin',
200 "This test can't be run on Cygwin (issue #1071513).")
201 @unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0,
202 "This test can't be run reliably as root (issue #1076467)." )
203 def test_on_error(self):
204 self.errorState = 0
205 os.mkdir(TESTFN)
206 self.addCleanup(shutil.rmtree, TESTFN)
207
208 self.child_file_path = os.path.join(TESTFN, 'a')
209 self.child_dir_path = os.path.join(TESTFN, 'b')
210 support.create_empty_file(self.child_file_path)
211 os.mkdir(self.child_dir_path)
212 old_dir_mode = os.stat(TESTFN).st_mode
213 old_child_file_mode = os.stat(self.child_file_path).st_mode
214 old_child_dir_mode = os.stat(self.child_dir_path).st_mode
215 # Make unwritable.
216 new_mode = stat.S_IREAD|stat.S_IEXEC
217 os.chmod(self.child_file_path, new_mode)
218 os.chmod(self.child_dir_path, new_mode)
219 os.chmod(TESTFN, new_mode)
220
221 self.addCleanup(os.chmod, TESTFN, old_dir_mode)
222 self.addCleanup(os.chmod, self.child_file_path, old_child_file_mode)
223 self.addCleanup(os.chmod, self.child_dir_path, old_child_dir_mode)
224
225 shutil.rmtree(TESTFN, onerror=self.check_args_to_onerror)
226 # Test whether onerror has actually been called.
227 self.assertEqual(self.errorState, 3,
228 "Expected call to onerror function did not happen.")
189 229
190 def check_args_to_onerror(self, func, arg, exc): 230 def check_args_to_onerror(self, func, arg, exc):
191 # test_rmtree_errors deliberately runs rmtree 231 # test_rmtree_errors deliberately runs rmtree
192 # on a directory that is chmod 500, which will fail. 232 # on a directory that is chmod 500, which will fail.
193 # This function is run when shutil.rmtree fails. 233 # This function is run when shutil.rmtree fails.
194 # 99.9% of the time it initially fails to remove 234 # 99.9% of the time it initially fails to remove
195 # a file in the directory, so the first time through 235 # a file in the directory, so the first time through
196 # func is os.remove. 236 # func is os.remove.
197 # However, some Linux machines running ZFS on 237 # However, some Linux machines running ZFS on
198 # FUSE experienced a failure earlier in the process 238 # FUSE experienced a failure earlier in the process
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 write_file(src, 'foo') 281 write_file(src, 'foo')
242 write_file(dst, 'foo') 282 write_file(dst, 'foo')
243 os.symlink(src, src_link) 283 os.symlink(src, src_link)
244 os.symlink(dst, dst_link) 284 os.symlink(dst, dst_link)
245 os.chmod(src, stat.S_IRWXU|stat.S_IRWXG) 285 os.chmod(src, stat.S_IRWXU|stat.S_IRWXG)
246 # file to file 286 # file to file
247 os.chmod(dst, stat.S_IRWXO) 287 os.chmod(dst, stat.S_IRWXO)
248 self.assertNotEqual(os.stat(src).st_mode, os.stat(dst).st_mode) 288 self.assertNotEqual(os.stat(src).st_mode, os.stat(dst).st_mode)
249 shutil.copymode(src, dst) 289 shutil.copymode(src, dst)
250 self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode) 290 self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode)
251 # follow src link 291 # On Windows, os.chmod does not follow symlinks (issue #15411)
252 os.chmod(dst, stat.S_IRWXO) 292 if os.name != 'nt':
253 shutil.copymode(src_link, dst) 293 # follow src link
254 self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode) 294 os.chmod(dst, stat.S_IRWXO)
255 # follow dst link 295 shutil.copymode(src_link, dst)
256 os.chmod(dst, stat.S_IRWXO) 296 self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode)
257 shutil.copymode(src, dst_link) 297 # follow dst link
258 self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode) 298 os.chmod(dst, stat.S_IRWXO)
259 # follow both links 299 shutil.copymode(src, dst_link)
260 os.chmod(dst, stat.S_IRWXO) 300 self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode)
261 shutil.copymode(src_link, dst) 301 # follow both links
262 self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode) 302 os.chmod(dst, stat.S_IRWXO)
303 shutil.copymode(src_link, dst_link)
304 self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode)
263 305
264 @unittest.skipUnless(hasattr(os, 'lchmod'), 'requires os.lchmod') 306 @unittest.skipUnless(hasattr(os, 'lchmod'), 'requires os.lchmod')
265 @support.skip_unless_symlink 307 @support.skip_unless_symlink
266 def test_copymode_symlink_to_symlink(self): 308 def test_copymode_symlink_to_symlink(self):
267 tmp_dir = self.mkdtemp() 309 tmp_dir = self.mkdtemp()
268 src = os.path.join(tmp_dir, 'foo') 310 src = os.path.join(tmp_dir, 'foo')
269 dst = os.path.join(tmp_dir, 'bar') 311 dst = os.path.join(tmp_dir, 'bar')
270 src_link = os.path.join(tmp_dir, 'baz') 312 src_link = os.path.join(tmp_dir, 'baz')
271 dst_link = os.path.join(tmp_dir, 'quux') 313 dst_link = os.path.join(tmp_dir, 'quux')
272 write_file(src, 'foo') 314 write_file(src, 'foo')
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 write_file(src, 'foo') 424 write_file(src, 'foo')
383 dst = os.path.join(tmp_dir, 'bar') 425 dst = os.path.join(tmp_dir, 'bar')
384 write_file(dst, 'bar') 426 write_file(dst, 'bar')
385 427
386 # no xattr == no problem 428 # no xattr == no problem
387 shutil._copyxattr(src, dst) 429 shutil._copyxattr(src, dst)
388 # common case 430 # common case
389 os.setxattr(src, 'user.foo', b'42') 431 os.setxattr(src, 'user.foo', b'42')
390 os.setxattr(src, 'user.bar', b'43') 432 os.setxattr(src, 'user.bar', b'43')
391 shutil._copyxattr(src, dst) 433 shutil._copyxattr(src, dst)
392 self.assertEqual(os.listxattr(src), os.listxattr(dst)) 434 self.assertEqual(sorted(os.listxattr(src)), sorted(os.listxattr(dst)))
393 self.assertEqual( 435 self.assertEqual(
394 os.getxattr(src, 'user.foo'), 436 os.getxattr(src, 'user.foo'),
395 os.getxattr(dst, 'user.foo')) 437 os.getxattr(dst, 'user.foo'))
396 # check errors don't affect other attrs 438 # check errors don't affect other attrs
397 os.remove(dst) 439 os.remove(dst)
398 write_file(dst, 'bar') 440 write_file(dst, 'bar')
399 os_error = OSError(errno.EPERM, 'EPERM') 441 os_error = OSError(errno.EPERM, 'EPERM')
400 442
401 def _raise_on_user_foo(fname, attr, val, **kwargs): 443 def _raise_on_user_foo(fname, attr, val, **kwargs):
402 if attr == 'user.foo': 444 if attr == 'user.foo':
403 raise os_error 445 raise os_error
404 else: 446 else:
405 orig_setxattr(fname, attr, val, **kwargs) 447 orig_setxattr(fname, attr, val, **kwargs)
406 try: 448 try:
407 orig_setxattr = os.setxattr 449 orig_setxattr = os.setxattr
408 os.setxattr = _raise_on_user_foo 450 os.setxattr = _raise_on_user_foo
409 shutil._copyxattr(src, dst) 451 shutil._copyxattr(src, dst)
410 self.assertIn('user.bar', os.listxattr(dst)) 452 self.assertIn('user.bar', os.listxattr(dst))
411 finally: 453 finally:
412 os.setxattr = orig_setxattr 454 os.setxattr = orig_setxattr
455 # the source filesystem not supporting xattrs should be ok, too.
456 def _raise_on_src(fname, *, follow_symlinks=True):
457 if fname == src:
458 raise OSError(errno.ENOTSUP, 'Operation not supported')
459 return orig_listxattr(fname, follow_symlinks=follow_symlinks)
460 try:
461 orig_listxattr = os.listxattr
462 os.listxattr = _raise_on_src
463 shutil._copyxattr(src, dst)
464 finally:
465 os.listxattr = orig_listxattr
413 466
414 # test that shutil.copystat copies xattrs 467 # test that shutil.copystat copies xattrs
415 src = os.path.join(tmp_dir, 'the_original') 468 src = os.path.join(tmp_dir, 'the_original')
416 write_file(src, src) 469 write_file(src, src)
417 os.setxattr(src, 'user.the_value', b'fiddly') 470 os.setxattr(src, 'user.the_value', b'fiddly')
418 dst = os.path.join(tmp_dir, 'the_copy') 471 dst = os.path.join(tmp_dir, 'the_copy')
419 write_file(dst, dst) 472 write_file(dst, dst)
420 shutil.copystat(src, dst) 473 shutil.copystat(src, dst)
421 self.assertEqual(os.getxattr(dst, 'user.the_value'), b'fiddly') 474 self.assertEqual(os.getxattr(dst, 'user.the_value'), b'fiddly')
422 475
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 self.assertFalse(exists(join(dst_dir, 'test_dir2', 'subdir2', 722 self.assertFalse(exists(join(dst_dir, 'test_dir2', 'subdir2',
670 'test.py'))) 723 'test.py')))
671 self.assertFalse(exists(join(dst_dir, 'test_dir2', 'subdir'))) 724 self.assertFalse(exists(join(dst_dir, 'test_dir2', 'subdir')))
672 725
673 finally: 726 finally:
674 shutil.rmtree(dst_dir) 727 shutil.rmtree(dst_dir)
675 finally: 728 finally:
676 shutil.rmtree(src_dir) 729 shutil.rmtree(src_dir)
677 shutil.rmtree(os.path.dirname(dst_dir)) 730 shutil.rmtree(os.path.dirname(dst_dir))
678 731
732 def test_copytree_retains_permissions(self):
733 tmp_dir = tempfile.mkdtemp()
734 src_dir = os.path.join(tmp_dir, 'source')
735 os.mkdir(src_dir)
736 dst_dir = os.path.join(tmp_dir, 'destination')
737 self.addCleanup(shutil.rmtree, tmp_dir)
738
739 os.chmod(src_dir, 0o777)
740 write_file((src_dir, 'permissive.txt'), '123')
741 os.chmod(os.path.join(src_dir, 'permissive.txt'), 0o777)
742 write_file((src_dir, 'restrictive.txt'), '456')
743 os.chmod(os.path.join(src_dir, 'restrictive.txt'), 0o600)
744 restrictive_subdir = tempfile.mkdtemp(dir=src_dir)
745 os.chmod(restrictive_subdir, 0o600)
746
747 shutil.copytree(src_dir, dst_dir)
748 self.assertEqual(os.stat(src_dir).st_mode, os.stat(dst_dir).st_mode)
749 self.assertEqual(os.stat(os.path.join(src_dir, 'permissive.txt')).st_mod e,
750 os.stat(os.path.join(dst_dir, 'permissive.txt')).st_mo de)
751 self.assertEqual(os.stat(os.path.join(src_dir, 'restrictive.txt')).st_mo de,
752 os.stat(os.path.join(dst_dir, 'restrictive.txt')).st_m ode)
753 restrictive_subdir_dst = os.path.join(dst_dir,
754 os.path.split(restrictive_subdir)[ 1])
755 self.assertEqual(os.stat(restrictive_subdir).st_mode,
756 os.stat(restrictive_subdir_dst).st_mode)
757
758 @unittest.skipIf(os.name == 'nt', 'temporarily disabled on Windows')
679 @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') 759 @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link')
680 def test_dont_copy_file_onto_link_to_itself(self): 760 def test_dont_copy_file_onto_link_to_itself(self):
681 # Temporarily disable test on Windows.
682 if os.name == 'nt':
683 return
684 # bug 851123. 761 # bug 851123.
685 os.mkdir(TESTFN) 762 os.mkdir(TESTFN)
686 src = os.path.join(TESTFN, 'cheese') 763 src = os.path.join(TESTFN, 'cheese')
687 dst = os.path.join(TESTFN, 'shop') 764 dst = os.path.join(TESTFN, 'shop')
688 try: 765 try:
689 with open(src, 'w') as f: 766 with open(src, 'w') as f:
690 f.write('cheddar') 767 f.write('cheddar')
691 os.link(src, dst) 768 os.link(src, dst)
692 self.assertRaises(shutil.SameFileError, shutil.copyfile, src, dst) 769 self.assertRaises(shutil.SameFileError, shutil.copyfile, src, dst)
693 with open(src, 'r') as f: 770 with open(src, 'r') as f:
(...skipping 29 matching lines...) Expand all
723 try: 800 try:
724 src = os.path.join(TESTFN, 'cheese') 801 src = os.path.join(TESTFN, 'cheese')
725 dst = os.path.join(TESTFN, 'shop') 802 dst = os.path.join(TESTFN, 'shop')
726 os.mkdir(src) 803 os.mkdir(src)
727 os.symlink(src, dst) 804 os.symlink(src, dst)
728 self.assertRaises(OSError, shutil.rmtree, dst) 805 self.assertRaises(OSError, shutil.rmtree, dst)
729 shutil.rmtree(dst, ignore_errors=True) 806 shutil.rmtree(dst, ignore_errors=True)
730 finally: 807 finally:
731 shutil.rmtree(TESTFN, ignore_errors=True) 808 shutil.rmtree(TESTFN, ignore_errors=True)
732 809
733 if hasattr(os, "mkfifo"): 810 # Issue #3002: copyfile and copytree block indefinitely on named pipes
734 # Issue #3002: copyfile and copytree block indefinitely on named pipes 811 @unittest.skipUnless(hasattr(os, "mkfifo"), 'requires os.mkfifo()')
735 def test_copyfile_named_pipe(self): 812 def test_copyfile_named_pipe(self):
736 os.mkfifo(TESTFN) 813 os.mkfifo(TESTFN)
814 try:
815 self.assertRaises(shutil.SpecialFileError,
816 shutil.copyfile, TESTFN, TESTFN2)
817 self.assertRaises(shutil.SpecialFileError,
818 shutil.copyfile, __file__, TESTFN)
819 finally:
820 os.remove(TESTFN)
821
822 @unittest.skipUnless(hasattr(os, "mkfifo"), 'requires os.mkfifo()')
823 @support.skip_unless_symlink
824 def test_copytree_named_pipe(self):
825 os.mkdir(TESTFN)
826 try:
827 subdir = os.path.join(TESTFN, "subdir")
828 os.mkdir(subdir)
829 pipe = os.path.join(subdir, "mypipe")
830 os.mkfifo(pipe)
737 try: 831 try:
738 self.assertRaises(shutil.SpecialFileError, 832 shutil.copytree(TESTFN, TESTFN2)
739 shutil.copyfile, TESTFN, TESTFN2) 833 except shutil.Error as e:
740 self.assertRaises(shutil.SpecialFileError, 834 errors = e.args[0]
741 shutil.copyfile, __file__, TESTFN) 835 self.assertEqual(len(errors), 1)
742 finally: 836 src, dst, error_msg = errors[0]
743 os.remove(TESTFN) 837 self.assertEqual("`%s` is a named pipe" % pipe, error_msg)
744 838 else:
745 @support.skip_unless_symlink 839 self.fail("shutil.Error should have been raised")
746 def test_copytree_named_pipe(self): 840 finally:
747 os.mkdir(TESTFN) 841 shutil.rmtree(TESTFN, ignore_errors=True)
748 try: 842 shutil.rmtree(TESTFN2, ignore_errors=True)
749 subdir = os.path.join(TESTFN, "subdir")
750 os.mkdir(subdir)
751 pipe = os.path.join(subdir, "mypipe")
752 os.mkfifo(pipe)
753 try:
754 shutil.copytree(TESTFN, TESTFN2)
755 except shutil.Error as e:
756 errors = e.args[0]
757 self.assertEqual(len(errors), 1)
758 src, dst, error_msg = errors[0]
759 self.assertEqual("`%s` is a named pipe" % pipe, error_msg)
760 else:
761 self.fail("shutil.Error should have been raised")
762 finally:
763 shutil.rmtree(TESTFN, ignore_errors=True)
764 shutil.rmtree(TESTFN2, ignore_errors=True)
765 843
766 def test_copytree_special_func(self): 844 def test_copytree_special_func(self):
767 845
768 src_dir = self.mkdtemp() 846 src_dir = self.mkdtemp()
769 dst_dir = os.path.join(self.mkdtemp(), 'destination') 847 dst_dir = os.path.join(self.mkdtemp(), 'destination')
770 write_file((src_dir, 'test.txt'), '123') 848 write_file((src_dir, 'test.txt'), '123')
771 os.mkdir(os.path.join(src_dir, 'test_dir')) 849 os.mkdir(os.path.join(src_dir, 'test_dir'))
772 write_file((src_dir, 'test_dir', 'test.txt'), '456') 850 write_file((src_dir, 'test_dir', 'test.txt'), '456')
773 851
774 copied = [] 852 copied = []
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 self.addCleanup(shutil.rmtree, dst_dir, True) 1311 self.addCleanup(shutil.rmtree, dst_dir, True)
1234 src = os.path.join(src_dir, 'foo') 1312 src = os.path.join(src_dir, 'foo')
1235 write_file(src, 'foo') 1313 write_file(src, 'foo')
1236 rv = shutil.copytree(src_dir, dst_dir) 1314 rv = shutil.copytree(src_dir, dst_dir)
1237 self.assertEqual(['foo'], os.listdir(rv)) 1315 self.assertEqual(['foo'], os.listdir(rv))
1238 1316
1239 1317
1240 class TestWhich(unittest.TestCase): 1318 class TestWhich(unittest.TestCase):
1241 1319
1242 def setUp(self): 1320 def setUp(self):
1243 self.temp_dir = tempfile.mkdtemp() 1321 self.temp_dir = tempfile.mkdtemp(prefix="Tmp")
1244 self.addCleanup(shutil.rmtree, self.temp_dir, True) 1322 self.addCleanup(shutil.rmtree, self.temp_dir, True)
1245 # Give the temp_file an ".exe" suffix for all. 1323 # Give the temp_file an ".exe" suffix for all.
1246 # It's needed on Windows and not harmful on other platforms. 1324 # It's needed on Windows and not harmful on other platforms.
1247 self.temp_file = tempfile.NamedTemporaryFile(dir=self.temp_dir, 1325 self.temp_file = tempfile.NamedTemporaryFile(dir=self.temp_dir,
1248 suffix=".exe") 1326 prefix="Tmp",
1327 suffix=".Exe")
1249 os.chmod(self.temp_file.name, stat.S_IXUSR) 1328 os.chmod(self.temp_file.name, stat.S_IXUSR)
1250 self.addCleanup(self.temp_file.close) 1329 self.addCleanup(self.temp_file.close)
1251 self.dir, self.file = os.path.split(self.temp_file.name) 1330 self.dir, self.file = os.path.split(self.temp_file.name)
1252 1331
1253 def test_basic(self): 1332 def test_basic(self):
1254 # Given an EXE in a directory, it should be returned. 1333 # Given an EXE in a directory, it should be returned.
1255 rv = shutil.which(self.file, path=self.dir) 1334 rv = shutil.which(self.file, path=self.dir)
1256 self.assertEqual(rv, self.temp_file.name) 1335 self.assertEqual(rv, self.temp_file.name)
1257 1336
1258 def test_full_path_short_circuit(self): 1337 def test_absolute_cmd(self):
1259 # When given the fully qualified path to an executable that exists, 1338 # When given the fully qualified path to an executable that exists,
1260 # it should be returned. 1339 # it should be returned.
1261 rv = shutil.which(self.temp_file.name, path=self.temp_dir) 1340 rv = shutil.which(self.temp_file.name, path=self.temp_dir)
1262 self.assertEqual(self.temp_file.name, rv) 1341 self.assertEqual(rv, self.temp_file.name)
1263 1342
1343 def test_relative_cmd(self):
1344 # When given the relative path with a directory part to an executable
1345 # that exists, it should be returned.
1346 base_dir, tail_dir = os.path.split(self.dir)
1347 relpath = os.path.join(tail_dir, self.file)
1348 with support.change_cwd(path=base_dir):
1349 rv = shutil.which(relpath, path=self.temp_dir)
1350 self.assertEqual(rv, relpath)
1351 # But it shouldn't be searched in PATH directories (issue #16957).
1352 with support.change_cwd(path=self.dir):
1353 rv = shutil.which(relpath, path=base_dir)
1354 self.assertIsNone(rv)
1355
1356 def test_cwd(self):
1357 # Issue #16957
1358 base_dir = os.path.dirname(self.dir)
1359 with support.change_cwd(path=self.dir):
1360 rv = shutil.which(self.file, path=base_dir)
1361 if sys.platform == "win32":
1362 # Windows: current directory implicitly on PATH
1363 self.assertEqual(rv, os.path.join(os.curdir, self.file))
1364 else:
1365 # Other platforms: shouldn't match in the current directory.
1366 self.assertIsNone(rv)
1367
1368 @unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0,
1369 'non-root user required')
1264 def test_non_matching_mode(self): 1370 def test_non_matching_mode(self):
1265 # Set the file read-only and ask for writeable files. 1371 # Set the file read-only and ask for writeable files.
1266 os.chmod(self.temp_file.name, stat.S_IREAD) 1372 os.chmod(self.temp_file.name, stat.S_IREAD)
1373 if os.access(self.temp_file.name, os.W_OK):
1374 self.skipTest("can't set the file read-only")
1267 rv = shutil.which(self.file, path=self.dir, mode=os.W_OK) 1375 rv = shutil.which(self.file, path=self.dir, mode=os.W_OK)
1268 self.assertIsNone(rv) 1376 self.assertIsNone(rv)
1269 1377
1270 def test_relative(self): 1378 def test_relative_path(self):
1271 old_cwd = os.getcwd()
1272 base_dir, tail_dir = os.path.split(self.dir) 1379 base_dir, tail_dir = os.path.split(self.dir)
1273 os.chdir(base_dir) 1380 with support.change_cwd(path=base_dir):
1274 try:
1275 rv = shutil.which(self.file, path=tail_dir) 1381 rv = shutil.which(self.file, path=tail_dir)
1276 self.assertEqual(rv, os.path.join(tail_dir, self.file)) 1382 self.assertEqual(rv, os.path.join(tail_dir, self.file))
1277 finally:
1278 os.chdir(old_cwd)
1279 1383
1280 def test_nonexistent_file(self): 1384 def test_nonexistent_file(self):
1281 # Return None when no matching executable file is found on the path. 1385 # Return None when no matching executable file is found on the path.
1282 rv = shutil.which("foo.exe", path=self.dir) 1386 rv = shutil.which("foo.exe", path=self.dir)
1283 self.assertIsNone(rv) 1387 self.assertIsNone(rv)
1284 1388
1285 @unittest.skipUnless(sys.platform == "win32", 1389 @unittest.skipUnless(sys.platform == "win32",
1286 "pathext check is Windows-only") 1390 "pathext check is Windows-only")
1287 def test_pathext_checking(self): 1391 def test_pathext_checking(self):
1288 # Ask for the file without the ".exe" extension, then ensure that 1392 # Ask for the file without the ".exe" extension, then ensure that
1289 # it gets found properly with the extension. 1393 # it gets found properly with the extension.
1290 rv = shutil.which(self.temp_file.name[:-4], path=self.dir) 1394 rv = shutil.which(self.file[:-4], path=self.dir)
1291 self.assertEqual(self.temp_file.name, rv) 1395 self.assertEqual(rv, self.temp_file.name[:-4] + ".EXE")
1396
1397 def test_environ_path(self):
1398 with support.EnvironmentVarGuard() as env:
1399 env['PATH'] = self.dir
1400 rv = shutil.which(self.file)
1401 self.assertEqual(rv, self.temp_file.name)
1402
1403 def test_empty_path(self):
1404 base_dir = os.path.dirname(self.dir)
1405 with support.change_cwd(path=self.dir), \
1406 support.EnvironmentVarGuard() as env:
1407 env['PATH'] = self.dir
1408 rv = shutil.which(self.file, path='')
1409 self.assertIsNone(rv)
1410
1411 def test_empty_path_no_PATH(self):
1412 with support.EnvironmentVarGuard() as env:
1413 env.pop('PATH', None)
1414 rv = shutil.which(self.file)
1415 self.assertIsNone(rv)
1292 1416
1293 1417
1294 class TestMove(unittest.TestCase): 1418 class TestMove(unittest.TestCase):
1295 1419
1296 def setUp(self): 1420 def setUp(self):
1297 filename = "foo" 1421 filename = "foo"
1298 self.src_dir = tempfile.mkdtemp() 1422 self.src_dir = tempfile.mkdtemp()
1299 self.dst_dir = tempfile.mkdtemp() 1423 self.dst_dir = tempfile.mkdtemp()
1300 self.src_file = os.path.join(self.src_dir, filename) 1424 self.src_file = os.path.join(self.src_dir, filename)
1301 self.dst_file = os.path.join(self.dst_dir, filename) 1425 self.dst_file = os.path.join(self.dst_dir, filename)
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1425 1549
1426 @support.skip_unless_symlink 1550 @support.skip_unless_symlink
1427 @mock_rename 1551 @mock_rename
1428 def test_move_dangling_symlink(self): 1552 def test_move_dangling_symlink(self):
1429 src = os.path.join(self.src_dir, 'baz') 1553 src = os.path.join(self.src_dir, 'baz')
1430 dst = os.path.join(self.src_dir, 'bar') 1554 dst = os.path.join(self.src_dir, 'bar')
1431 os.symlink(src, dst) 1555 os.symlink(src, dst)
1432 dst_link = os.path.join(self.dst_dir, 'quux') 1556 dst_link = os.path.join(self.dst_dir, 'quux')
1433 shutil.move(dst, dst_link) 1557 shutil.move(dst, dst_link)
1434 self.assertTrue(os.path.islink(dst_link)) 1558 self.assertTrue(os.path.islink(dst_link))
1435 self.assertEqual(os.path.realpath(src), os.path.realpath(dst_link)) 1559 # On Windows, os.path.realpath does not follow symlinks (issue #9949)
1560 if os.name == 'nt':
1561 self.assertEqual(os.path.realpath(src), os.readlink(dst_link))
1562 else:
1563 self.assertEqual(os.path.realpath(src), os.path.realpath(dst_link))
1436 1564
1437 @support.skip_unless_symlink 1565 @support.skip_unless_symlink
1438 @mock_rename 1566 @mock_rename
1439 def test_move_dir_symlink(self): 1567 def test_move_dir_symlink(self):
1440 src = os.path.join(self.src_dir, 'baz') 1568 src = os.path.join(self.src_dir, 'baz')
1441 dst = os.path.join(self.src_dir, 'bar') 1569 dst = os.path.join(self.src_dir, 'bar')
1442 os.mkdir(src) 1570 os.mkdir(src)
1443 os.symlink(src, dst) 1571 os.symlink(src, dst)
1444 dst_link = os.path.join(self.dst_dir, 'quux') 1572 dst_link = os.path.join(self.dst_dir, 'quux')
1445 shutil.move(dst, dst_link) 1573 shutil.move(dst, dst_link)
(...skipping 22 matching lines...) Expand all
1468 self._raise_in_exit = raise_in_exit 1596 self._raise_in_exit = raise_in_exit
1469 self._suppress_at_exit = suppress_at_exit 1597 self._suppress_at_exit = suppress_at_exit
1470 def read(self, *args): 1598 def read(self, *args):
1471 return '' 1599 return ''
1472 def __enter__(self): 1600 def __enter__(self):
1473 self._entered = True 1601 self._entered = True
1474 def __exit__(self, exc_type, exc_val, exc_tb): 1602 def __exit__(self, exc_type, exc_val, exc_tb):
1475 self._exited_with = exc_type, exc_val, exc_tb 1603 self._exited_with = exc_type, exc_val, exc_tb
1476 if self._raise_in_exit: 1604 if self._raise_in_exit:
1477 self._raised = True 1605 self._raised = True
1478 raise IOError("Cannot close") 1606 raise OSError("Cannot close")
1479 return self._suppress_at_exit 1607 return self._suppress_at_exit
1480 1608
1481 def tearDown(self): 1609 def tearDown(self):
1482 if self._delete: 1610 if self._delete:
1483 del shutil.open 1611 del shutil.open
1484 1612
1485 def _set_shutil_open(self, func): 1613 def _set_shutil_open(self, func):
1486 shutil.open = func 1614 shutil.open = func
1487 self._delete = True 1615 self._delete = True
1488 1616
1489 def test_w_source_open_fails(self): 1617 def test_w_source_open_fails(self):
1490 def _open(filename, mode='r'): 1618 def _open(filename, mode='r'):
1491 if filename == 'srcfile': 1619 if filename == 'srcfile':
1492 raise IOError('Cannot open "srcfile"') 1620 raise OSError('Cannot open "srcfile"')
1493 assert 0 # shouldn't reach here. 1621 assert 0 # shouldn't reach here.
1494 1622
1495 self._set_shutil_open(_open) 1623 self._set_shutil_open(_open)
1496 1624
1497 self.assertRaises(IOError, shutil.copyfile, 'srcfile', 'destfile') 1625 self.assertRaises(OSError, shutil.copyfile, 'srcfile', 'destfile')
1498 1626
1499 def test_w_dest_open_fails(self): 1627 def test_w_dest_open_fails(self):
1500 1628
1501 srcfile = self.Faux() 1629 srcfile = self.Faux()
1502 1630
1503 def _open(filename, mode='r'): 1631 def _open(filename, mode='r'):
1504 if filename == 'srcfile': 1632 if filename == 'srcfile':
1505 return srcfile 1633 return srcfile
1506 if filename == 'destfile': 1634 if filename == 'destfile':
1507 raise IOError('Cannot open "destfile"') 1635 raise OSError('Cannot open "destfile"')
1508 assert 0 # shouldn't reach here. 1636 assert 0 # shouldn't reach here.
1509 1637
1510 self._set_shutil_open(_open) 1638 self._set_shutil_open(_open)
1511 1639
1512 shutil.copyfile('srcfile', 'destfile') 1640 shutil.copyfile('srcfile', 'destfile')
1513 self.assertTrue(srcfile._entered) 1641 self.assertTrue(srcfile._entered)
1514 self.assertIs(srcfile._exited_with[0], IOError) 1642 self.assertIs(srcfile._exited_with[0], OSError)
1515 self.assertEqual(srcfile._exited_with[1].args, 1643 self.assertEqual(srcfile._exited_with[1].args,
1516 ('Cannot open "destfile"',)) 1644 ('Cannot open "destfile"',))
1517 1645
1518 def test_w_dest_close_fails(self): 1646 def test_w_dest_close_fails(self):
1519 1647
1520 srcfile = self.Faux() 1648 srcfile = self.Faux()
1521 destfile = self.Faux(True) 1649 destfile = self.Faux(True)
1522 1650
1523 def _open(filename, mode='r'): 1651 def _open(filename, mode='r'):
1524 if filename == 'srcfile': 1652 if filename == 'srcfile':
1525 return srcfile 1653 return srcfile
1526 if filename == 'destfile': 1654 if filename == 'destfile':
1527 return destfile 1655 return destfile
1528 assert 0 # shouldn't reach here. 1656 assert 0 # shouldn't reach here.
1529 1657
1530 self._set_shutil_open(_open) 1658 self._set_shutil_open(_open)
1531 1659
1532 shutil.copyfile('srcfile', 'destfile') 1660 shutil.copyfile('srcfile', 'destfile')
1533 self.assertTrue(srcfile._entered) 1661 self.assertTrue(srcfile._entered)
1534 self.assertTrue(destfile._entered) 1662 self.assertTrue(destfile._entered)
1535 self.assertTrue(destfile._raised) 1663 self.assertTrue(destfile._raised)
1536 self.assertIs(srcfile._exited_with[0], IOError) 1664 self.assertIs(srcfile._exited_with[0], OSError)
1537 self.assertEqual(srcfile._exited_with[1].args, 1665 self.assertEqual(srcfile._exited_with[1].args,
1538 ('Cannot close',)) 1666 ('Cannot close',))
1539 1667
1540 def test_w_source_close_fails(self): 1668 def test_w_source_close_fails(self):
1541 1669
1542 srcfile = self.Faux(True) 1670 srcfile = self.Faux(True)
1543 destfile = self.Faux() 1671 destfile = self.Faux()
1544 1672
1545 def _open(filename, mode='r'): 1673 def _open(filename, mode='r'):
1546 if filename == 'srcfile': 1674 if filename == 'srcfile':
1547 return srcfile 1675 return srcfile
1548 if filename == 'destfile': 1676 if filename == 'destfile':
1549 return destfile 1677 return destfile
1550 assert 0 # shouldn't reach here. 1678 assert 0 # shouldn't reach here.
1551 1679
1552 self._set_shutil_open(_open) 1680 self._set_shutil_open(_open)
1553 1681
1554 self.assertRaises(IOError, 1682 self.assertRaises(OSError,
1555 shutil.copyfile, 'srcfile', 'destfile') 1683 shutil.copyfile, 'srcfile', 'destfile')
1556 self.assertTrue(srcfile._entered) 1684 self.assertTrue(srcfile._entered)
1557 self.assertTrue(destfile._entered) 1685 self.assertTrue(destfile._entered)
1558 self.assertFalse(destfile._raised) 1686 self.assertFalse(destfile._raised)
1559 self.assertIsNone(srcfile._exited_with[0]) 1687 self.assertIsNone(srcfile._exited_with[0])
1560 self.assertTrue(srcfile._raised) 1688 self.assertTrue(srcfile._raised)
1561 1689
1562 def test_move_dir_caseinsensitive(self): 1690 def test_move_dir_caseinsensitive(self):
1563 # Renames a folder to the same name 1691 # Renames a folder to the same name
1564 # but a different case. 1692 # but a different case.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1615 expected = (int(size[1]), int(size[0])) # reversed order 1743 expected = (int(size[1]), int(size[0])) # reversed order
1616 1744
1617 with support.EnvironmentVarGuard() as env: 1745 with support.EnvironmentVarGuard() as env:
1618 del env['LINES'] 1746 del env['LINES']
1619 del env['COLUMNS'] 1747 del env['COLUMNS']
1620 actual = shutil.get_terminal_size() 1748 actual = shutil.get_terminal_size()
1621 1749
1622 self.assertEqual(expected, actual) 1750 self.assertEqual(expected, actual)
1623 1751
1624 1752
1625 def test_main():
1626 support.run_unittest(TestShutil, TestMove, TestCopyFile,
1627 TermsizeTests, TestWhich)
1628
1629 if __name__ == '__main__': 1753 if __name__ == '__main__':
1630 test_main() 1754 unittest.main()
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+