[Python-checkins] GH-89812: Churn `pathlib.Path` test methods (#105807)
barneygale
webhook-mailer at python.org
Wed Jun 14 21:31:33 EDT 2023
https://github.com/python/cpython/commit/10bf2cd404320252ef162d5699cb7ce52a970d44
commit: 10bf2cd404320252ef162d5699cb7ce52a970d44
branch: main
author: Barney Gale <barney.gale at gmail.com>
committer: barneygale <barney.gale at gmail.com>
date: 2023-06-15T01:31:30Z
summary:
GH-89812: Churn `pathlib.Path` test methods (#105807)
Re-arrange `pathlib.Path` test methods in source code. No other changes.
The test methods are arranged in two groups. The first group checks
`stat()`, `open()`, `iterdir()`, `readlink()`, and derived methods like
`exists()`, `read_text()`, `glob()` and `resolve()`. The second group
checks all other `Path` methods. To minimise the diff I've maintained the
method order within groups where possible.
This patch prepares the ground for a new `_AbstractPath` class, which will
support methods in the first group above. By churning the test methods
here, subsequent patches will be easier to review and less likely to break
things.
files:
M Lib/test/test_pathlib.py
diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py
index 46ac30e91e32..02a0f25e0bd9 100644
--- a/Lib/test/test_pathlib.py
+++ b/Lib/test/test_pathlib.py
@@ -1642,101 +1642,6 @@ def assertFileNotFound(self, func, *args, **kwargs):
def assertEqualNormCase(self, path_a, path_b):
self.assertEqual(os.path.normcase(path_a), os.path.normcase(path_b))
- def test_concrete_class(self):
- if self.cls is pathlib.Path:
- expected = pathlib.WindowsPath if os.name == 'nt' else pathlib.PosixPath
- else:
- expected = self.cls
- p = self.cls('a')
- self.assertIs(type(p), expected)
-
- def test_unsupported_flavour(self):
- if self.cls._flavour is os.path:
- self.skipTest("path flavour is supported")
- else:
- self.assertRaises(NotImplementedError, self.cls)
-
- def _test_cwd(self, p):
- q = self.cls(os.getcwd())
- self.assertEqual(p, q)
- self.assertEqualNormCase(str(p), str(q))
- self.assertIs(type(p), type(q))
- self.assertTrue(p.is_absolute())
-
- def test_cwd(self):
- p = self.cls.cwd()
- self._test_cwd(p)
-
- def test_absolute_common(self):
- P = self.cls
-
- with mock.patch("os.getcwd") as getcwd:
- getcwd.return_value = BASE
-
- # Simple relative paths.
- self.assertEqual(str(P().absolute()), BASE)
- self.assertEqual(str(P('.').absolute()), BASE)
- self.assertEqual(str(P('a').absolute()), os.path.join(BASE, 'a'))
- self.assertEqual(str(P('a', 'b', 'c').absolute()), os.path.join(BASE, 'a', 'b', 'c'))
-
- # Symlinks should not be resolved.
- self.assertEqual(str(P('linkB', 'fileB').absolute()), os.path.join(BASE, 'linkB', 'fileB'))
- self.assertEqual(str(P('brokenLink').absolute()), os.path.join(BASE, 'brokenLink'))
- self.assertEqual(str(P('brokenLinkLoop').absolute()), os.path.join(BASE, 'brokenLinkLoop'))
-
- # '..' entries should be preserved and not normalised.
- self.assertEqual(str(P('..').absolute()), os.path.join(BASE, '..'))
- self.assertEqual(str(P('a', '..').absolute()), os.path.join(BASE, 'a', '..'))
- self.assertEqual(str(P('..', 'b').absolute()), os.path.join(BASE, '..', 'b'))
-
- def _test_home(self, p):
- q = self.cls(os.path.expanduser('~'))
- self.assertEqual(p, q)
- self.assertEqualNormCase(str(p), str(q))
- self.assertIs(type(p), type(q))
- self.assertTrue(p.is_absolute())
-
- @unittest.skipIf(
- pwd is None, reason="Test requires pwd module to get homedir."
- )
- def test_home(self):
- with os_helper.EnvironmentVarGuard() as env:
- self._test_home(self.cls.home())
-
- env.clear()
- env['USERPROFILE'] = os.path.join(BASE, 'userprofile')
- self._test_home(self.cls.home())
-
- # bpo-38883: ignore `HOME` when set on windows
- env['HOME'] = os.path.join(BASE, 'home')
- self._test_home(self.cls.home())
-
- def test_with_segments(self):
- class P(self.cls):
- def __init__(self, *pathsegments, session_id):
- super().__init__(*pathsegments)
- self.session_id = session_id
-
- def with_segments(self, *pathsegments):
- return type(self)(*pathsegments, session_id=self.session_id)
- p = P(BASE, session_id=42)
- self.assertEqual(42, p.absolute().session_id)
- self.assertEqual(42, p.resolve().session_id)
- if not is_wasi: # WASI has no user accounts.
- self.assertEqual(42, p.with_segments('~').expanduser().session_id)
- self.assertEqual(42, (p / 'fileA').rename(p / 'fileB').session_id)
- self.assertEqual(42, (p / 'fileB').replace(p / 'fileA').session_id)
- if os_helper.can_symlink():
- self.assertEqual(42, (p / 'linkA').readlink().session_id)
- for path in p.iterdir():
- self.assertEqual(42, path.session_id)
- for path in p.glob('*'):
- self.assertEqual(42, path.session_id)
- for path in p.rglob('*'):
- self.assertEqual(42, path.session_id)
- for dirpath, dirnames, filenames in p.walk():
- self.assertEqual(42, dirpath.session_id)
-
def test_samefile(self):
fileA_path = os.path.join(BASE, 'fileA')
fileB_path = os.path.join(BASE, 'dirB', 'fileB')
@@ -1762,22 +1667,6 @@ def test_empty_path(self):
p = self.cls('')
self.assertEqual(p.stat(), os.stat('.'))
- @unittest.skipIf(is_wasi, "WASI has no user accounts.")
- def test_expanduser_common(self):
- P = self.cls
- p = P('~')
- self.assertEqual(p.expanduser(), P(os.path.expanduser('~')))
- p = P('foo')
- self.assertEqual(p.expanduser(), p)
- p = P('/~')
- self.assertEqual(p.expanduser(), p)
- p = P('../~')
- self.assertEqual(p.expanduser(), p)
- p = P(P('').absolute().anchor) / '~'
- self.assertEqual(p.expanduser(), p)
- p = P('~/a:b')
- self.assertEqual(p.expanduser(), P(os.path.expanduser('~'), './a:b'))
-
def test_exists(self):
P = self.cls
p = P(BASE)
@@ -2156,6 +2045,16 @@ def test_glob_above_recursion_limit(self):
with set_recursion_limit(recursion_limit):
list(base.glob('**'))
+ @os_helper.skip_unless_symlink
+ def test_readlink(self):
+ P = self.cls(BASE)
+ self.assertEqual((P / 'linkA').readlink(), self.cls('fileA'))
+ self.assertEqual((P / 'brokenLink').readlink(),
+ self.cls('non-existing'))
+ self.assertEqual((P / 'linkB').readlink(), self.cls('dirB'))
+ with self.assertRaises(OSError):
+ (P / 'fileA').readlink()
+
def _check_resolve(self, p, expected, strict=True):
q = p.resolve(strict)
self.assertEqual(q, expected)
@@ -2238,47 +2137,6 @@ def test_resolve_dot(self):
# Non-strict
self.assertEqual(r.resolve(strict=False), p / '3' / '4')
- def test_resolve_nonexist_relative_issue38671(self):
- p = self.cls('non', 'exist')
-
- old_cwd = os.getcwd()
- os.chdir(BASE)
- try:
- self.assertEqual(p.resolve(), self.cls(BASE, p))
- finally:
- os.chdir(old_cwd)
-
- @os_helper.skip_unless_working_chmod
- def test_chmod(self):
- p = self.cls(BASE) / 'fileA'
- mode = p.stat().st_mode
- # Clear writable bit.
- new_mode = mode & ~0o222
- p.chmod(new_mode)
- self.assertEqual(p.stat().st_mode, new_mode)
- # Set writable bit.
- new_mode = mode | 0o222
- p.chmod(new_mode)
- self.assertEqual(p.stat().st_mode, new_mode)
-
- # On Windows, os.chmod does not follow symlinks (issue #15411)
- @only_posix
- @os_helper.skip_unless_working_chmod
- def test_chmod_follow_symlinks_true(self):
- p = self.cls(BASE) / 'linkA'
- q = p.resolve()
- mode = q.stat().st_mode
- # Clear writable bit.
- new_mode = mode & ~0o222
- p.chmod(new_mode, follow_symlinks=True)
- self.assertEqual(q.stat().st_mode, new_mode)
- # Set writable bit
- new_mode = mode | 0o222
- p.chmod(new_mode, follow_symlinks=True)
- self.assertEqual(q.stat().st_mode, new_mode)
-
- # XXX also need a test for lchmod.
-
@os_helper.skip_unless_working_chmod
def test_stat(self):
p = self.cls(BASE) / 'fileA'
@@ -2311,82 +2169,396 @@ def test_lstat_nosymlink(self):
st = p.stat()
self.assertEqual(st, p.lstat())
- @unittest.skipUnless(pwd, "the pwd module is needed for this test")
- def test_owner(self):
- p = self.cls(BASE) / 'fileA'
- uid = p.stat().st_uid
- try:
- name = pwd.getpwuid(uid).pw_name
- except KeyError:
- self.skipTest(
- "user %d doesn't have an entry in the system database" % uid)
- self.assertEqual(name, p.owner())
-
- @unittest.skipUnless(grp, "the grp module is needed for this test")
- def test_group(self):
- p = self.cls(BASE) / 'fileA'
- gid = p.stat().st_gid
- try:
- name = grp.getgrgid(gid).gr_name
- except KeyError:
- self.skipTest(
- "group %d doesn't have an entry in the system database" % gid)
- self.assertEqual(name, p.group())
-
- def test_unlink(self):
- p = self.cls(BASE) / 'fileA'
- p.unlink()
- self.assertFileNotFound(p.stat)
- self.assertFileNotFound(p.unlink)
-
- def test_unlink_missing_ok(self):
- p = self.cls(BASE) / 'fileAAA'
- self.assertFileNotFound(p.unlink)
- p.unlink(missing_ok=True)
-
- def test_rmdir(self):
- p = self.cls(BASE) / 'dirA'
- for q in p.iterdir():
- q.unlink()
- p.rmdir()
- self.assertFileNotFound(p.stat)
- self.assertFileNotFound(p.unlink)
-
- @unittest.skipUnless(hasattr(os, "link"), "os.link() is not present")
- def test_hardlink_to(self):
+ def test_is_dir(self):
P = self.cls(BASE)
- target = P / 'fileA'
- size = target.stat().st_size
- # linking to another path.
- link = P / 'dirA' / 'fileAA'
- link.hardlink_to(target)
- self.assertEqual(link.stat().st_size, size)
- self.assertTrue(os.path.samefile(target, link))
- self.assertTrue(target.exists())
- # Linking to a str of a relative path.
- link2 = P / 'dirA' / 'fileAAA'
- target2 = rel_join('fileA')
- link2.hardlink_to(target2)
- self.assertEqual(os.stat(target2).st_size, size)
- self.assertTrue(link2.exists())
+ self.assertTrue((P / 'dirA').is_dir())
+ self.assertFalse((P / 'fileA').is_dir())
+ self.assertFalse((P / 'non-existing').is_dir())
+ self.assertFalse((P / 'fileA' / 'bah').is_dir())
+ if os_helper.can_symlink():
+ self.assertFalse((P / 'linkA').is_dir())
+ self.assertTrue((P / 'linkB').is_dir())
+ self.assertFalse((P/ 'brokenLink').is_dir(), False)
+ self.assertIs((P / 'dirA\udfff').is_dir(), False)
+ self.assertIs((P / 'dirA\x00').is_dir(), False)
- @unittest.skipIf(hasattr(os, "link"), "os.link() is present")
- def test_link_to_not_implemented(self):
+ def test_is_file(self):
P = self.cls(BASE)
- p = P / 'fileA'
- # linking to another path.
- q = P / 'dirA' / 'fileAA'
- with self.assertRaises(NotImplementedError):
- q.hardlink_to(p)
+ self.assertTrue((P / 'fileA').is_file())
+ self.assertFalse((P / 'dirA').is_file())
+ self.assertFalse((P / 'non-existing').is_file())
+ self.assertFalse((P / 'fileA' / 'bah').is_file())
+ if os_helper.can_symlink():
+ self.assertTrue((P / 'linkA').is_file())
+ self.assertFalse((P / 'linkB').is_file())
+ self.assertFalse((P/ 'brokenLink').is_file())
+ self.assertIs((P / 'fileA\udfff').is_file(), False)
+ self.assertIs((P / 'fileA\x00').is_file(), False)
- def test_rename(self):
+ def test_is_mount(self):
P = self.cls(BASE)
- p = P / 'fileA'
- size = p.stat().st_size
- # Renaming to another path.
- q = P / 'dirA' / 'fileAA'
- renamed_p = p.rename(q)
- self.assertEqual(renamed_p, q)
+ if os.name == 'nt':
+ R = self.cls('c:\\')
+ else:
+ R = self.cls('/')
+ self.assertFalse((P / 'fileA').is_mount())
+ self.assertFalse((P / 'dirA').is_mount())
+ self.assertFalse((P / 'non-existing').is_mount())
+ self.assertFalse((P / 'fileA' / 'bah').is_mount())
+ self.assertTrue(R.is_mount())
+ if os_helper.can_symlink():
+ self.assertFalse((P / 'linkA').is_mount())
+ self.assertIs((R / '\udfff').is_mount(), False)
+
+ def test_is_symlink(self):
+ P = self.cls(BASE)
+ self.assertFalse((P / 'fileA').is_symlink())
+ self.assertFalse((P / 'dirA').is_symlink())
+ self.assertFalse((P / 'non-existing').is_symlink())
+ self.assertFalse((P / 'fileA' / 'bah').is_symlink())
+ if os_helper.can_symlink():
+ self.assertTrue((P / 'linkA').is_symlink())
+ self.assertTrue((P / 'linkB').is_symlink())
+ self.assertTrue((P/ 'brokenLink').is_symlink())
+ self.assertIs((P / 'fileA\udfff').is_file(), False)
+ self.assertIs((P / 'fileA\x00').is_file(), False)
+ if os_helper.can_symlink():
+ self.assertIs((P / 'linkA\udfff').is_file(), False)
+ self.assertIs((P / 'linkA\x00').is_file(), False)
+
+ def test_is_fifo_false(self):
+ P = self.cls(BASE)
+ self.assertFalse((P / 'fileA').is_fifo())
+ self.assertFalse((P / 'dirA').is_fifo())
+ self.assertFalse((P / 'non-existing').is_fifo())
+ self.assertFalse((P / 'fileA' / 'bah').is_fifo())
+ self.assertIs((P / 'fileA\udfff').is_fifo(), False)
+ self.assertIs((P / 'fileA\x00').is_fifo(), False)
+
+ def test_is_socket_false(self):
+ P = self.cls(BASE)
+ self.assertFalse((P / 'fileA').is_socket())
+ self.assertFalse((P / 'dirA').is_socket())
+ self.assertFalse((P / 'non-existing').is_socket())
+ self.assertFalse((P / 'fileA' / 'bah').is_socket())
+ self.assertIs((P / 'fileA\udfff').is_socket(), False)
+ self.assertIs((P / 'fileA\x00').is_socket(), False)
+
+ def test_is_block_device_false(self):
+ P = self.cls(BASE)
+ self.assertFalse((P / 'fileA').is_block_device())
+ self.assertFalse((P / 'dirA').is_block_device())
+ self.assertFalse((P / 'non-existing').is_block_device())
+ self.assertFalse((P / 'fileA' / 'bah').is_block_device())
+ self.assertIs((P / 'fileA\udfff').is_block_device(), False)
+ self.assertIs((P / 'fileA\x00').is_block_device(), False)
+
+ def test_is_char_device_false(self):
+ P = self.cls(BASE)
+ self.assertFalse((P / 'fileA').is_char_device())
+ self.assertFalse((P / 'dirA').is_char_device())
+ self.assertFalse((P / 'non-existing').is_char_device())
+ self.assertFalse((P / 'fileA' / 'bah').is_char_device())
+ self.assertIs((P / 'fileA\udfff').is_char_device(), False)
+ self.assertIs((P / 'fileA\x00').is_char_device(), False)
+
+ def test_pickling_common(self):
+ p = self.cls(BASE, 'fileA')
+ for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
+ dumped = pickle.dumps(p, proto)
+ pp = pickle.loads(dumped)
+ self.assertEqual(pp.stat(), p.stat())
+
+ def test_parts_interning(self):
+ P = self.cls
+ p = P('/usr/bin/foo')
+ q = P('/usr/local/bin')
+ # 'usr'
+ self.assertIs(p.parts[1], q.parts[1])
+ # 'bin'
+ self.assertIs(p.parts[2], q.parts[3])
+
+ def _check_complex_symlinks(self, link0_target):
+ # Test solving a non-looping chain of symlinks (issue #19887).
+ P = self.cls(BASE)
+ self.dirlink(os.path.join('link0', 'link0'), join('link1'))
+ self.dirlink(os.path.join('link1', 'link1'), join('link2'))
+ self.dirlink(os.path.join('link2', 'link2'), join('link3'))
+ self.dirlink(link0_target, join('link0'))
+
+ # Resolve absolute paths.
+ p = (P / 'link0').resolve()
+ self.assertEqual(p, P)
+ self.assertEqualNormCase(str(p), BASE)
+ p = (P / 'link1').resolve()
+ self.assertEqual(p, P)
+ self.assertEqualNormCase(str(p), BASE)
+ p = (P / 'link2').resolve()
+ self.assertEqual(p, P)
+ self.assertEqualNormCase(str(p), BASE)
+ p = (P / 'link3').resolve()
+ self.assertEqual(p, P)
+ self.assertEqualNormCase(str(p), BASE)
+
+ # Resolve relative paths.
+ old_path = os.getcwd()
+ os.chdir(BASE)
+ try:
+ p = self.cls('link0').resolve()
+ self.assertEqual(p, P)
+ self.assertEqualNormCase(str(p), BASE)
+ p = self.cls('link1').resolve()
+ self.assertEqual(p, P)
+ self.assertEqualNormCase(str(p), BASE)
+ p = self.cls('link2').resolve()
+ self.assertEqual(p, P)
+ self.assertEqualNormCase(str(p), BASE)
+ p = self.cls('link3').resolve()
+ self.assertEqual(p, P)
+ self.assertEqualNormCase(str(p), BASE)
+ finally:
+ os.chdir(old_path)
+
+ @os_helper.skip_unless_symlink
+ def test_complex_symlinks_absolute(self):
+ self._check_complex_symlinks(BASE)
+
+ @os_helper.skip_unless_symlink
+ def test_complex_symlinks_relative(self):
+ self._check_complex_symlinks('.')
+
+ @os_helper.skip_unless_symlink
+ def test_complex_symlinks_relative_dot_dot(self):
+ self._check_complex_symlinks(os.path.join('dirA', '..'))
+
+ def test_concrete_class(self):
+ if self.cls is pathlib.Path:
+ expected = pathlib.WindowsPath if os.name == 'nt' else pathlib.PosixPath
+ else:
+ expected = self.cls
+ p = self.cls('a')
+ self.assertIs(type(p), expected)
+
+ def test_unsupported_flavour(self):
+ if self.cls._flavour is os.path:
+ self.skipTest("path flavour is supported")
+ else:
+ self.assertRaises(NotImplementedError, self.cls)
+
+ def _test_cwd(self, p):
+ q = self.cls(os.getcwd())
+ self.assertEqual(p, q)
+ self.assertEqualNormCase(str(p), str(q))
+ self.assertIs(type(p), type(q))
+ self.assertTrue(p.is_absolute())
+
+ def test_cwd(self):
+ p = self.cls.cwd()
+ self._test_cwd(p)
+
+ def test_absolute_common(self):
+ P = self.cls
+
+ with mock.patch("os.getcwd") as getcwd:
+ getcwd.return_value = BASE
+
+ # Simple relative paths.
+ self.assertEqual(str(P().absolute()), BASE)
+ self.assertEqual(str(P('.').absolute()), BASE)
+ self.assertEqual(str(P('a').absolute()), os.path.join(BASE, 'a'))
+ self.assertEqual(str(P('a', 'b', 'c').absolute()), os.path.join(BASE, 'a', 'b', 'c'))
+
+ # Symlinks should not be resolved.
+ self.assertEqual(str(P('linkB', 'fileB').absolute()), os.path.join(BASE, 'linkB', 'fileB'))
+ self.assertEqual(str(P('brokenLink').absolute()), os.path.join(BASE, 'brokenLink'))
+ self.assertEqual(str(P('brokenLinkLoop').absolute()), os.path.join(BASE, 'brokenLinkLoop'))
+
+ # '..' entries should be preserved and not normalised.
+ self.assertEqual(str(P('..').absolute()), os.path.join(BASE, '..'))
+ self.assertEqual(str(P('a', '..').absolute()), os.path.join(BASE, 'a', '..'))
+ self.assertEqual(str(P('..', 'b').absolute()), os.path.join(BASE, '..', 'b'))
+
+ def _test_home(self, p):
+ q = self.cls(os.path.expanduser('~'))
+ self.assertEqual(p, q)
+ self.assertEqualNormCase(str(p), str(q))
+ self.assertIs(type(p), type(q))
+ self.assertTrue(p.is_absolute())
+
+ @unittest.skipIf(
+ pwd is None, reason="Test requires pwd module to get homedir."
+ )
+ def test_home(self):
+ with os_helper.EnvironmentVarGuard() as env:
+ self._test_home(self.cls.home())
+
+ env.clear()
+ env['USERPROFILE'] = os.path.join(BASE, 'userprofile')
+ self._test_home(self.cls.home())
+
+ # bpo-38883: ignore `HOME` when set on windows
+ env['HOME'] = os.path.join(BASE, 'home')
+ self._test_home(self.cls.home())
+
+ @unittest.skipIf(is_wasi, "WASI has no user accounts.")
+ def test_expanduser_common(self):
+ P = self.cls
+ p = P('~')
+ self.assertEqual(p.expanduser(), P(os.path.expanduser('~')))
+ p = P('foo')
+ self.assertEqual(p.expanduser(), p)
+ p = P('/~')
+ self.assertEqual(p.expanduser(), p)
+ p = P('../~')
+ self.assertEqual(p.expanduser(), p)
+ p = P(P('').absolute().anchor) / '~'
+ self.assertEqual(p.expanduser(), p)
+ p = P('~/a:b')
+ self.assertEqual(p.expanduser(), P(os.path.expanduser('~'), './a:b'))
+
+ def test_with_segments(self):
+ class P(self.cls):
+ def __init__(self, *pathsegments, session_id):
+ super().__init__(*pathsegments)
+ self.session_id = session_id
+
+ def with_segments(self, *pathsegments):
+ return type(self)(*pathsegments, session_id=self.session_id)
+ p = P(BASE, session_id=42)
+ self.assertEqual(42, p.absolute().session_id)
+ self.assertEqual(42, p.resolve().session_id)
+ if not is_wasi: # WASI has no user accounts.
+ self.assertEqual(42, p.with_segments('~').expanduser().session_id)
+ self.assertEqual(42, (p / 'fileA').rename(p / 'fileB').session_id)
+ self.assertEqual(42, (p / 'fileB').replace(p / 'fileA').session_id)
+ if os_helper.can_symlink():
+ self.assertEqual(42, (p / 'linkA').readlink().session_id)
+ for path in p.iterdir():
+ self.assertEqual(42, path.session_id)
+ for path in p.glob('*'):
+ self.assertEqual(42, path.session_id)
+ for path in p.rglob('*'):
+ self.assertEqual(42, path.session_id)
+ for dirpath, dirnames, filenames in p.walk():
+ self.assertEqual(42, dirpath.session_id)
+
+ def test_resolve_nonexist_relative_issue38671(self):
+ p = self.cls('non', 'exist')
+
+ old_cwd = os.getcwd()
+ os.chdir(BASE)
+ try:
+ self.assertEqual(p.resolve(), self.cls(BASE, p))
+ finally:
+ os.chdir(old_cwd)
+
+ @os_helper.skip_unless_working_chmod
+ def test_chmod(self):
+ p = self.cls(BASE) / 'fileA'
+ mode = p.stat().st_mode
+ # Clear writable bit.
+ new_mode = mode & ~0o222
+ p.chmod(new_mode)
+ self.assertEqual(p.stat().st_mode, new_mode)
+ # Set writable bit.
+ new_mode = mode | 0o222
+ p.chmod(new_mode)
+ self.assertEqual(p.stat().st_mode, new_mode)
+
+ # On Windows, os.chmod does not follow symlinks (issue #15411)
+ @only_posix
+ @os_helper.skip_unless_working_chmod
+ def test_chmod_follow_symlinks_true(self):
+ p = self.cls(BASE) / 'linkA'
+ q = p.resolve()
+ mode = q.stat().st_mode
+ # Clear writable bit.
+ new_mode = mode & ~0o222
+ p.chmod(new_mode, follow_symlinks=True)
+ self.assertEqual(q.stat().st_mode, new_mode)
+ # Set writable bit
+ new_mode = mode | 0o222
+ p.chmod(new_mode, follow_symlinks=True)
+ self.assertEqual(q.stat().st_mode, new_mode)
+
+ # XXX also need a test for lchmod.
+
+ @unittest.skipUnless(pwd, "the pwd module is needed for this test")
+ def test_owner(self):
+ p = self.cls(BASE) / 'fileA'
+ uid = p.stat().st_uid
+ try:
+ name = pwd.getpwuid(uid).pw_name
+ except KeyError:
+ self.skipTest(
+ "user %d doesn't have an entry in the system database" % uid)
+ self.assertEqual(name, p.owner())
+
+ @unittest.skipUnless(grp, "the grp module is needed for this test")
+ def test_group(self):
+ p = self.cls(BASE) / 'fileA'
+ gid = p.stat().st_gid
+ try:
+ name = grp.getgrgid(gid).gr_name
+ except KeyError:
+ self.skipTest(
+ "group %d doesn't have an entry in the system database" % gid)
+ self.assertEqual(name, p.group())
+
+ def test_unlink(self):
+ p = self.cls(BASE) / 'fileA'
+ p.unlink()
+ self.assertFileNotFound(p.stat)
+ self.assertFileNotFound(p.unlink)
+
+ def test_unlink_missing_ok(self):
+ p = self.cls(BASE) / 'fileAAA'
+ self.assertFileNotFound(p.unlink)
+ p.unlink(missing_ok=True)
+
+ def test_rmdir(self):
+ p = self.cls(BASE) / 'dirA'
+ for q in p.iterdir():
+ q.unlink()
+ p.rmdir()
+ self.assertFileNotFound(p.stat)
+ self.assertFileNotFound(p.unlink)
+
+ @unittest.skipUnless(hasattr(os, "link"), "os.link() is not present")
+ def test_hardlink_to(self):
+ P = self.cls(BASE)
+ target = P / 'fileA'
+ size = target.stat().st_size
+ # linking to another path.
+ link = P / 'dirA' / 'fileAA'
+ link.hardlink_to(target)
+ self.assertEqual(link.stat().st_size, size)
+ self.assertTrue(os.path.samefile(target, link))
+ self.assertTrue(target.exists())
+ # Linking to a str of a relative path.
+ link2 = P / 'dirA' / 'fileAAA'
+ target2 = rel_join('fileA')
+ link2.hardlink_to(target2)
+ self.assertEqual(os.stat(target2).st_size, size)
+ self.assertTrue(link2.exists())
+
+ @unittest.skipIf(hasattr(os, "link"), "os.link() is present")
+ def test_link_to_not_implemented(self):
+ P = self.cls(BASE)
+ p = P / 'fileA'
+ # linking to another path.
+ q = P / 'dirA' / 'fileAA'
+ with self.assertRaises(NotImplementedError):
+ q.hardlink_to(p)
+
+ def test_rename(self):
+ P = self.cls(BASE)
+ p = P / 'fileA'
+ size = p.stat().st_size
+ # Renaming to another path.
+ q = P / 'dirA' / 'fileAA'
+ renamed_p = p.rename(q)
+ self.assertEqual(renamed_p, q)
self.assertEqual(q.stat().st_size, size)
self.assertFileNotFound(p.stat)
# Renaming to a str of a relative path.
@@ -2413,16 +2585,6 @@ def test_replace(self):
self.assertEqual(os.stat(r).st_size, size)
self.assertFileNotFound(q.stat)
- @os_helper.skip_unless_symlink
- def test_readlink(self):
- P = self.cls(BASE)
- self.assertEqual((P / 'linkA').readlink(), self.cls('fileA'))
- self.assertEqual((P / 'brokenLink').readlink(),
- self.cls('non-existing'))
- self.assertEqual((P / 'linkB').readlink(), self.cls('dirB'))
- with self.assertRaises(OSError):
- (P / 'fileA').readlink()
-
def test_touch_common(self):
P = self.cls(BASE)
p = P / 'newfileA'
@@ -2614,63 +2776,6 @@ def test_symlink_to(self):
self.assertTrue(link.is_dir())
self.assertTrue(list(link.iterdir()))
- def test_is_dir(self):
- P = self.cls(BASE)
- self.assertTrue((P / 'dirA').is_dir())
- self.assertFalse((P / 'fileA').is_dir())
- self.assertFalse((P / 'non-existing').is_dir())
- self.assertFalse((P / 'fileA' / 'bah').is_dir())
- if os_helper.can_symlink():
- self.assertFalse((P / 'linkA').is_dir())
- self.assertTrue((P / 'linkB').is_dir())
- self.assertFalse((P/ 'brokenLink').is_dir(), False)
- self.assertIs((P / 'dirA\udfff').is_dir(), False)
- self.assertIs((P / 'dirA\x00').is_dir(), False)
-
- def test_is_file(self):
- P = self.cls(BASE)
- self.assertTrue((P / 'fileA').is_file())
- self.assertFalse((P / 'dirA').is_file())
- self.assertFalse((P / 'non-existing').is_file())
- self.assertFalse((P / 'fileA' / 'bah').is_file())
- if os_helper.can_symlink():
- self.assertTrue((P / 'linkA').is_file())
- self.assertFalse((P / 'linkB').is_file())
- self.assertFalse((P/ 'brokenLink').is_file())
- self.assertIs((P / 'fileA\udfff').is_file(), False)
- self.assertIs((P / 'fileA\x00').is_file(), False)
-
- def test_is_mount(self):
- P = self.cls(BASE)
- if os.name == 'nt':
- R = self.cls('c:\\')
- else:
- R = self.cls('/')
- self.assertFalse((P / 'fileA').is_mount())
- self.assertFalse((P / 'dirA').is_mount())
- self.assertFalse((P / 'non-existing').is_mount())
- self.assertFalse((P / 'fileA' / 'bah').is_mount())
- self.assertTrue(R.is_mount())
- if os_helper.can_symlink():
- self.assertFalse((P / 'linkA').is_mount())
- self.assertIs((R / '\udfff').is_mount(), False)
-
- def test_is_symlink(self):
- P = self.cls(BASE)
- self.assertFalse((P / 'fileA').is_symlink())
- self.assertFalse((P / 'dirA').is_symlink())
- self.assertFalse((P / 'non-existing').is_symlink())
- self.assertFalse((P / 'fileA' / 'bah').is_symlink())
- if os_helper.can_symlink():
- self.assertTrue((P / 'linkA').is_symlink())
- self.assertTrue((P / 'linkB').is_symlink())
- self.assertTrue((P/ 'brokenLink').is_symlink())
- self.assertIs((P / 'fileA\udfff').is_file(), False)
- self.assertIs((P / 'fileA\x00').is_file(), False)
- if os_helper.can_symlink():
- self.assertIs((P / 'linkA\udfff').is_file(), False)
- self.assertIs((P / 'linkA\x00').is_file(), False)
-
def test_is_junction(self):
P = self.cls(BASE)
@@ -2678,15 +2783,6 @@ def test_is_junction(self):
self.assertEqual(P.is_junction(), P._flavour.isjunction.return_value)
P._flavour.isjunction.assert_called_once_with(P)
- def test_is_fifo_false(self):
- P = self.cls(BASE)
- self.assertFalse((P / 'fileA').is_fifo())
- self.assertFalse((P / 'dirA').is_fifo())
- self.assertFalse((P / 'non-existing').is_fifo())
- self.assertFalse((P / 'fileA' / 'bah').is_fifo())
- self.assertIs((P / 'fileA\udfff').is_fifo(), False)
- self.assertIs((P / 'fileA\x00').is_fifo(), False)
-
@unittest.skipUnless(hasattr(os, "mkfifo"), "os.mkfifo() required")
@unittest.skipIf(sys.platform == "vxworks",
"fifo requires special path on VxWorks")
@@ -2702,15 +2798,6 @@ def test_is_fifo_true(self):
self.assertIs(self.cls(BASE, 'myfifo\udfff').is_fifo(), False)
self.assertIs(self.cls(BASE, 'myfifo\x00').is_fifo(), False)
- def test_is_socket_false(self):
- P = self.cls(BASE)
- self.assertFalse((P / 'fileA').is_socket())
- self.assertFalse((P / 'dirA').is_socket())
- self.assertFalse((P / 'non-existing').is_socket())
- self.assertFalse((P / 'fileA' / 'bah').is_socket())
- self.assertIs((P / 'fileA\udfff').is_socket(), False)
- self.assertIs((P / 'fileA\x00').is_socket(), False)
-
@unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required")
@unittest.skipIf(
is_emscripten, "Unix sockets are not implemented on Emscripten."
@@ -2734,24 +2821,6 @@ def test_is_socket_true(self):
self.assertIs(self.cls(BASE, 'mysock\udfff').is_socket(), False)
self.assertIs(self.cls(BASE, 'mysock\x00').is_socket(), False)
- def test_is_block_device_false(self):
- P = self.cls(BASE)
- self.assertFalse((P / 'fileA').is_block_device())
- self.assertFalse((P / 'dirA').is_block_device())
- self.assertFalse((P / 'non-existing').is_block_device())
- self.assertFalse((P / 'fileA' / 'bah').is_block_device())
- self.assertIs((P / 'fileA\udfff').is_block_device(), False)
- self.assertIs((P / 'fileA\x00').is_block_device(), False)
-
- def test_is_char_device_false(self):
- P = self.cls(BASE)
- self.assertFalse((P / 'fileA').is_char_device())
- self.assertFalse((P / 'dirA').is_char_device())
- self.assertFalse((P / 'non-existing').is_char_device())
- self.assertFalse((P / 'fileA' / 'bah').is_char_device())
- self.assertIs((P / 'fileA\udfff').is_char_device(), False)
- self.assertIs((P / 'fileA\x00').is_char_device(), False)
-
def test_is_char_device_true(self):
# Under Unix, /dev/null should generally be a char device.
P = self.cls('/dev/null')
@@ -2763,75 +2832,6 @@ def test_is_char_device_true(self):
self.assertIs(self.cls('/dev/null\udfff').is_char_device(), False)
self.assertIs(self.cls('/dev/null\x00').is_char_device(), False)
- def test_pickling_common(self):
- p = self.cls(BASE, 'fileA')
- for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
- dumped = pickle.dumps(p, proto)
- pp = pickle.loads(dumped)
- self.assertEqual(pp.stat(), p.stat())
-
- def test_parts_interning(self):
- P = self.cls
- p = P('/usr/bin/foo')
- q = P('/usr/local/bin')
- # 'usr'
- self.assertIs(p.parts[1], q.parts[1])
- # 'bin'
- self.assertIs(p.parts[2], q.parts[3])
-
- def _check_complex_symlinks(self, link0_target):
- # Test solving a non-looping chain of symlinks (issue #19887).
- P = self.cls(BASE)
- self.dirlink(os.path.join('link0', 'link0'), join('link1'))
- self.dirlink(os.path.join('link1', 'link1'), join('link2'))
- self.dirlink(os.path.join('link2', 'link2'), join('link3'))
- self.dirlink(link0_target, join('link0'))
-
- # Resolve absolute paths.
- p = (P / 'link0').resolve()
- self.assertEqual(p, P)
- self.assertEqualNormCase(str(p), BASE)
- p = (P / 'link1').resolve()
- self.assertEqual(p, P)
- self.assertEqualNormCase(str(p), BASE)
- p = (P / 'link2').resolve()
- self.assertEqual(p, P)
- self.assertEqualNormCase(str(p), BASE)
- p = (P / 'link3').resolve()
- self.assertEqual(p, P)
- self.assertEqualNormCase(str(p), BASE)
-
- # Resolve relative paths.
- old_path = os.getcwd()
- os.chdir(BASE)
- try:
- p = self.cls('link0').resolve()
- self.assertEqual(p, P)
- self.assertEqualNormCase(str(p), BASE)
- p = self.cls('link1').resolve()
- self.assertEqual(p, P)
- self.assertEqualNormCase(str(p), BASE)
- p = self.cls('link2').resolve()
- self.assertEqual(p, P)
- self.assertEqualNormCase(str(p), BASE)
- p = self.cls('link3').resolve()
- self.assertEqual(p, P)
- self.assertEqualNormCase(str(p), BASE)
- finally:
- os.chdir(old_path)
-
- @os_helper.skip_unless_symlink
- def test_complex_symlinks_absolute(self):
- self._check_complex_symlinks(BASE)
-
- @os_helper.skip_unless_symlink
- def test_complex_symlinks_relative(self):
- self._check_complex_symlinks('.')
-
- @os_helper.skip_unless_symlink
- def test_complex_symlinks_relative_dot_dot(self):
- self._check_complex_symlinks(os.path.join('dirA', '..'))
-
def test_passing_kwargs_deprecated(self):
with self.assertWarns(DeprecationWarning):
self.cls(foo="bar")
More information about the Python-checkins
mailing list