| LEFT | RIGHT |
| 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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 return d | 109 return d |
| 110 | 110 |
| 111 def test_rmtree_works_on_bytes(self): | 111 def test_rmtree_works_on_bytes(self): |
| 112 tmp = self.mkdtemp() | 112 tmp = self.mkdtemp() |
| 113 victim = os.path.join(tmp, 'killme') | 113 victim = os.path.join(tmp, 'killme') |
| 114 os.mkdir(victim) | 114 os.mkdir(victim) |
| 115 write_file(os.path.join(victim, 'somefile'), 'foo') | 115 write_file(os.path.join(victim, 'somefile'), 'foo') |
| 116 victim = os.fsencode(victim) | 116 victim = os.fsencode(victim) |
| 117 self.assertIsInstance(victim, bytes) | 117 self.assertIsInstance(victim, bytes) |
| 118 shutil.rmtree(victim) | 118 shutil.rmtree(victim) |
| 119 |
| 120 @support.skip_unless_symlink |
| 121 def test_rmtree_fails_on_symlink(self): |
| 122 tmp = self.mkdtemp() |
| 123 dir_ = os.path.join(tmp, 'dir') |
| 124 os.mkdir(dir_) |
| 125 link = os.path.join(tmp, 'link') |
| 126 os.symlink(dir_, link) |
| 127 self.assertRaises(OSError, shutil.rmtree, link) |
| 128 self.assertTrue(os.path.exists(dir_)) |
| 129 |
| 130 @support.skip_unless_symlink |
| 131 def test_rmtree_works_on_symlinks(self): |
| 132 tmp = self.mkdtemp() |
| 133 dir1 = os.path.join(tmp, 'dir1') |
| 134 dir2 = os.path.join(dir1, 'dir2') |
| 135 dir3 = os.path.join(tmp, 'dir3') |
| 136 for d in dir1, dir2, dir3: |
| 137 os.mkdir(d) |
| 138 file1 = os.path.join(tmp, 'file1') |
| 139 write_file(file1, 'foo') |
| 140 link1 = os.path.join(dir1, 'link1') |
| 141 os.symlink(dir2, link1) |
| 142 link2 = os.path.join(dir1, 'link2') |
| 143 os.symlink(dir3, link2) |
| 144 link3 = os.path.join(dir1, 'link3') |
| 145 os.symlink(file1, link3) |
| 146 # make sure symlinks are removed but not followed |
| 147 shutil.rmtree(dir1) |
| 148 self.assertFalse(os.path.exists(dir1)) |
| 149 self.assertTrue(os.path.exists(dir3)) |
| 150 self.assertTrue(os.path.exists(file1)) |
| 119 | 151 |
| 120 def test_rmtree_errors(self): | 152 def test_rmtree_errors(self): |
| 121 # filename is guaranteed not to exist | 153 # filename is guaranteed not to exist |
| 122 filename = tempfile.mktemp() | 154 filename = tempfile.mktemp() |
| 123 self.assertRaises(OSError, shutil.rmtree, filename) | 155 self.assertRaises(OSError, shutil.rmtree, filename) |
| 124 | 156 |
| 125 # See bug #1071513 for why we don't run this on cygwin | 157 # See bug #1071513 for why we don't run this on cygwin |
| 126 # and bug #1076467 for why we don't run this as root. | 158 # and bug #1076467 for why we don't run this as root. |
| 127 if (hasattr(os, 'chmod') and sys.platform[:6] != 'cygwin' | 159 if (hasattr(os, 'chmod') and sys.platform[:6] != 'cygwin' |
| 128 and not (hasattr(os, 'geteuid') and os.geteuid() == 0)): | 160 and not (hasattr(os, 'geteuid') and os.geteuid() == 0)): |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 self.errorState += 1 | 209 self.errorState += 1 |
| 178 else: | 210 else: |
| 179 self.assertEqual(func, os.rmdir) | 211 self.assertEqual(func, os.rmdir) |
| 180 self.assertEqual(arg, TESTFN) | 212 self.assertEqual(arg, TESTFN) |
| 181 self.assertTrue(issubclass(exc[0], OSError)) | 213 self.assertTrue(issubclass(exc[0], OSError)) |
| 182 self.errorState = 3 | 214 self.errorState = 3 |
| 183 | 215 |
| 184 def test_rmtree_does_not_choke_on_failing_lstat(self): | 216 def test_rmtree_does_not_choke_on_failing_lstat(self): |
| 185 try: | 217 try: |
| 186 orig_lstat = os.lstat | 218 orig_lstat = os.lstat |
| 187 def raiser(fn): | 219 def raiser(fn, *args, **kwargs): |
| 188 if fn != TESTFN: | 220 if fn != TESTFN: |
| 189 raise OSError() | 221 raise OSError() |
| 190 else: | 222 else: |
| 191 return orig_lstat(fn) | 223 return orig_lstat(fn) |
| 192 os.lstat = raiser | 224 os.lstat = raiser |
| 193 | 225 |
| 194 os.mkdir(TESTFN) | 226 os.mkdir(TESTFN) |
| 195 write_file((TESTFN, 'foo'), 'foo') | 227 write_file((TESTFN, 'foo'), 'foo') |
| 196 shutil.rmtree(TESTFN) | 228 shutil.rmtree(TESTFN) |
| 197 finally: | 229 finally: |
| 198 os.lstat = orig_lstat | 230 os.lstat = orig_lstat |
| 199 | 231 |
| 200 @unittest.skipUnless(hasattr(os, 'chmod'), 'requires os.chmod') | 232 @unittest.skipUnless(hasattr(os, 'chmod'), 'requires os.chmod') |
| 201 @support.skip_unless_symlink | 233 @support.skip_unless_symlink |
| 202 def test_copymode_followlinks(self): | 234 def test_copymode_follow_symlinks(self): |
| 203 tmp_dir = self.mkdtemp() | 235 tmp_dir = self.mkdtemp() |
| 204 src = os.path.join(tmp_dir, 'foo') | 236 src = os.path.join(tmp_dir, 'foo') |
| 205 dst = os.path.join(tmp_dir, 'bar') | 237 dst = os.path.join(tmp_dir, 'bar') |
| 206 src_link = os.path.join(tmp_dir, 'baz') | 238 src_link = os.path.join(tmp_dir, 'baz') |
| 207 dst_link = os.path.join(tmp_dir, 'quux') | 239 dst_link = os.path.join(tmp_dir, 'quux') |
| 208 write_file(src, 'foo') | 240 write_file(src, 'foo') |
| 209 write_file(dst, 'foo') | 241 write_file(dst, 'foo') |
| 210 os.symlink(src, src_link) | 242 os.symlink(src, src_link) |
| 211 os.symlink(dst, dst_link) | 243 os.symlink(dst, dst_link) |
| 212 os.chmod(src, stat.S_IRWXU|stat.S_IRWXG) | 244 os.chmod(src, stat.S_IRWXU|stat.S_IRWXG) |
| (...skipping 25 matching lines...) Expand all Loading... |
| 238 dst_link = os.path.join(tmp_dir, 'quux') | 270 dst_link = os.path.join(tmp_dir, 'quux') |
| 239 write_file(src, 'foo') | 271 write_file(src, 'foo') |
| 240 write_file(dst, 'foo') | 272 write_file(dst, 'foo') |
| 241 os.symlink(src, src_link) | 273 os.symlink(src, src_link) |
| 242 os.symlink(dst, dst_link) | 274 os.symlink(dst, dst_link) |
| 243 os.chmod(src, stat.S_IRWXU|stat.S_IRWXG) | 275 os.chmod(src, stat.S_IRWXU|stat.S_IRWXG) |
| 244 os.chmod(dst, stat.S_IRWXU) | 276 os.chmod(dst, stat.S_IRWXU) |
| 245 os.lchmod(src_link, stat.S_IRWXO|stat.S_IRWXG) | 277 os.lchmod(src_link, stat.S_IRWXO|stat.S_IRWXG) |
| 246 # link to link | 278 # link to link |
| 247 os.lchmod(dst_link, stat.S_IRWXO) | 279 os.lchmod(dst_link, stat.S_IRWXO) |
| 248 shutil.copymode(src_link, dst_link, symlinks=True) | 280 shutil.copymode(src_link, dst_link, follow_symlinks=False) |
| 249 self.assertEqual(os.lstat(src_link).st_mode, | 281 self.assertEqual(os.lstat(src_link).st_mode, |
| 250 os.lstat(dst_link).st_mode) | 282 os.lstat(dst_link).st_mode) |
| 251 self.assertNotEqual(os.stat(src).st_mode, os.stat(dst).st_mode) | 283 self.assertNotEqual(os.stat(src).st_mode, os.stat(dst).st_mode) |
| 252 # src link - use chmod | 284 # src link - use chmod |
| 253 os.lchmod(dst_link, stat.S_IRWXO) | 285 os.lchmod(dst_link, stat.S_IRWXO) |
| 254 shutil.copymode(src_link, dst, symlinks=True) | 286 shutil.copymode(src_link, dst, follow_symlinks=False) |
| 255 self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode) | 287 self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode) |
| 256 # dst link - use chmod | 288 # dst link - use chmod |
| 257 os.lchmod(dst_link, stat.S_IRWXO) | 289 os.lchmod(dst_link, stat.S_IRWXO) |
| 258 shutil.copymode(src, dst_link, symlinks=True) | 290 shutil.copymode(src, dst_link, follow_symlinks=False) |
| 259 self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode) | 291 self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode) |
| 260 | 292 |
| 261 @unittest.skipIf(hasattr(os, 'lchmod'), 'requires os.lchmod to be missing') | 293 @unittest.skipIf(hasattr(os, 'lchmod'), 'requires os.lchmod to be missing') |
| 262 @support.skip_unless_symlink | 294 @support.skip_unless_symlink |
| 263 def test_copymode_symlink_to_symlink_wo_lchmod(self): | 295 def test_copymode_symlink_to_symlink_wo_lchmod(self): |
| 264 tmp_dir = self.mkdtemp() | 296 tmp_dir = self.mkdtemp() |
| 265 src = os.path.join(tmp_dir, 'foo') | 297 src = os.path.join(tmp_dir, 'foo') |
| 266 dst = os.path.join(tmp_dir, 'bar') | 298 dst = os.path.join(tmp_dir, 'bar') |
| 267 src_link = os.path.join(tmp_dir, 'baz') | 299 src_link = os.path.join(tmp_dir, 'baz') |
| 268 dst_link = os.path.join(tmp_dir, 'quux') | 300 dst_link = os.path.join(tmp_dir, 'quux') |
| 269 write_file(src, 'foo') | 301 write_file(src, 'foo') |
| 270 write_file(dst, 'foo') | 302 write_file(dst, 'foo') |
| 271 os.symlink(src, src_link) | 303 os.symlink(src, src_link) |
| 272 os.symlink(dst, dst_link) | 304 os.symlink(dst, dst_link) |
| 273 shutil.copymode(src_link, dst_link, symlinks=True) # silent fail | 305 shutil.copymode(src_link, dst_link, follow_symlinks=False) # silent fai
l |
| 274 | 306 |
| 275 @support.skip_unless_symlink | 307 @support.skip_unless_symlink |
| 276 def test_copystat_symlinks(self): | 308 def test_copystat_symlinks(self): |
| 277 tmp_dir = self.mkdtemp() | 309 tmp_dir = self.mkdtemp() |
| 278 src = os.path.join(tmp_dir, 'foo') | 310 src = os.path.join(tmp_dir, 'foo') |
| 279 dst = os.path.join(tmp_dir, 'bar') | 311 dst = os.path.join(tmp_dir, 'bar') |
| 280 src_link = os.path.join(tmp_dir, 'baz') | 312 src_link = os.path.join(tmp_dir, 'baz') |
| 281 dst_link = os.path.join(tmp_dir, 'qux') | 313 dst_link = os.path.join(tmp_dir, 'qux') |
| 282 write_file(src, 'foo') | 314 write_file(src, 'foo') |
| 283 src_stat = os.stat(src) | 315 src_stat = os.stat(src) |
| 284 os.utime(src, (src_stat.st_atime, | 316 os.utime(src, (src_stat.st_atime, |
| 285 src_stat.st_mtime - 42.0)) # ensure different mtimes | 317 src_stat.st_mtime - 42.0)) # ensure different mtimes |
| 286 write_file(dst, 'bar') | 318 write_file(dst, 'bar') |
| 287 self.assertNotEqual(os.stat(src).st_mtime, os.stat(dst).st_mtime) | 319 self.assertNotEqual(os.stat(src).st_mtime, os.stat(dst).st_mtime) |
| 288 os.symlink(src, src_link) | 320 os.symlink(src, src_link) |
| 289 os.symlink(dst, dst_link) | 321 os.symlink(dst, dst_link) |
| 290 if hasattr(os, 'lchmod'): | 322 if hasattr(os, 'lchmod'): |
| 291 os.lchmod(src_link, stat.S_IRWXO) | 323 os.lchmod(src_link, stat.S_IRWXO) |
| 292 if hasattr(os, 'lchflags') and hasattr(stat, 'UF_NODUMP'): | 324 if hasattr(os, 'lchflags') and hasattr(stat, 'UF_NODUMP'): |
| 293 os.lchflags(src_link, stat.UF_NODUMP) | 325 os.lchflags(src_link, stat.UF_NODUMP) |
| 294 src_link_stat = os.lstat(src_link) | 326 src_link_stat = os.lstat(src_link) |
| 295 # follow | 327 # follow |
| 296 if hasattr(os, 'lchmod'): | 328 if hasattr(os, 'lchmod'): |
| 297 shutil.copystat(src_link, dst_link, symlinks=False) | 329 shutil.copystat(src_link, dst_link, follow_symlinks=True) |
| 298 self.assertNotEqual(src_link_stat.st_mode, os.stat(dst).st_mode) | 330 self.assertNotEqual(src_link_stat.st_mode, os.stat(dst).st_mode) |
| 299 # don't follow | 331 # don't follow |
| 300 shutil.copystat(src_link, dst_link, symlinks=True) | 332 shutil.copystat(src_link, dst_link, follow_symlinks=False) |
| 301 dst_link_stat = os.lstat(dst_link) | 333 dst_link_stat = os.lstat(dst_link) |
| 302 if os.utime in os.supports_followlinks: | 334 if os.utime in os.supports_follow_symlinks: |
| 303 for attr in 'st_atime', 'st_mtime': | 335 for attr in 'st_atime', 'st_mtime': |
| 304 # The modification times may be truncated in the new file. | 336 # The modification times may be truncated in the new file. |
| 305 self.assertLessEqual(getattr(src_link_stat, attr), | 337 self.assertLessEqual(getattr(src_link_stat, attr), |
| 306 getattr(dst_link_stat, attr) + 1) | 338 getattr(dst_link_stat, attr) + 1) |
| 307 if hasattr(os, 'lchmod'): | 339 if hasattr(os, 'lchmod'): |
| 308 self.assertEqual(src_link_stat.st_mode, dst_link_stat.st_mode) | 340 self.assertEqual(src_link_stat.st_mode, dst_link_stat.st_mode) |
| 309 if hasattr(os, 'lchflags') and hasattr(src_link_stat, 'st_flags'): | 341 if hasattr(os, 'lchflags') and hasattr(src_link_stat, 'st_flags'): |
| 310 self.assertEqual(src_link_stat.st_flags, dst_link_stat.st_flags) | 342 self.assertEqual(src_link_stat.st_flags, dst_link_stat.st_flags) |
| 311 # tell to follow but dst is not a link | 343 # tell to follow but dst is not a link |
| 312 shutil.copystat(src_link, dst, symlinks=True) | 344 shutil.copystat(src_link, dst, follow_symlinks=False) |
| 313 self.assertTrue(abs(os.stat(src).st_mtime - os.stat(dst).st_mtime) < | 345 self.assertTrue(abs(os.stat(src).st_mtime - os.stat(dst).st_mtime) < |
| 314 00000.1) | 346 00000.1) |
| 315 | 347 |
| 316 @unittest.skipUnless(hasattr(os, 'chflags') and | 348 @unittest.skipUnless(hasattr(os, 'chflags') and |
| 317 hasattr(errno, 'EOPNOTSUPP') and | 349 hasattr(errno, 'EOPNOTSUPP') and |
| 318 hasattr(errno, 'ENOTSUP'), | 350 hasattr(errno, 'ENOTSUP'), |
| 319 "requires os.chflags, EOPNOTSUPP & ENOTSUP") | 351 "requires os.chflags, EOPNOTSUPP & ENOTSUP") |
| 320 def test_copystat_handles_harmless_chflags_errors(self): | 352 def test_copystat_handles_harmless_chflags_errors(self): |
| 321 tmpdir = self.mkdtemp() | 353 tmpdir = self.mkdtemp() |
| 322 file1 = os.path.join(tmpdir, 'file1') | 354 file1 = os.path.join(tmpdir, 'file1') |
| 323 file2 = os.path.join(tmpdir, 'file2') | 355 file2 = os.path.join(tmpdir, 'file2') |
| 324 write_file(file1, 'xxx') | 356 write_file(file1, 'xxx') |
| 325 write_file(file2, 'xxx') | 357 write_file(file2, 'xxx') |
| 326 | 358 |
| 327 def make_chflags_raiser(err): | 359 def make_chflags_raiser(err): |
| 328 ex = OSError() | 360 ex = OSError() |
| 329 | 361 |
| 330 def _chflags_raiser(path, flags, *, followlinks=True): | 362 def _chflags_raiser(path, flags, *, follow_symlinks=True): |
| 331 ex.errno = err | 363 ex.errno = err |
| 332 raise ex | 364 raise ex |
| 333 return _chflags_raiser | 365 return _chflags_raiser |
| 334 old_chflags = os.chflags | 366 old_chflags = os.chflags |
| 335 try: | 367 try: |
| 336 for err in errno.EOPNOTSUPP, errno.ENOTSUP: | 368 for err in errno.EOPNOTSUPP, errno.ENOTSUP: |
| 337 os.chflags = make_chflags_raiser(err) | 369 os.chflags = make_chflags_raiser(err) |
| 338 shutil.copystat(file1, file2) | 370 shutil.copystat(file1, file2) |
| 339 # assert others errors break it | 371 # assert others errors break it |
| 340 os.chflags = make_chflags_raiser(errno.EOPNOTSUPP + errno.ENOTSUP) | 372 os.chflags = make_chflags_raiser(errno.EOPNOTSUPP + errno.ENOTSUP) |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 def test_copyxattr_symlinks(self): | 417 def test_copyxattr_symlinks(self): |
| 386 # On Linux, it's only possible to access non-user xattr for symlinks; | 418 # On Linux, it's only possible to access non-user xattr for symlinks; |
| 387 # which in turn require root privileges. This test should be expanded | 419 # which in turn require root privileges. This test should be expanded |
| 388 # as soon as other platforms gain support for extended attributes. | 420 # as soon as other platforms gain support for extended attributes. |
| 389 tmp_dir = self.mkdtemp() | 421 tmp_dir = self.mkdtemp() |
| 390 src = os.path.join(tmp_dir, 'foo') | 422 src = os.path.join(tmp_dir, 'foo') |
| 391 src_link = os.path.join(tmp_dir, 'baz') | 423 src_link = os.path.join(tmp_dir, 'baz') |
| 392 write_file(src, 'foo') | 424 write_file(src, 'foo') |
| 393 os.symlink(src, src_link) | 425 os.symlink(src, src_link) |
| 394 os.setxattr(src, 'trusted.foo', b'42') | 426 os.setxattr(src, 'trusted.foo', b'42') |
| 395 os.setxattr(src_link, 'trusted.foo', b'43', followlinks=False) | 427 os.setxattr(src_link, 'trusted.foo', b'43', follow_symlinks=False) |
| 396 dst = os.path.join(tmp_dir, 'bar') | 428 dst = os.path.join(tmp_dir, 'bar') |
| 397 dst_link = os.path.join(tmp_dir, 'qux') | 429 dst_link = os.path.join(tmp_dir, 'qux') |
| 398 write_file(dst, 'bar') | 430 write_file(dst, 'bar') |
| 399 os.symlink(dst, dst_link) | 431 os.symlink(dst, dst_link) |
| 400 shutil._copyxattr(src_link, dst_link, symlinks=True) | 432 shutil._copyxattr(src_link, dst_link, follow_symlinks=False) |
| 401 self.assertEqual(os.getxattr(dst_link, 'trusted.foo', followlinks=False)
, b'43') | 433 self.assertEqual(os.getxattr(dst_link, 'trusted.foo', follow_symlinks=Fa
lse), b'43') |
| 402 self.assertRaises(OSError, os.getxattr, dst, 'trusted.foo') | 434 self.assertRaises(OSError, os.getxattr, dst, 'trusted.foo') |
| 403 shutil._copyxattr(src_link, dst, symlinks=True) | 435 shutil._copyxattr(src_link, dst, follow_symlinks=False) |
| 404 self.assertEqual(os.getxattr(dst, 'trusted.foo'), b'43') | 436 self.assertEqual(os.getxattr(dst, 'trusted.foo'), b'43') |
| 405 | 437 |
| 406 @support.skip_unless_symlink | 438 @support.skip_unless_symlink |
| 407 def test_copy_symlinks(self): | 439 def test_copy_symlinks(self): |
| 408 tmp_dir = self.mkdtemp() | 440 tmp_dir = self.mkdtemp() |
| 409 src = os.path.join(tmp_dir, 'foo') | 441 src = os.path.join(tmp_dir, 'foo') |
| 410 dst = os.path.join(tmp_dir, 'bar') | 442 dst = os.path.join(tmp_dir, 'bar') |
| 411 src_link = os.path.join(tmp_dir, 'baz') | 443 src_link = os.path.join(tmp_dir, 'baz') |
| 412 write_file(src, 'foo') | 444 write_file(src, 'foo') |
| 413 os.symlink(src, src_link) | 445 os.symlink(src, src_link) |
| 414 if hasattr(os, 'lchmod'): | 446 if hasattr(os, 'lchmod'): |
| 415 os.lchmod(src_link, stat.S_IRWXU | stat.S_IRWXO) | 447 os.lchmod(src_link, stat.S_IRWXU | stat.S_IRWXO) |
| 416 # don't follow | 448 # don't follow |
| 417 shutil.copy(src_link, dst, symlinks=False) | 449 shutil.copy(src_link, dst, follow_symlinks=True) |
| 418 self.assertFalse(os.path.islink(dst)) | 450 self.assertFalse(os.path.islink(dst)) |
| 419 self.assertEqual(read_file(src), read_file(dst)) | 451 self.assertEqual(read_file(src), read_file(dst)) |
| 420 os.remove(dst) | 452 os.remove(dst) |
| 421 # follow | 453 # follow |
| 422 shutil.copy(src_link, dst, symlinks=True) | 454 shutil.copy(src_link, dst, follow_symlinks=False) |
| 423 self.assertTrue(os.path.islink(dst)) | 455 self.assertTrue(os.path.islink(dst)) |
| 424 self.assertEqual(os.readlink(dst), os.readlink(src_link)) | 456 self.assertEqual(os.readlink(dst), os.readlink(src_link)) |
| 425 if hasattr(os, 'lchmod'): | 457 if hasattr(os, 'lchmod'): |
| 426 self.assertEqual(os.lstat(src_link).st_mode, | 458 self.assertEqual(os.lstat(src_link).st_mode, |
| 427 os.lstat(dst).st_mode) | 459 os.lstat(dst).st_mode) |
| 428 | 460 |
| 429 @support.skip_unless_symlink | 461 @support.skip_unless_symlink |
| 430 def test_copy2_symlinks(self): | 462 def test_copy2_symlinks(self): |
| 431 tmp_dir = self.mkdtemp() | 463 tmp_dir = self.mkdtemp() |
| 432 src = os.path.join(tmp_dir, 'foo') | 464 src = os.path.join(tmp_dir, 'foo') |
| 433 dst = os.path.join(tmp_dir, 'bar') | 465 dst = os.path.join(tmp_dir, 'bar') |
| 434 src_link = os.path.join(tmp_dir, 'baz') | 466 src_link = os.path.join(tmp_dir, 'baz') |
| 435 write_file(src, 'foo') | 467 write_file(src, 'foo') |
| 436 os.symlink(src, src_link) | 468 os.symlink(src, src_link) |
| 437 if hasattr(os, 'lchmod'): | 469 if hasattr(os, 'lchmod'): |
| 438 os.lchmod(src_link, stat.S_IRWXU | stat.S_IRWXO) | 470 os.lchmod(src_link, stat.S_IRWXU | stat.S_IRWXO) |
| 439 if hasattr(os, 'lchflags') and hasattr(stat, 'UF_NODUMP'): | 471 if hasattr(os, 'lchflags') and hasattr(stat, 'UF_NODUMP'): |
| 440 os.lchflags(src_link, stat.UF_NODUMP) | 472 os.lchflags(src_link, stat.UF_NODUMP) |
| 441 src_stat = os.stat(src) | 473 src_stat = os.stat(src) |
| 442 src_link_stat = os.lstat(src_link) | 474 src_link_stat = os.lstat(src_link) |
| 443 # follow | 475 # follow |
| 444 shutil.copy2(src_link, dst, symlinks=False) | 476 shutil.copy2(src_link, dst, follow_symlinks=True) |
| 445 self.assertFalse(os.path.islink(dst)) | 477 self.assertFalse(os.path.islink(dst)) |
| 446 self.assertEqual(read_file(src), read_file(dst)) | 478 self.assertEqual(read_file(src), read_file(dst)) |
| 447 os.remove(dst) | 479 os.remove(dst) |
| 448 # don't follow | 480 # don't follow |
| 449 shutil.copy2(src_link, dst, symlinks=True) | 481 shutil.copy2(src_link, dst, follow_symlinks=False) |
| 450 self.assertTrue(os.path.islink(dst)) | 482 self.assertTrue(os.path.islink(dst)) |
| 451 self.assertEqual(os.readlink(dst), os.readlink(src_link)) | 483 self.assertEqual(os.readlink(dst), os.readlink(src_link)) |
| 452 dst_stat = os.lstat(dst) | 484 dst_stat = os.lstat(dst) |
| 453 if os.utime in os.supports_followlinks: | 485 if os.utime in os.supports_follow_symlinks: |
| 454 for attr in 'st_atime', 'st_mtime': | 486 for attr in 'st_atime', 'st_mtime': |
| 455 # The modification times may be truncated in the new file. | 487 # The modification times may be truncated in the new file. |
| 456 self.assertLessEqual(getattr(src_link_stat, attr), | 488 self.assertLessEqual(getattr(src_link_stat, attr), |
| 457 getattr(dst_stat, attr) + 1) | 489 getattr(dst_stat, attr) + 1) |
| 458 if hasattr(os, 'lchmod'): | 490 if hasattr(os, 'lchmod'): |
| 459 self.assertEqual(src_link_stat.st_mode, dst_stat.st_mode) | 491 self.assertEqual(src_link_stat.st_mode, dst_stat.st_mode) |
| 460 self.assertNotEqual(src_stat.st_mode, dst_stat.st_mode) | 492 self.assertNotEqual(src_stat.st_mode, dst_stat.st_mode) |
| 461 if hasattr(os, 'lchflags') and hasattr(src_link_stat, 'st_flags'): | 493 if hasattr(os, 'lchflags') and hasattr(src_link_stat, 'st_flags'): |
| 462 self.assertEqual(src_link_stat.st_flags, dst_stat.st_flags) | 494 self.assertEqual(src_link_stat.st_flags, dst_stat.st_flags) |
| 463 | 495 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 477 @support.skip_unless_symlink | 509 @support.skip_unless_symlink |
| 478 def test_copyfile_symlinks(self): | 510 def test_copyfile_symlinks(self): |
| 479 tmp_dir = self.mkdtemp() | 511 tmp_dir = self.mkdtemp() |
| 480 src = os.path.join(tmp_dir, 'src') | 512 src = os.path.join(tmp_dir, 'src') |
| 481 dst = os.path.join(tmp_dir, 'dst') | 513 dst = os.path.join(tmp_dir, 'dst') |
| 482 dst_link = os.path.join(tmp_dir, 'dst_link') | 514 dst_link = os.path.join(tmp_dir, 'dst_link') |
| 483 link = os.path.join(tmp_dir, 'link') | 515 link = os.path.join(tmp_dir, 'link') |
| 484 write_file(src, 'foo') | 516 write_file(src, 'foo') |
| 485 os.symlink(src, link) | 517 os.symlink(src, link) |
| 486 # don't follow | 518 # don't follow |
| 487 shutil.copyfile(link, dst_link, symlinks=True) | 519 shutil.copyfile(link, dst_link, follow_symlinks=False) |
| 488 self.assertTrue(os.path.islink(dst_link)) | 520 self.assertTrue(os.path.islink(dst_link)) |
| 489 self.assertEqual(os.readlink(link), os.readlink(dst_link)) | 521 self.assertEqual(os.readlink(link), os.readlink(dst_link)) |
| 490 # follow | 522 # follow |
| 491 shutil.copyfile(link, dst) | 523 shutil.copyfile(link, dst) |
| 492 self.assertFalse(os.path.islink(dst)) | 524 self.assertFalse(os.path.islink(dst)) |
| 493 | 525 |
| 494 def test_rmtree_uses_safe_fd_version_if_available(self): | 526 def test_rmtree_uses_safe_fd_version_if_available(self): |
| 495 if os.unlink in os.supports_dir_fd and os.open in os.supports_dir_fd: | 527 _use_fd_functions = ({os.open, os.stat, os.unlink, os.rmdir} <= |
| 528 os.supports_dir_fd and |
| 529 os.listdir in os.supports_fd and |
| 530 os.stat in os.supports_follow_symlinks) |
| 531 if _use_fd_functions: |
| 496 self.assertTrue(shutil._use_fd_functions) | 532 self.assertTrue(shutil._use_fd_functions) |
| 497 self.assertTrue(shutil.rmtree.avoids_symlink_attacks) | 533 self.assertTrue(shutil.rmtree.avoids_symlink_attacks) |
| 498 tmp_dir = self.mkdtemp() | 534 tmp_dir = self.mkdtemp() |
| 499 d = os.path.join(tmp_dir, 'a') | 535 d = os.path.join(tmp_dir, 'a') |
| 500 os.mkdir(d) | 536 os.mkdir(d) |
| 501 try: | 537 try: |
| 502 real_rmtree = shutil._rmtree_safe_fd | 538 real_rmtree = shutil._rmtree_safe_fd |
| 503 class Called(Exception): pass | 539 class Called(Exception): pass |
| 504 def _raiser(*args, **kwargs): | 540 def _raiser(*args, **kwargs): |
| 505 raise Called | 541 raise Called |
| (...skipping 1059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1565 | 1601 |
| 1566 self.assertEqual(expected, actual) | 1602 self.assertEqual(expected, actual) |
| 1567 | 1603 |
| 1568 | 1604 |
| 1569 def test_main(): | 1605 def test_main(): |
| 1570 support.run_unittest(TestShutil, TestMove, TestCopyFile, | 1606 support.run_unittest(TestShutil, TestMove, TestCopyFile, |
| 1571 TermsizeTests, TestWhich) | 1607 TermsizeTests, TestWhich) |
| 1572 | 1608 |
| 1573 if __name__ == '__main__': | 1609 if __name__ == '__main__': |
| 1574 test_main() | 1610 test_main() |
| LEFT | RIGHT |