diff -r b916efe30d77 Lib/test/test_os.py --- a/Lib/test/test_os.py Fri Mar 22 15:27:52 2013 +0000 +++ b/Lib/test/test_os.py Fri Mar 22 13:26:03 2013 -0400 @@ -632,61 +632,67 @@ key = 'key=' self.assertRaises(OSError, os.environ.__delitem__, key) + class WalkTests(unittest.TestCase): """Tests for os.walk().""" + # Build: + # TESTFN/ + # TEST1/ a file kid and two directory kids + # tmp1 + # SUB1/ a file kid and a directory kid + # tmp2 + # SUB11/ no kids + # SUB2/ a file kid and a dirsymlink kid + # tmp3 + # link/ a symlink to TESTFN.2 + # broken_link + # TEST2/ + # tmp4 a lone file + + walk_path = os.path.join(support.TESTFN, "TEST1") + sub1_path = os.path.join(walk_path, "SUB1") + sub11_path = os.path.join(sub1_path, "SUB11") + sub2_path = os.path.join(walk_path, "SUB2") + tmp1_path = os.path.join(walk_path, "tmp1") + tmp2_path = os.path.join(sub1_path, "tmp2") + tmp3_path = os.path.join(sub2_path, "tmp3") + link_path = os.path.join(sub2_path, "link") + t2_path = os.path.join(support.TESTFN, "TEST2") + tmp4_path = os.path.join(support.TESTFN, "TEST2", "tmp4") + link_path = os.path.join(sub2_path, "link") + broken_link_path = os.path.join(sub2_path, "broken_link") def setUp(self): - import os - from os.path import join - - # Build: - # TESTFN/ - # TEST1/ a file kid and two directory kids - # tmp1 - # SUB1/ a file kid and a directory kid - # tmp2 - # SUB11/ no kids - # SUB2/ a file kid and a dirsymlink kid - # tmp3 - # link/ a symlink to TESTFN.2 - # broken_link - # TEST2/ - # tmp4 a lone file - walk_path = join(support.TESTFN, "TEST1") - sub1_path = join(walk_path, "SUB1") - sub11_path = join(sub1_path, "SUB11") - sub2_path = join(walk_path, "SUB2") - tmp1_path = join(walk_path, "tmp1") - tmp2_path = join(sub1_path, "tmp2") - tmp3_path = join(sub2_path, "tmp3") - link_path = join(sub2_path, "link") - t2_path = join(support.TESTFN, "TEST2") - tmp4_path = join(support.TESTFN, "TEST2", "tmp4") - link_path = join(sub2_path, "link") - broken_link_path = join(sub2_path, "broken_link") - - # Create stuff. - os.makedirs(sub11_path) - os.makedirs(sub2_path) - os.makedirs(t2_path) - for path in tmp1_path, tmp2_path, tmp3_path, tmp4_path: - f = open(path, "w") - f.write("I'm " + path + " and proud of it. Blame test_os.\n") - f.close() + os.makedirs(self.sub11_path) + os.makedirs(self.sub2_path) + os.makedirs(self.t2_path) + tmp_paths = ( + self.tmp1_path, + self.tmp2_path, + self.tmp3_path, + self.tmp4_path, + ) + for path in tmp_paths: + with open(path, "w") as f: + f.write("I'm " + path + " and proud of it. Blame test_os.\n") if support.can_symlink(): if os.name == 'nt': def symlink_to_dir(src, dest): os.symlink(src, dest, True) else: symlink_to_dir = os.symlink - symlink_to_dir(os.path.abspath(t2_path), link_path) - symlink_to_dir('broken', broken_link_path) - sub2_tree = (sub2_path, ["link"], ["broken_link", "tmp3"]) + symlink_to_dir(os.path.abspath(self.t2_path), self.link_path) + symlink_to_dir('broken', self.broken_link_path) + self.sub2_tree = ( + self.sub2_path, + ["link"], + ["broken_link", "tmp3"], + ) else: - sub2_tree = (sub2_path, [], ["tmp3"]) + self.sub2_tree = (self.sub2_path, [], ["tmp3"]) - # Walk top-down. - all = list(os.walk(walk_path)) + def test_walking_bottom_down(self): + all = list(os.walk(self.walk_path)) self.assertEqual(len(all), 4) # We can't know which order SUB1 and SUB2 will appear in. # Not flipped: TESTFN, SUB1, SUB11, SUB2 @@ -694,26 +700,32 @@ flipped = all[0][1][0] != "SUB1" all[0][1].sort() all[3 - 2 * flipped][-1].sort() - self.assertEqual(all[0], (walk_path, ["SUB1", "SUB2"], ["tmp1"])) - self.assertEqual(all[1 + flipped], (sub1_path, ["SUB11"], ["tmp2"])) - self.assertEqual(all[2 + flipped], (sub11_path, [], [])) - self.assertEqual(all[3 - 2 * flipped], sub2_tree) + self.assertEqual( + all[0], + (self.walk_path, ["SUB1", "SUB2"], ["tmp1"]), + ) + self.assertEqual( + all[1 + flipped], + (self.sub1_path, ["SUB11"], ["tmp2"]), + ) + self.assertEqual(all[2 + flipped], (self.sub11_path, [], [])) + self.assertEqual(all[3 - 2 * flipped], self.sub2_tree) # Prune the search. all = [] - for root, dirs, files in os.walk(walk_path): + for root, dirs, files in os.walk(self.walk_path): all.append((root, dirs, files)) # Don't descend into SUB1. if 'SUB1' in dirs: # Note that this also mutates the dirs we appended to all! dirs.remove('SUB1') self.assertEqual(len(all), 2) - self.assertEqual(all[0], (walk_path, ["SUB2"], ["tmp1"])) + self.assertEqual(all[0], (self.walk_path, ["SUB2"], ["tmp1"])) all[1][-1].sort() - self.assertEqual(all[1], sub2_tree) + self.assertEqual(all[1], self.sub2_tree) - # Walk bottom-up. - all = list(os.walk(walk_path, topdown=False)) + def test_walking_bottom_up(self): + all = list(os.walk(self.walk_path, topdown=False)) self.assertEqual(len(all), 4) # We can't know which order SUB1 and SUB2 will appear in. # Not flipped: SUB11, SUB1, SUB2, TESTFN @@ -721,15 +733,18 @@ flipped = all[3][1][0] != "SUB1" all[3][1].sort() all[2 - 2 * flipped][-1].sort() - self.assertEqual(all[3], (walk_path, ["SUB1", "SUB2"], ["tmp1"])) - self.assertEqual(all[flipped], (sub11_path, [], [])) - self.assertEqual(all[flipped + 1], (sub1_path, ["SUB11"], ["tmp2"])) - self.assertEqual(all[2 - 2 * flipped], sub2_tree) + self.assertEqual(all[3], (self.walk_path, ["SUB1", "SUB2"], ["tmp1"])) + self.assertEqual(all[flipped], (self.sub11_path, [], [])) + self.assertEqual( + all[flipped + 1], + (self.sub1_path, ["SUB11"], ["tmp2"]), + ) + self.assertEqual(all[2 - 2 * flipped], self.sub2_tree) if support.can_symlink(): # Walk, following symlinks. - for root, dirs, files in os.walk(walk_path, followlinks=True): - if root == link_path: + for root, dirs, files in os.walk(self.walk_path, followlinks=True): + if root == self.link_path: self.assertEqual(dirs, []) self.assertEqual(files, ["tmp4"]) break @@ -737,20 +752,7 @@ self.fail("Didn't follow symlink with followlinks=True") def tearDown(self): - # Tear everything down. This is a decent use for bottom-up on - # Windows, which doesn't have a recursive delete command. The - # (not so) subtlety is that rmdir will fail unless the dir's - # kids are removed first, so bottom up is essential. - for root, dirs, files in os.walk(support.TESTFN, topdown=False): - for name in files: - os.remove(os.path.join(root, name)) - for name in dirs: - dirname = os.path.join(root, name) - if not os.path.islink(dirname): - os.rmdir(dirname) - else: - os.remove(dirname) - os.rmdir(support.TESTFN) + shutil.rmtree(support.TESTFN) @unittest.skipUnless(hasattr(os, 'fwalk'), "Test needs os.fwalk()") @@ -829,84 +831,107 @@ class MakedirTests(unittest.TestCase): + base = support.TESTFN + file_path = os.path.join(base, 'file1') + def setUp(self): - os.mkdir(support.TESTFN) + os.mkdir(self.base) + with open(self.file_path, 'w') as f: + f.write('abc') - def test_makedir(self): - base = support.TESTFN - path = os.path.join(base, 'dir1', 'dir2', 'dir3') - os.makedirs(path) # Should work - path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4') + def tearDown(self): + shutil.rmtree(self.base) + + def test_one_level(self): + path = os.path.join(self.base, 'dir1') os.makedirs(path) + self.assertTrue(os.path.exists(path)) - # Try paths with a '.' in them + def test_two_levels(self): + path = os.path.join(self.base, 'dir1', 'dir2') + os.makedirs(path) + self.assertTrue(os.path.exists(path)) + + def test_dot_at_the_end(self): + path = os.path.join(self.base, 'dir1', os.curdir) + os.makedirs(path) + expected = os.path.join(self.base, 'dir1') + self.assertTrue(os.path.exists(expected)) + + def test_dot_in_the_middle(self): + path = os.path.join(self.base, 'dir1', os.curdir, 'dir2') + os.makedirs(path) + expected = os.path.join(self.base, 'dir1', 'dir2') + self.assertTrue(os.path.exists(expected)) + + def test_slash_at_the_end(self): + path = os.path.join(self.base, 'dir1/') + os.makedirs(path) + expected = os.path.join(self.base, 'dir1') + self.assertTrue(os.path.exists(expected)) + + def test_excepts_on_existing_directory(self): self.assertRaises(OSError, os.makedirs, os.curdir) - path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4', 'dir5', os.curdir) + + def test_regular_file_exist_ok_true(self): + self.assertRaises(OSError, os.makedirs, self.file_path, exist_ok=True) + + def test_regular_file_exist_ok_false(self): + path = os.path.join(self.base, 'file1') + self.assertRaises(OSError, os.makedirs, self.file_path, exist_ok=False) + + def test_byte_strings(self): + path = os.path.join(bytes(self.base, 'ascii'), b'dir1', b'dir2') os.makedirs(path) - path = os.path.join(base, 'dir1', os.curdir, 'dir2', 'dir3', 'dir4', - 'dir5', 'dir6') - os.makedirs(path) + expected = os.path.join(self.base, 'dir1', 'dir2') + self.assertTrue(os.path.exists(expected)) - def test_exist_ok_existing_directory(self): - path = os.path.join(support.TESTFN, 'dir1') - mode = 0o777 - old_mask = os.umask(0o022) - os.makedirs(path, mode) - self.assertRaises(OSError, os.makedirs, path, mode) - self.assertRaises(OSError, os.makedirs, path, mode, exist_ok=False) - self.assertRaises(OSError, os.makedirs, path, 0o776, exist_ok=True) - os.makedirs(path, mode=mode, exist_ok=True) - os.umask(old_mask) + +class MakedirWithModeTests(unittest.TestCase): + base = support.TESTFN + mode = 0o777 + + def setUp(self): + self.old_mask = os.umask(0o022) + self.test_dir = os.path.join(self.base, 'dir1') + os.mkdir(self.base) + os.makedirs(self.test_dir, self.mode) + + def tearDown(self): + os.umask(self.old_mask) + shutil.rmtree(self.base) + + def test_excepts_on_exising_directory(self): + self.assertRaises(OSError, os.makedirs, self.test_dir, self.mode) + + def test_allow_exist_ok(self): + os.makedirs(self.test_dir, self.mode, exist_ok=True) + + def test_excepts_on_exising_with_exist_ok_and_invalid_mode(self): + self.assertRaises(OSError, os.makedirs, self.test_dir, 0o776, + exist_ok=True) def test_exist_ok_s_isgid_directory(self): - path = os.path.join(support.TESTFN, 'dir1') + path = os.path.join(self.base, 'dir1', 'dir2') S_ISGID = stat.S_ISGID - mode = 0o777 - old_mask = os.umask(0o022) + existing_testfn_mode = stat.S_IMODE(os.lstat(self.base).st_mode) try: - existing_testfn_mode = stat.S_IMODE( - os.lstat(support.TESTFN).st_mode) - try: - os.chmod(support.TESTFN, existing_testfn_mode | S_ISGID) - except PermissionError: - raise unittest.SkipTest('Cannot set S_ISGID for dir.') - if (os.lstat(support.TESTFN).st_mode & S_ISGID != S_ISGID): - raise unittest.SkipTest('No support for S_ISGID dir mode.') - # The os should apply S_ISGID from the parent dir for us, but - # this test need not depend on that behavior. Be explicit. - os.makedirs(path, mode | S_ISGID) - # http://bugs.python.org/issue14992 - # Should not fail when the bit is already set. - os.makedirs(path, mode, exist_ok=True) - # remove the bit. - os.chmod(path, stat.S_IMODE(os.lstat(path).st_mode) & ~S_ISGID) - with self.assertRaises(OSError): - # Should fail when the bit is not already set when demanded. - os.makedirs(path, mode | S_ISGID, exist_ok=True) - finally: - os.umask(old_mask) - - def test_exist_ok_existing_regular_file(self): - base = support.TESTFN - path = os.path.join(support.TESTFN, 'dir1') - f = open(path, 'w') - f.write('abc') - f.close() - self.assertRaises(OSError, os.makedirs, path) - self.assertRaises(OSError, os.makedirs, path, exist_ok=False) - self.assertRaises(OSError, os.makedirs, path, exist_ok=True) - os.remove(path) - - def tearDown(self): - path = os.path.join(support.TESTFN, 'dir1', 'dir2', 'dir3', - 'dir4', 'dir5', 'dir6') - # If the tests failed, the bottom-most directory ('../dir6') - # may not have been created, so we look for the outermost directory - # that exists. - while not os.path.exists(path) and path != support.TESTFN: - path = os.path.dirname(path) - - os.removedirs(path) + os.chmod(self.base, existing_testfn_mode | S_ISGID) + except PermissionError: + raise unittest.SkipTest('Cannot set S_ISGID for dir.') + if (os.lstat(self.base).st_mode & S_ISGID != S_ISGID): + raise unittest.SkipTest('No support for S_ISGID dir mode.') + # The os should apply S_ISGID from the parent dir for us, but + # this test need not depend on that behavior. Be explicit. + os.makedirs(path, self.mode | S_ISGID) + # http://bugs.python.org/issue14992 + # Should not fail when the bit is already set. + os.makedirs(path, self.mode, exist_ok=True) + # remove the bit. + os.chmod(path, stat.S_IMODE(os.lstat(path).st_mode) & ~S_ISGID) + with self.assertRaises(OSError): + # Should fail when the bit is not already set when demanded. + os.makedirs(path, self.mode | S_ISGID, exist_ok=True) class RemoveDirsTests(unittest.TestCase): @@ -951,6 +976,13 @@ self.assertTrue(os.path.exists(dira)) self.assertTrue(os.path.exists(support.TESTFN)) + def test_slash_at_the_end(self): + expected = os.path.join(support.TESTFN, 'dir1') + path = os.path.join(support.TESTFN, 'dir1/') + os.mkdir(expected) + os.removedirs(path) + self.assertFalse(os.path.exists(expected)) + class DevNullTests(unittest.TestCase): def test_devnull(self): @@ -2204,6 +2236,30 @@ else: self.fail("No exception thrown by {}".format(func)) + +class RenamesTests(unittest.TestCase): + base = support.TESTFN + rename_base = os.path.join(base, 'dir_from') + + def setUp(self): + os.makedirs(self.rename_base) + + def tearDown(self): + shutil.rmtree(self.base) + + def test_at_same_level(self): + path = os.path.join(self.base, 'dir_to') + os.renames(self.rename_base, path) + self.assertTrue(os.path.exists(path)) + self.assertFalse(os.path.exists(self.rename_base)) + + def test_at_one_level_deep(self): + path = os.path.join(self.base, 'dir1', 'dir_to') + os.renames(self.rename_base, path) + self.assertTrue(os.path.exists(path)) + self.assertFalse(os.path.exists(self.rename_base)) + + @support.reap_threads def test_main(): support.run_unittest( @@ -2213,6 +2269,7 @@ WalkTests, FwalkTests, MakedirTests, + MakedirWithModeTests, DevNullTests, URandomTests, ExecTests, @@ -2234,6 +2291,7 @@ TermsizeTests, OSErrorTests, RemoveDirsTests, + RenamesTests, ) if __name__ == "__main__":