GH-110109: pathlib tests: store base directory as test class attribute (#113221)

Store the test base directory as a class attribute named `base` rather than
module constants named `BASE`.

The base directory is a local file path, and therefore not ideally suited
to the pathlib ABC tests. In a future commit we'll change its value in
`test_pathlib_abc.py` such that it points to a totally fictitious path, which 
will help to ensure we're not touching the local filesystem.
This commit is contained in:
Barney Gale 2023-12-17 00:07:32 +00:00 committed by GitHub
parent d91e43ed78
commit 2f0ec7fa94
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 210 additions and 222 deletions

View file

@ -23,11 +23,6 @@
grp = pwd = None
# Make sure any symbolic links in the base test path are resolved.
BASE = os.path.realpath(TESTFN)
join = lambda *x: os.path.join(BASE, *x)
rel_join = lambda *x: os.path.join(TESTFN, *x)
only_nt = unittest.skipIf(os.name != 'nt',
'test requires a Windows-compatible system')
only_posix = unittest.skipIf(os.name == 'nt',
@ -937,11 +932,11 @@ class PathTest(test_pathlib_abc.DummyPathTest, PurePathTest):
def setUp(self):
super().setUp()
os.chmod(join('dirE'), 0)
os.chmod(self.pathmod.join(self.base, 'dirE'), 0)
def tearDown(self):
os.chmod(join('dirE'), 0o777)
os_helper.rmtree(BASE)
os.chmod(self.pathmod.join(self.base, 'dirE'), 0o777)
os_helper.rmtree(self.base)
def tempdir(self):
d = os_helper._longpath(tempfile.mkdtemp(suffix='-dirD',
@ -978,23 +973,23 @@ def test_absolute_common(self):
P = self.cls
with mock.patch("os.getcwd") as getcwd:
getcwd.return_value = BASE
getcwd.return_value = self.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'))
self.assertEqual(str(P().absolute()), self.base)
self.assertEqual(str(P('.').absolute()), self.base)
self.assertEqual(str(P('a').absolute()), os.path.join(self.base, 'a'))
self.assertEqual(str(P('a', 'b', 'c').absolute()), os.path.join(self.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'))
self.assertEqual(str(P('linkB', 'fileB').absolute()), os.path.join(self.base, 'linkB', 'fileB'))
self.assertEqual(str(P('brokenLink').absolute()), os.path.join(self.base, 'brokenLink'))
self.assertEqual(str(P('brokenLinkLoop').absolute()), os.path.join(self.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'))
self.assertEqual(str(P('..').absolute()), os.path.join(self.base, '..'))
self.assertEqual(str(P('a', '..').absolute()), os.path.join(self.base, 'a', '..'))
self.assertEqual(str(P('..', 'b').absolute()), os.path.join(self.base, '..', 'b'))
def _test_home(self, p):
q = self.cls(os.path.expanduser('~'))
@ -1011,11 +1006,11 @@ def test_home(self):
self._test_home(self.cls.home())
env.clear()
env['USERPROFILE'] = os.path.join(BASE, 'userprofile')
env['USERPROFILE'] = os.path.join(self.base, 'userprofile')
self._test_home(self.cls.home())
# bpo-38883: ignore `HOME` when set on windows
env['HOME'] = os.path.join(BASE, 'home')
env['HOME'] = os.path.join(self.base, 'home')
self._test_home(self.cls.home())
@unittest.skipIf(is_wasi, "WASI has no user accounts.")
@ -1042,7 +1037,7 @@ def __init__(self, *pathsegments, session_id):
def with_segments(self, *pathsegments):
return type(self)(*pathsegments, session_id=self.session_id)
p = P(BASE, session_id=42)
p = P(self.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.
@ -1061,7 +1056,7 @@ def with_segments(self, *pathsegments):
self.assertEqual(42, dirpath.session_id)
def test_open_unbuffered(self):
p = self.cls(BASE)
p = self.cls(self.base)
with (p / 'fileA').open('rb', buffering=0) as f:
self.assertIsInstance(f, io.RawIOBase)
self.assertEqual(f.read().strip(), b"this is file A")
@ -1070,15 +1065,15 @@ def test_resolve_nonexist_relative_issue38671(self):
p = self.cls('non', 'exist')
old_cwd = os.getcwd()
os.chdir(BASE)
os.chdir(self.base)
try:
self.assertEqual(p.resolve(), self.cls(BASE, p))
self.assertEqual(p.resolve(), self.cls(self.base, p))
finally:
os.chdir(old_cwd)
@os_helper.skip_unless_working_chmod
def test_chmod(self):
p = self.cls(BASE) / 'fileA'
p = self.cls(self.base) / 'fileA'
mode = p.stat().st_mode
# Clear writable bit.
new_mode = mode & ~0o222
@ -1093,7 +1088,7 @@ def test_chmod(self):
@only_posix
@os_helper.skip_unless_working_chmod
def test_chmod_follow_symlinks_true(self):
p = self.cls(BASE) / 'linkA'
p = self.cls(self.base) / 'linkA'
q = p.resolve()
mode = q.stat().st_mode
# Clear writable bit.
@ -1116,7 +1111,7 @@ def _get_pw_name_or_skip_test(self, uid):
@unittest.skipUnless(pwd, "the pwd module is needed for this test")
def test_owner(self):
p = self.cls(BASE) / 'fileA'
p = self.cls(self.base) / 'fileA'
expected_uid = p.stat().st_uid
expected_name = self._get_pw_name_or_skip_test(expected_uid)
@ -1129,8 +1124,8 @@ def test_owner_no_follow_symlinks(self):
if len(all_users) < 2:
self.skipTest("test needs more than one user")
target = self.cls(BASE) / 'fileA'
link = self.cls(BASE) / 'linkA'
target = self.cls(self.base) / 'fileA'
link = self.cls(self.base) / 'linkA'
uid_1, uid_2 = all_users[:2]
os.chown(target, uid_1, -1)
@ -1151,7 +1146,7 @@ def _get_gr_name_or_skip_test(self, gid):
@unittest.skipUnless(grp, "the grp module is needed for this test")
def test_group(self):
p = self.cls(BASE) / 'fileA'
p = self.cls(self.base) / 'fileA'
expected_gid = p.stat().st_gid
expected_name = self._get_gr_name_or_skip_test(expected_gid)
@ -1164,8 +1159,8 @@ def test_group_no_follow_symlinks(self):
if len(all_groups) < 2:
self.skipTest("test needs more than one group")
target = self.cls(BASE) / 'fileA'
link = self.cls(BASE) / 'linkA'
target = self.cls(self.base) / 'fileA'
link = self.cls(self.base) / 'linkA'
gid_1, gid_2 = all_groups[:2]
os.chown(target, -1, gid_1)
@ -1178,18 +1173,18 @@ def test_group_no_follow_symlinks(self):
self.assertEqual(expected_name, link.group(follow_symlinks=False))
def test_unlink(self):
p = self.cls(BASE) / 'fileA'
p = self.cls(self.base) / 'fileA'
p.unlink()
self.assertFileNotFound(p.stat)
self.assertFileNotFound(p.unlink)
def test_unlink_missing_ok(self):
p = self.cls(BASE) / 'fileAAA'
p = self.cls(self.base) / 'fileAAA'
self.assertFileNotFound(p.unlink)
p.unlink(missing_ok=True)
def test_rmdir(self):
p = self.cls(BASE) / 'dirA'
p = self.cls(self.base) / 'dirA'
for q in p.iterdir():
q.unlink()
p.rmdir()
@ -1198,7 +1193,7 @@ def test_rmdir(self):
@unittest.skipUnless(hasattr(os, "link"), "os.link() is not present")
def test_hardlink_to(self):
P = self.cls(BASE)
P = self.cls(self.base)
target = P / 'fileA'
size = target.stat().st_size
# linking to another path.
@ -1209,14 +1204,14 @@ def test_hardlink_to(self):
self.assertTrue(target.exists())
# Linking to a str of a relative path.
link2 = P / 'dirA' / 'fileAAA'
target2 = rel_join('fileA')
target2 = self.pathmod.join(TESTFN, '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_hardlink_to_unsupported(self):
P = self.cls(BASE)
P = self.cls(self.base)
p = P / 'fileA'
# linking to another path.
q = P / 'dirA' / 'fileAA'
@ -1224,7 +1219,7 @@ def test_hardlink_to_unsupported(self):
q.hardlink_to(p)
def test_rename(self):
P = self.cls(BASE)
P = self.cls(self.base)
p = P / 'fileA'
size = p.stat().st_size
# Renaming to another path.
@ -1234,14 +1229,14 @@ def test_rename(self):
self.assertEqual(q.stat().st_size, size)
self.assertFileNotFound(p.stat)
# Renaming to a str of a relative path.
r = rel_join('fileAAA')
r = self.pathmod.join(TESTFN, 'fileAAA')
renamed_q = q.rename(r)
self.assertEqual(renamed_q, self.cls(r))
self.assertEqual(os.stat(r).st_size, size)
self.assertFileNotFound(q.stat)
def test_replace(self):
P = self.cls(BASE)
P = self.cls(self.base)
p = P / 'fileA'
size = p.stat().st_size
# Replacing a non-existing path.
@ -1251,14 +1246,14 @@ def test_replace(self):
self.assertEqual(q.stat().st_size, size)
self.assertFileNotFound(p.stat)
# Replacing another (existing) path.
r = rel_join('dirB', 'fileB')
r = self.pathmod.join(TESTFN, 'dirB', 'fileB')
replaced_q = q.replace(r)
self.assertEqual(replaced_q, self.cls(r))
self.assertEqual(os.stat(r).st_size, size)
self.assertFileNotFound(q.stat)
def test_touch_common(self):
P = self.cls(BASE)
P = self.cls(self.base)
p = P / 'newfileA'
self.assertFalse(p.exists())
p.touch()
@ -1282,14 +1277,14 @@ def test_touch_common(self):
self.assertRaises(OSError, p.touch, exist_ok=False)
def test_touch_nochange(self):
P = self.cls(BASE)
P = self.cls(self.base)
p = P / 'fileA'
p.touch()
with p.open('rb') as f:
self.assertEqual(f.read().strip(), b"this is file A")
def test_mkdir(self):
P = self.cls(BASE)
P = self.cls(self.base)
p = P / 'newdirA'
self.assertFalse(p.exists())
p.mkdir()
@ -1301,7 +1296,7 @@ def test_mkdir(self):
def test_mkdir_parents(self):
# Creating a chain of directories.
p = self.cls(BASE, 'newdirB', 'newdirC')
p = self.cls(self.base, 'newdirB', 'newdirC')
self.assertFalse(p.exists())
with self.assertRaises(OSError) as cm:
p.mkdir()
@ -1314,7 +1309,7 @@ def test_mkdir_parents(self):
self.assertEqual(cm.exception.errno, errno.EEXIST)
# Test `mode` arg.
mode = stat.S_IMODE(p.stat().st_mode) # Default mode.
p = self.cls(BASE, 'newdirD', 'newdirE')
p = self.cls(self.base, 'newdirD', 'newdirE')
p.mkdir(0o555, parents=True)
self.assertTrue(p.exists())
self.assertTrue(p.is_dir())
@ -1325,7 +1320,7 @@ def test_mkdir_parents(self):
self.assertEqual(stat.S_IMODE(p.parent.stat().st_mode), mode)
def test_mkdir_exist_ok(self):
p = self.cls(BASE, 'dirB')
p = self.cls(self.base, 'dirB')
st_ctime_first = p.stat().st_ctime
self.assertTrue(p.exists())
self.assertTrue(p.is_dir())
@ -1337,7 +1332,7 @@ def test_mkdir_exist_ok(self):
self.assertEqual(p.stat().st_ctime, st_ctime_first)
def test_mkdir_exist_ok_with_parent(self):
p = self.cls(BASE, 'dirC')
p = self.cls(self.base, 'dirC')
self.assertTrue(p.exists())
with self.assertRaises(FileExistsError) as cm:
p.mkdir()
@ -1371,7 +1366,7 @@ def test_mkdir_with_unknown_drive(self):
(p / 'child' / 'path').mkdir(parents=True)
def test_mkdir_with_child_file(self):
p = self.cls(BASE, 'dirB', 'fileB')
p = self.cls(self.base, 'dirB', 'fileB')
self.assertTrue(p.exists())
# An exception is raised when the last path component is an existing
# regular file, regardless of whether exist_ok is true or not.
@ -1383,7 +1378,7 @@ def test_mkdir_with_child_file(self):
self.assertEqual(cm.exception.errno, errno.EEXIST)
def test_mkdir_no_parents_file(self):
p = self.cls(BASE, 'fileA')
p = self.cls(self.base, 'fileA')
self.assertTrue(p.exists())
# An exception is raised when the last path component is an existing
# regular file, regardless of whether exist_ok is true or not.
@ -1396,7 +1391,7 @@ def test_mkdir_no_parents_file(self):
def test_mkdir_concurrent_parent_creation(self):
for pattern_num in range(32):
p = self.cls(BASE, 'dirCPC%d' % pattern_num)
p = self.cls(self.base, 'dirCPC%d' % pattern_num)
self.assertFalse(p.exists())
real_mkdir = os.mkdir
@ -1427,7 +1422,7 @@ def my_mkdir(path, mode=0o777):
def test_symlink_to(self):
if not self.can_symlink:
self.skipTest("symlinks required")
P = self.cls(BASE)
P = self.cls(self.base)
target = P / 'fileA'
# Symlinking a path target.
link = P / 'dirA' / 'linkAA'
@ -1451,7 +1446,7 @@ def test_symlink_to(self):
@unittest.skipIf(hasattr(os, "symlink"), "os.symlink() is present")
def test_symlink_to_unsupported(self):
P = self.cls(BASE)
P = self.cls(self.base)
p = P / 'fileA'
# linking to another path.
q = P / 'dirA' / 'fileAA'
@ -1459,7 +1454,7 @@ def test_symlink_to_unsupported(self):
q.symlink_to(p)
def test_is_junction(self):
P = self.cls(BASE)
P = self.cls(self.base)
with mock.patch.object(P.pathmod, 'isjunction'):
self.assertEqual(P.is_junction(), P.pathmod.isjunction.return_value)
@ -1469,7 +1464,7 @@ def test_is_junction(self):
@unittest.skipIf(sys.platform == "vxworks",
"fifo requires special path on VxWorks")
def test_is_fifo_true(self):
P = self.cls(BASE, 'myfifo')
P = self.cls(self.base, 'myfifo')
try:
os.mkfifo(str(P))
except PermissionError as e:
@ -1477,8 +1472,8 @@ def test_is_fifo_true(self):
self.assertTrue(P.is_fifo())
self.assertFalse(P.is_socket())
self.assertFalse(P.is_file())
self.assertIs(self.cls(BASE, 'myfifo\udfff').is_fifo(), False)
self.assertIs(self.cls(BASE, 'myfifo\x00').is_fifo(), False)
self.assertIs(self.cls(self.base, 'myfifo\udfff').is_fifo(), False)
self.assertIs(self.cls(self.base, 'myfifo\x00').is_fifo(), False)
@unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required")
@unittest.skipIf(
@ -1488,7 +1483,7 @@ def test_is_fifo_true(self):
is_wasi, "Cannot create socket on WASI."
)
def test_is_socket_true(self):
P = self.cls(BASE, 'mysock')
P = self.cls(self.base, 'mysock')
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self.addCleanup(sock.close)
try:
@ -1500,8 +1495,8 @@ def test_is_socket_true(self):
self.assertTrue(P.is_socket())
self.assertFalse(P.is_fifo())
self.assertFalse(P.is_file())
self.assertIs(self.cls(BASE, 'mysock\udfff').is_socket(), False)
self.assertIs(self.cls(BASE, 'mysock\x00').is_socket(), False)
self.assertIs(self.cls(self.base, 'mysock\udfff').is_socket(), False)
self.assertIs(self.cls(self.base, 'mysock\x00').is_socket(), False)
def test_is_char_device_true(self):
# Under Unix, /dev/null should generally be a char device.
@ -1573,7 +1568,7 @@ def test_walk_bad_dir(self):
def test_walk_many_open_files(self):
depth = 30
base = self.cls(BASE, 'deep')
base = self.cls(self.base, 'deep')
path = self.cls(base, *(['d']*depth))
path.mkdir(parents=True)
@ -1615,15 +1610,15 @@ def test_absolute(self):
def test_open_mode(self):
old_mask = os.umask(0)
self.addCleanup(os.umask, old_mask)
p = self.cls(BASE)
p = self.cls(self.base)
with (p / 'new_file').open('wb'):
pass
st = os.stat(join('new_file'))
st = os.stat(self.pathmod.join(self.base, 'new_file'))
self.assertEqual(stat.S_IMODE(st.st_mode), 0o666)
os.umask(0o022)
with (p / 'other_new_file').open('wb'):
pass
st = os.stat(join('other_new_file'))
st = os.stat(self.pathmod.join(self.base, 'other_new_file'))
self.assertEqual(stat.S_IMODE(st.st_mode), 0o644)
def test_resolve_root(self):
@ -1642,31 +1637,31 @@ def test_resolve_root(self):
def test_touch_mode(self):
old_mask = os.umask(0)
self.addCleanup(os.umask, old_mask)
p = self.cls(BASE)
p = self.cls(self.base)
(p / 'new_file').touch()
st = os.stat(join('new_file'))
st = os.stat(self.pathmod.join(self.base, 'new_file'))
self.assertEqual(stat.S_IMODE(st.st_mode), 0o666)
os.umask(0o022)
(p / 'other_new_file').touch()
st = os.stat(join('other_new_file'))
st = os.stat(self.pathmod.join(self.base, 'other_new_file'))
self.assertEqual(stat.S_IMODE(st.st_mode), 0o644)
(p / 'masked_new_file').touch(mode=0o750)
st = os.stat(join('masked_new_file'))
st = os.stat(self.pathmod.join(self.base, 'masked_new_file'))
self.assertEqual(stat.S_IMODE(st.st_mode), 0o750)
def test_glob(self):
P = self.cls
p = P(BASE)
p = P(self.base)
given = set(p.glob("FILEa"))
expect = set() if not os_helper.fs_is_case_insensitive(BASE) else given
expect = set() if not os_helper.fs_is_case_insensitive(self.base) else given
self.assertEqual(given, expect)
self.assertEqual(set(p.glob("FILEa*")), set())
def test_rglob(self):
P = self.cls
p = P(BASE, "dirC")
p = P(self.base, "dirC")
given = set(p.rglob("FILEd"))
expect = set() if not os_helper.fs_is_case_insensitive(BASE) else given
expect = set() if not os_helper.fs_is_case_insensitive(self.base) else given
self.assertEqual(given, expect)
self.assertEqual(set(p.rglob("FILEd*")), set())
@ -1797,17 +1792,17 @@ def test_absolute(self):
self.assertEqual(str(P('a', 'b', 'c').absolute()),
os.path.join(share, 'a', 'b', 'c'))
drive = os.path.splitdrive(BASE)[0]
with os_helper.change_cwd(BASE):
drive = os.path.splitdrive(self.base)[0]
with os_helper.change_cwd(self.base):
# Relative path with root
self.assertEqual(str(P('\\').absolute()), drive + '\\')
self.assertEqual(str(P('\\foo').absolute()), drive + '\\foo')
# Relative path on current drive
self.assertEqual(str(P(drive).absolute()), BASE)
self.assertEqual(str(P(drive + 'foo').absolute()), os.path.join(BASE, 'foo'))
self.assertEqual(str(P(drive).absolute()), self.base)
self.assertEqual(str(P(drive + 'foo').absolute()), os.path.join(self.base, 'foo'))
with os_helper.subst_drive(BASE) as other_drive:
with os_helper.subst_drive(self.base) as other_drive:
# Set the working directory on the substitute drive
saved_cwd = os.getcwd()
other_cwd = f'{other_drive}\\dirA'
@ -1820,18 +1815,18 @@ def test_absolute(self):
def test_glob(self):
P = self.cls
p = P(BASE)
self.assertEqual(set(p.glob("FILEa")), { P(BASE, "fileA") })
self.assertEqual(set(p.glob("*a\\")), { P(BASE, "dirA/") })
self.assertEqual(set(p.glob("F*a")), { P(BASE, "fileA") })
p = P(self.base)
self.assertEqual(set(p.glob("FILEa")), { P(self.base, "fileA") })
self.assertEqual(set(p.glob("*a\\")), { P(self.base, "dirA/") })
self.assertEqual(set(p.glob("F*a")), { P(self.base, "fileA") })
self.assertEqual(set(map(str, p.glob("FILEa"))), {f"{p}\\fileA"})
self.assertEqual(set(map(str, p.glob("F*a"))), {f"{p}\\fileA"})
def test_rglob(self):
P = self.cls
p = P(BASE, "dirC")
self.assertEqual(set(p.rglob("FILEd")), { P(BASE, "dirC/dirD/fileD") })
self.assertEqual(set(p.rglob("*\\")), { P(BASE, "dirC/dirD/") })
p = P(self.base, "dirC")
self.assertEqual(set(p.rglob("FILEd")), { P(self.base, "dirC/dirD/fileD") })
self.assertEqual(set(p.rglob("*\\")), { P(self.base, "dirC/dirD/") })
self.assertEqual(set(map(str, p.rglob("FILEd"))), {f"{p}\\dirD\\fileD"})
def test_expanduser(self):

View file

@ -18,16 +18,6 @@ def test_is_notimplemented(self):
self.assertTrue(isinstance(pathlib.UnsupportedOperation(), NotImplementedError))
# Make sure any symbolic links in the base test path are resolved.
BASE = os.path.realpath(TESTFN)
join = lambda *x: os.path.join(BASE, *x)
only_nt = unittest.skipIf(os.name != 'nt',
'test requires a Windows-compatible system')
only_posix = unittest.skipIf(os.name == 'nt',
'test requires a POSIX-compatible system')
#
# Tests for the pure classes.
#
@ -62,6 +52,9 @@ def __hash__(self):
class DummyPurePathTest(unittest.TestCase):
cls = DummyPurePath
# Make sure any symbolic links in the base test path are resolved.
base = os.path.realpath(TESTFN)
# Keys are canonical paths, values are list of tuples of arguments
# supposed to produce equal paths.
equivalences = {
@ -859,7 +852,7 @@ class DummyPathTest(DummyPurePathTest):
cls = DummyPath
can_symlink = False
# (BASE)
# (self.base)
# |
# |-- brokenLink -> non-existing
# |-- dirA
@ -882,7 +875,7 @@ class DummyPathTest(DummyPurePathTest):
def setUp(self):
super().setUp()
pathmod = self.cls.pathmod
p = self.cls(BASE)
p = self.cls(self.base)
p.mkdir(parents=True)
p.joinpath('dirA').mkdir()
p.joinpath('dirB').mkdir()
@ -914,7 +907,7 @@ def tearDown(self):
cls._symlinks.clear()
def tempdir(self):
path = self.cls(BASE).with_name('tmp-dirD')
path = self.cls(self.base).with_name('tmp-dirD')
path.mkdir()
return path
@ -927,8 +920,8 @@ def assertEqualNormCase(self, path_a, path_b):
self.assertEqual(os.path.normcase(path_a), os.path.normcase(path_b))
def test_samefile(self):
fileA_path = os.path.join(BASE, 'fileA')
fileB_path = os.path.join(BASE, 'dirB', 'fileB')
fileA_path = os.path.join(self.base, 'fileA')
fileB_path = os.path.join(self.base, 'dirB', 'fileB')
p = self.cls(fileA_path)
pp = self.cls(fileA_path)
q = self.cls(fileB_path)
@ -937,7 +930,7 @@ def test_samefile(self):
self.assertFalse(p.samefile(fileB_path))
self.assertFalse(p.samefile(q))
# Test the non-existent file case
non_existent = os.path.join(BASE, 'foo')
non_existent = os.path.join(self.base, 'foo')
r = self.cls(non_existent)
self.assertRaises(FileNotFoundError, p.samefile, r)
self.assertRaises(FileNotFoundError, p.samefile, non_existent)
@ -953,7 +946,7 @@ def test_empty_path(self):
def test_exists(self):
P = self.cls
p = P(BASE)
p = P(self.base)
self.assertIs(True, p.exists())
self.assertIs(True, (p / 'dirA').exists())
self.assertIs(True, (p / 'fileA').exists())
@ -967,11 +960,11 @@ def test_exists(self):
self.assertIs(True, (p / 'brokenLink').exists(follow_symlinks=False))
self.assertIs(False, (p / 'foo').exists())
self.assertIs(False, P('/xyzzy').exists())
self.assertIs(False, P(BASE + '\udfff').exists())
self.assertIs(False, P(BASE + '\x00').exists())
self.assertIs(False, P(self.base + '\udfff').exists())
self.assertIs(False, P(self.base + '\x00').exists())
def test_open_common(self):
p = self.cls(BASE)
p = self.cls(self.base)
with (p / 'fileA').open('r') as f:
self.assertIsInstance(f, io.TextIOBase)
self.assertEqual(f.read(), "this is file A\n")
@ -980,7 +973,7 @@ def test_open_common(self):
self.assertEqual(f.read().strip(), b"this is file A")
def test_read_write_bytes(self):
p = self.cls(BASE)
p = self.cls(self.base)
(p / 'fileA').write_bytes(b'abcdefg')
self.assertEqual((p / 'fileA').read_bytes(), b'abcdefg')
# Check that trying to write str does not truncate the file.
@ -988,7 +981,7 @@ def test_read_write_bytes(self):
self.assertEqual((p / 'fileA').read_bytes(), b'abcdefg')
def test_read_write_text(self):
p = self.cls(BASE)
p = self.cls(self.base)
(p / 'fileA').write_text('äbcdefg', encoding='latin-1')
self.assertEqual((p / 'fileA').read_text(
encoding='utf-8', errors='ignore'), 'bcdefg')
@ -997,7 +990,7 @@ def test_read_write_text(self):
self.assertEqual((p / 'fileA').read_text(encoding='latin-1'), 'äbcdefg')
def test_read_text_with_newlines(self):
p = self.cls(BASE)
p = self.cls(self.base)
# Check that `\n` character change nothing
(p / 'fileA').write_bytes(b'abcde\r\nfghlk\n\rmnopq')
self.assertEqual((p / 'fileA').read_text(newline='\n'),
@ -1012,7 +1005,7 @@ def test_read_text_with_newlines(self):
'abcde\r\nfghlk\n\rmnopq')
def test_write_text_with_newlines(self):
p = self.cls(BASE)
p = self.cls(self.base)
# Check that `\n` character change nothing
(p / 'fileA').write_text('abcde\r\nfghlk\n\rmnopq', newline='\n')
self.assertEqual((p / 'fileA').read_bytes(),
@ -1033,27 +1026,27 @@ def test_write_text_with_newlines(self):
def test_iterdir(self):
P = self.cls
p = P(BASE)
p = P(self.base)
it = p.iterdir()
paths = set(it)
expected = ['dirA', 'dirB', 'dirC', 'dirE', 'fileA']
if self.can_symlink:
expected += ['linkA', 'linkB', 'brokenLink', 'brokenLinkLoop']
self.assertEqual(paths, { P(BASE, q) for q in expected })
self.assertEqual(paths, { P(self.base, q) for q in expected })
def test_iterdir_symlink(self):
if not self.can_symlink:
self.skipTest("symlinks required")
# __iter__ on a symlink to a directory.
P = self.cls
p = P(BASE, 'linkB')
p = P(self.base, 'linkB')
paths = set(p.iterdir())
expected = { P(BASE, 'linkB', q) for q in ['fileB', 'linkD'] }
expected = { P(self.base, 'linkB', q) for q in ['fileB', 'linkD'] }
self.assertEqual(paths, expected)
def test_iterdir_nodir(self):
# __iter__ on something that is not a directory.
p = self.cls(BASE, 'fileA')
p = self.cls(self.base, 'fileA')
with self.assertRaises(OSError) as cm:
p.iterdir()
# ENOENT or EINVAL under Windows, ENOTDIR otherwise
@ -1063,9 +1056,9 @@ def test_iterdir_nodir(self):
def test_glob_common(self):
def _check(glob, expected):
self.assertEqual(set(glob), { P(BASE, q) for q in expected })
self.assertEqual(set(glob), { P(self.base, q) for q in expected })
P = self.cls
p = P(BASE)
p = P(self.base)
it = p.glob("fileA")
self.assertIsInstance(it, collections.abc.Iterator)
_check(it, ["fileA"])
@ -1101,9 +1094,9 @@ def test_glob_case_sensitive(self):
P = self.cls
def _check(path, pattern, case_sensitive, expected):
actual = {str(q) for q in path.glob(pattern, case_sensitive=case_sensitive)}
expected = {str(P(BASE, q)) for q in expected}
expected = {str(P(self.base, q)) for q in expected}
self.assertEqual(actual, expected)
path = P(BASE)
path = P(self.base)
_check(path, "DIRB/FILE*", True, [])
_check(path, "DIRB/FILE*", False, ["dirB/fileB"])
_check(path, "dirb/file*", True, [])
@ -1115,9 +1108,9 @@ def test_glob_follow_symlinks_common(self):
def _check(path, glob, expected):
actual = {path for path in path.glob(glob, follow_symlinks=True)
if "linkD" not in path.parent.parts} # exclude symlink loop.
self.assertEqual(actual, { P(BASE, q) for q in expected })
self.assertEqual(actual, { P(self.base, q) for q in expected })
P = self.cls
p = P(BASE)
p = P(self.base)
_check(p, "fileB", [])
_check(p, "dir*/file*", ["dirB/fileB", "dirC/fileC"])
_check(p, "*A", ["dirA", "fileA", "linkA"])
@ -1140,9 +1133,9 @@ def test_glob_no_follow_symlinks_common(self):
self.skipTest("symlinks required")
def _check(path, glob, expected):
actual = {path for path in path.glob(glob, follow_symlinks=False)}
self.assertEqual(actual, { P(BASE, q) for q in expected })
self.assertEqual(actual, { P(self.base, q) for q in expected })
P = self.cls
p = P(BASE)
p = P(self.base)
_check(p, "fileB", [])
_check(p, "dir*/file*", ["dirB/fileB", "dirC/fileC"])
_check(p, "*A", ["dirA", "fileA", "linkA"])
@ -1160,9 +1153,9 @@ def _check(path, glob, expected):
def test_rglob_common(self):
def _check(glob, expected):
self.assertEqual(set(glob), {P(BASE, q) for q in expected})
self.assertEqual(set(glob), {P(self.base, q) for q in expected})
P = self.cls
p = P(BASE)
p = P(self.base)
it = p.rglob("fileA")
self.assertIsInstance(it, collections.abc.Iterator)
_check(it, ["fileA"])
@ -1187,7 +1180,7 @@ def _check(glob, expected):
])
_check(p.rglob(""), ["./", "dirA/", "dirB/", "dirC/", "dirE/", "dirC/dirD/"])
p = P(BASE, "dirC")
p = P(self.base, "dirC")
_check(p.rglob("*"), ["dirC/fileC", "dirC/novel.txt",
"dirC/dirD", "dirC/dirD/fileD"])
_check(p.rglob("file*"), ["dirC/fileC", "dirC/dirD/fileD"])
@ -1207,9 +1200,9 @@ def test_rglob_follow_symlinks_common(self):
def _check(path, glob, expected):
actual = {path for path in path.rglob(glob, follow_symlinks=True)
if 'linkD' not in path.parent.parts} # exclude symlink loop.
self.assertEqual(actual, { P(BASE, q) for q in expected })
self.assertEqual(actual, { P(self.base, q) for q in expected })
P = self.cls
p = P(BASE)
p = P(self.base)
_check(p, "fileB", ["dirB/fileB", "dirA/linkC/fileB", "linkB/fileB"])
_check(p, "*/fileA", [])
_check(p, "*/fileB", ["dirB/fileB", "dirA/linkC/fileB", "linkB/fileB"])
@ -1220,7 +1213,7 @@ def _check(path, glob, expected):
_check(p, "", ["./", "dirA/", "dirA/linkC/", "dirA/linkC/linkD/", "dirB/", "dirB/linkD/",
"dirC/", "dirE/", "dirC/dirD/", "linkB/", "linkB/linkD/"])
p = P(BASE, "dirC")
p = P(self.base, "dirC")
_check(p, "*", ["dirC/fileC", "dirC/novel.txt",
"dirC/dirD", "dirC/dirD/fileD"])
_check(p, "file*", ["dirC/fileC", "dirC/dirD/fileD"])
@ -1236,9 +1229,9 @@ def test_rglob_no_follow_symlinks_common(self):
self.skipTest("symlinks required")
def _check(path, glob, expected):
actual = {path for path in path.rglob(glob, follow_symlinks=False)}
self.assertEqual(actual, { P(BASE, q) for q in expected })
self.assertEqual(actual, { P(self.base, q) for q in expected })
P = self.cls
p = P(BASE)
p = P(self.base)
_check(p, "fileB", ["dirB/fileB"])
_check(p, "*/fileA", [])
_check(p, "*/fileB", ["dirB/fileB"])
@ -1246,7 +1239,7 @@ def _check(path, glob, expected):
_check(p, "*/", ["dirA/", "dirB/", "dirC/", "dirC/dirD/", "dirE/"])
_check(p, "", ["./", "dirA/", "dirB/", "dirC/", "dirE/", "dirC/dirD/"])
p = P(BASE, "dirC")
p = P(self.base, "dirC")
_check(p, "*", ["dirC/fileC", "dirC/novel.txt",
"dirC/dirD", "dirC/dirD/fileD"])
_check(p, "file*", ["dirC/fileC", "dirC/dirD/fileD"])
@ -1262,7 +1255,7 @@ def test_rglob_symlink_loop(self):
if not self.can_symlink:
self.skipTest("symlinks required")
P = self.cls
p = P(BASE)
p = P(self.base)
given = set(p.rglob('*'))
expect = {'brokenLink',
'dirA', 'dirA/linkC',
@ -1280,7 +1273,7 @@ def test_rglob_symlink_loop(self):
def test_glob_many_open_files(self):
depth = 30
P = self.cls
p = base = P(BASE) / 'deep'
p = base = P(self.base) / 'deep'
p.mkdir()
for _ in range(depth):
p /= 'd'
@ -1299,30 +1292,30 @@ def test_glob_many_open_files(self):
def test_glob_dotdot(self):
# ".." is not special in globs.
P = self.cls
p = P(BASE)
self.assertEqual(set(p.glob("..")), { P(BASE, "..") })
self.assertEqual(set(p.glob("../..")), { P(BASE, "..", "..") })
self.assertEqual(set(p.glob("dirA/..")), { P(BASE, "dirA", "..") })
self.assertEqual(set(p.glob("dirA/../file*")), { P(BASE, "dirA/../fileA") })
p = P(self.base)
self.assertEqual(set(p.glob("..")), { P(self.base, "..") })
self.assertEqual(set(p.glob("../..")), { P(self.base, "..", "..") })
self.assertEqual(set(p.glob("dirA/..")), { P(self.base, "dirA", "..") })
self.assertEqual(set(p.glob("dirA/../file*")), { P(self.base, "dirA/../fileA") })
self.assertEqual(set(p.glob("dirA/../file*/..")), set())
self.assertEqual(set(p.glob("../xyzzy")), set())
self.assertEqual(set(p.glob("xyzzy/..")), set())
self.assertEqual(set(p.glob("/".join([".."] * 50))), { P(BASE, *[".."] * 50)})
self.assertEqual(set(p.glob("/".join([".."] * 50))), { P(self.base, *[".."] * 50)})
def test_glob_permissions(self):
# See bpo-38894
if not self.can_symlink:
self.skipTest("symlinks required")
P = self.cls
base = P(BASE) / 'permissions'
base = P(self.base) / 'permissions'
base.mkdir()
for i in range(100):
link = base / f"link{i}"
if i % 2:
link.symlink_to(P(BASE, "dirE", "nonexistent"))
link.symlink_to(P(self.base, "dirE", "nonexistent"))
else:
link.symlink_to(P(BASE, "dirC"))
link.symlink_to(P(self.base, "dirC"))
self.assertEqual(len(set(base.glob("*"))), 100)
self.assertEqual(len(set(base.glob("*/"))), 50)
@ -1333,7 +1326,7 @@ def test_glob_long_symlink(self):
# See gh-87695
if not self.can_symlink:
self.skipTest("symlinks required")
base = self.cls(BASE) / 'long_symlink'
base = self.cls(self.base) / 'long_symlink'
base.mkdir()
bad_link = base / 'bad_link'
bad_link.symlink_to("bad" * 200)
@ -1343,7 +1336,7 @@ def test_glob_above_recursion_limit(self):
recursion_limit = 50
# directory_depth > recursion_limit
directory_depth = recursion_limit + 10
base = self.cls(BASE, 'deep')
base = self.cls(self.base, 'deep')
path = base.joinpath(*(['d'] * directory_depth))
path.mkdir(parents=True)
@ -1352,7 +1345,7 @@ def test_glob_above_recursion_limit(self):
def test_glob_recursive_no_trailing_slash(self):
P = self.cls
p = P(BASE)
p = P(self.base)
with self.assertWarns(FutureWarning):
p.glob('**')
with self.assertWarns(FutureWarning):
@ -1366,7 +1359,7 @@ def test_glob_recursive_no_trailing_slash(self):
def test_readlink(self):
if not self.can_symlink:
self.skipTest("symlinks required")
P = self.cls(BASE)
P = self.cls(self.base)
self.assertEqual((P / 'linkA').readlink(), self.cls('fileA'))
self.assertEqual((P / 'brokenLink').readlink(),
self.cls('non-existing'))
@ -1377,7 +1370,7 @@ def test_readlink(self):
@unittest.skipIf(hasattr(os, "readlink"), "os.readlink() is present")
def test_readlink_unsupported(self):
P = self.cls(BASE)
P = self.cls(self.base)
p = P / 'fileA'
with self.assertRaises(pathlib.UnsupportedOperation):
q.readlink(p)
@ -1393,53 +1386,53 @@ def test_resolve_common(self):
if not self.can_symlink:
self.skipTest("symlinks required")
P = self.cls
p = P(BASE, 'foo')
p = P(self.base, 'foo')
with self.assertRaises(OSError) as cm:
p.resolve(strict=True)
self.assertEqual(cm.exception.errno, errno.ENOENT)
# Non-strict
self.assertEqualNormCase(str(p.resolve(strict=False)),
os.path.join(BASE, 'foo'))
p = P(BASE, 'foo', 'in', 'spam')
os.path.join(self.base, 'foo'))
p = P(self.base, 'foo', 'in', 'spam')
self.assertEqualNormCase(str(p.resolve(strict=False)),
os.path.join(BASE, 'foo', 'in', 'spam'))
p = P(BASE, '..', 'foo', 'in', 'spam')
os.path.join(self.base, 'foo', 'in', 'spam'))
p = P(self.base, '..', 'foo', 'in', 'spam')
self.assertEqualNormCase(str(p.resolve(strict=False)),
os.path.abspath(os.path.join('foo', 'in', 'spam')))
# These are all relative symlinks.
p = P(BASE, 'dirB', 'fileB')
p = P(self.base, 'dirB', 'fileB')
self._check_resolve_relative(p, p)
p = P(BASE, 'linkA')
self._check_resolve_relative(p, P(BASE, 'fileA'))
p = P(BASE, 'dirA', 'linkC', 'fileB')
self._check_resolve_relative(p, P(BASE, 'dirB', 'fileB'))
p = P(BASE, 'dirB', 'linkD', 'fileB')
self._check_resolve_relative(p, P(BASE, 'dirB', 'fileB'))
p = P(self.base, 'linkA')
self._check_resolve_relative(p, P(self.base, 'fileA'))
p = P(self.base, 'dirA', 'linkC', 'fileB')
self._check_resolve_relative(p, P(self.base, 'dirB', 'fileB'))
p = P(self.base, 'dirB', 'linkD', 'fileB')
self._check_resolve_relative(p, P(self.base, 'dirB', 'fileB'))
# Non-strict
p = P(BASE, 'dirA', 'linkC', 'fileB', 'foo', 'in', 'spam')
self._check_resolve_relative(p, P(BASE, 'dirB', 'fileB', 'foo', 'in',
p = P(self.base, 'dirA', 'linkC', 'fileB', 'foo', 'in', 'spam')
self._check_resolve_relative(p, P(self.base, 'dirB', 'fileB', 'foo', 'in',
'spam'), False)
p = P(BASE, 'dirA', 'linkC', '..', 'foo', 'in', 'spam')
p = P(self.base, 'dirA', 'linkC', '..', 'foo', 'in', 'spam')
if os.name == 'nt' and isinstance(p, pathlib.Path):
# In Windows, if linkY points to dirB, 'dirA\linkY\..'
# resolves to 'dirA' without resolving linkY first.
self._check_resolve_relative(p, P(BASE, 'dirA', 'foo', 'in',
self._check_resolve_relative(p, P(self.base, 'dirA', 'foo', 'in',
'spam'), False)
else:
# In Posix, if linkY points to dirB, 'dirA/linkY/..'
# resolves to 'dirB/..' first before resolving to parent of dirB.
self._check_resolve_relative(p, P(BASE, 'foo', 'in', 'spam'), False)
self._check_resolve_relative(p, P(self.base, 'foo', 'in', 'spam'), False)
# Now create absolute symlinks.
d = self.tempdir()
P(BASE, 'dirA', 'linkX').symlink_to(d)
P(BASE, str(d), 'linkY').symlink_to(join('dirB'))
p = P(BASE, 'dirA', 'linkX', 'linkY', 'fileB')
self._check_resolve_absolute(p, P(BASE, 'dirB', 'fileB'))
P(self.base, 'dirA', 'linkX').symlink_to(d)
P(self.base, str(d), 'linkY').symlink_to(self.pathmod.join(self.base, 'dirB'))
p = P(self.base, 'dirA', 'linkX', 'linkY', 'fileB')
self._check_resolve_absolute(p, P(self.base, 'dirB', 'fileB'))
# Non-strict
p = P(BASE, 'dirA', 'linkX', 'linkY', 'foo', 'in', 'spam')
self._check_resolve_relative(p, P(BASE, 'dirB', 'foo', 'in', 'spam'),
p = P(self.base, 'dirA', 'linkX', 'linkY', 'foo', 'in', 'spam')
self._check_resolve_relative(p, P(self.base, 'dirB', 'foo', 'in', 'spam'),
False)
p = P(BASE, 'dirA', 'linkX', 'linkY', '..', 'foo', 'in', 'spam')
p = P(self.base, 'dirA', 'linkX', 'linkY', '..', 'foo', 'in', 'spam')
if os.name == 'nt' and isinstance(p, pathlib.Path):
# In Windows, if linkY points to dirB, 'dirA\linkY\..'
# resolves to 'dirA' without resolving linkY first.
@ -1447,13 +1440,13 @@ def test_resolve_common(self):
else:
# In Posix, if linkY points to dirB, 'dirA/linkY/..'
# resolves to 'dirB/..' first before resolving to parent of dirB.
self._check_resolve_relative(p, P(BASE, 'foo', 'in', 'spam'), False)
self._check_resolve_relative(p, P(self.base, 'foo', 'in', 'spam'), False)
def test_resolve_dot(self):
# See http://web.archive.org/web/20200623062557/https://bitbucket.org/pitrou/pathlib/issues/9/
if not self.can_symlink:
self.skipTest("symlinks required")
p = self.cls(BASE)
p = self.cls(self.base)
p.joinpath('0').symlink_to('.', target_is_directory=True)
p.joinpath('1').symlink_to(os.path.join('0', '0'), target_is_directory=True)
p.joinpath('2').symlink_to(os.path.join('1', '1'), target_is_directory=True)
@ -1476,30 +1469,30 @@ def test_resolve_loop(self):
if os.name == 'nt' and issubclass(self.cls, pathlib.Path):
self.skipTest("symlink loops work differently with concrete Windows paths")
# Loops with relative symlinks.
self.cls(BASE, 'linkX').symlink_to('linkX/inside')
self._check_symlink_loop(BASE, 'linkX')
self.cls(BASE, 'linkY').symlink_to('linkY')
self._check_symlink_loop(BASE, 'linkY')
self.cls(BASE, 'linkZ').symlink_to('linkZ/../linkZ')
self._check_symlink_loop(BASE, 'linkZ')
self.cls(self.base, 'linkX').symlink_to('linkX/inside')
self._check_symlink_loop(self.base, 'linkX')
self.cls(self.base, 'linkY').symlink_to('linkY')
self._check_symlink_loop(self.base, 'linkY')
self.cls(self.base, 'linkZ').symlink_to('linkZ/../linkZ')
self._check_symlink_loop(self.base, 'linkZ')
# Non-strict
p = self.cls(BASE, 'linkZ', 'foo')
p = self.cls(self.base, 'linkZ', 'foo')
self.assertEqual(p.resolve(strict=False), p)
# Loops with absolute symlinks.
self.cls(BASE, 'linkU').symlink_to(join('linkU/inside'))
self._check_symlink_loop(BASE, 'linkU')
self.cls(BASE, 'linkV').symlink_to(join('linkV'))
self._check_symlink_loop(BASE, 'linkV')
self.cls(BASE, 'linkW').symlink_to(join('linkW/../linkW'))
self._check_symlink_loop(BASE, 'linkW')
self.cls(self.base, 'linkU').symlink_to(self.pathmod.join(self.base, 'linkU/inside'))
self._check_symlink_loop(self.base, 'linkU')
self.cls(self.base, 'linkV').symlink_to(self.pathmod.join(self.base, 'linkV'))
self._check_symlink_loop(self.base, 'linkV')
self.cls(self.base, 'linkW').symlink_to(self.pathmod.join(self.base, 'linkW/../linkW'))
self._check_symlink_loop(self.base, 'linkW')
# Non-strict
q = self.cls(BASE, 'linkW', 'foo')
q = self.cls(self.base, 'linkW', 'foo')
self.assertEqual(q.resolve(strict=False), q)
def test_stat(self):
statA = self.cls(BASE).joinpath('fileA').stat()
statB = self.cls(BASE).joinpath('dirB', 'fileB').stat()
statC = self.cls(BASE).joinpath('dirC').stat()
statA = self.cls(self.base).joinpath('fileA').stat()
statB = self.cls(self.base).joinpath('dirB', 'fileB').stat()
statC = self.cls(self.base).joinpath('dirC').stat()
# st_mode: files are the same, directory differs.
self.assertIsInstance(statA.st_mode, int)
self.assertEqual(statA.st_mode, statB.st_mode)
@ -1519,29 +1512,29 @@ def test_stat(self):
def test_stat_no_follow_symlinks(self):
if not self.can_symlink:
self.skipTest("symlinks required")
p = self.cls(BASE) / 'linkA'
p = self.cls(self.base) / 'linkA'
st = p.stat()
self.assertNotEqual(st, p.stat(follow_symlinks=False))
def test_stat_no_follow_symlinks_nosymlink(self):
p = self.cls(BASE) / 'fileA'
p = self.cls(self.base) / 'fileA'
st = p.stat()
self.assertEqual(st, p.stat(follow_symlinks=False))
def test_lstat(self):
if not self.can_symlink:
self.skipTest("symlinks required")
p = self.cls(BASE)/ 'linkA'
p = self.cls(self.base)/ 'linkA'
st = p.stat()
self.assertNotEqual(st, p.lstat())
def test_lstat_nosymlink(self):
p = self.cls(BASE) / 'fileA'
p = self.cls(self.base) / 'fileA'
st = p.stat()
self.assertEqual(st, p.lstat())
def test_is_dir(self):
P = self.cls(BASE)
P = self.cls(self.base)
self.assertTrue((P / 'dirA').is_dir())
self.assertFalse((P / 'fileA').is_dir())
self.assertFalse((P / 'non-existing').is_dir())
@ -1554,7 +1547,7 @@ def test_is_dir(self):
self.assertFalse((P / 'dirA\x00').is_dir())
def test_is_dir_no_follow_symlinks(self):
P = self.cls(BASE)
P = self.cls(self.base)
self.assertTrue((P / 'dirA').is_dir(follow_symlinks=False))
self.assertFalse((P / 'fileA').is_dir(follow_symlinks=False))
self.assertFalse((P / 'non-existing').is_dir(follow_symlinks=False))
@ -1567,7 +1560,7 @@ def test_is_dir_no_follow_symlinks(self):
self.assertFalse((P / 'dirA\x00').is_dir(follow_symlinks=False))
def test_is_file(self):
P = self.cls(BASE)
P = self.cls(self.base)
self.assertTrue((P / 'fileA').is_file())
self.assertFalse((P / 'dirA').is_file())
self.assertFalse((P / 'non-existing').is_file())
@ -1580,7 +1573,7 @@ def test_is_file(self):
self.assertFalse((P / 'fileA\x00').is_file())
def test_is_file_no_follow_symlinks(self):
P = self.cls(BASE)
P = self.cls(self.base)
self.assertTrue((P / 'fileA').is_file(follow_symlinks=False))
self.assertFalse((P / 'dirA').is_file(follow_symlinks=False))
self.assertFalse((P / 'non-existing').is_file(follow_symlinks=False))
@ -1593,7 +1586,7 @@ def test_is_file_no_follow_symlinks(self):
self.assertFalse((P / 'fileA\x00').is_file(follow_symlinks=False))
def test_is_mount(self):
P = self.cls(BASE)
P = self.cls(self.base)
self.assertFalse((P / 'fileA').is_mount())
self.assertFalse((P / 'dirA').is_mount())
self.assertFalse((P / 'non-existing').is_mount())
@ -1602,7 +1595,7 @@ def test_is_mount(self):
self.assertFalse((P / 'linkA').is_mount())
def test_is_symlink(self):
P = self.cls(BASE)
P = self.cls(self.base)
self.assertFalse((P / 'fileA').is_symlink())
self.assertFalse((P / 'dirA').is_symlink())
self.assertFalse((P / 'non-existing').is_symlink())
@ -1618,7 +1611,7 @@ def test_is_symlink(self):
self.assertIs((P / 'linkA\x00').is_file(), False)
def test_is_junction_false(self):
P = self.cls(BASE)
P = self.cls(self.base)
self.assertFalse((P / 'fileA').is_junction())
self.assertFalse((P / 'dirA').is_junction())
self.assertFalse((P / 'non-existing').is_junction())
@ -1627,7 +1620,7 @@ def test_is_junction_false(self):
self.assertFalse((P / 'fileA\x00').is_junction())
def test_is_fifo_false(self):
P = self.cls(BASE)
P = self.cls(self.base)
self.assertFalse((P / 'fileA').is_fifo())
self.assertFalse((P / 'dirA').is_fifo())
self.assertFalse((P / 'non-existing').is_fifo())
@ -1636,7 +1629,7 @@ def test_is_fifo_false(self):
self.assertIs((P / 'fileA\x00').is_fifo(), False)
def test_is_socket_false(self):
P = self.cls(BASE)
P = self.cls(self.base)
self.assertFalse((P / 'fileA').is_socket())
self.assertFalse((P / 'dirA').is_socket())
self.assertFalse((P / 'non-existing').is_socket())
@ -1645,7 +1638,7 @@ def test_is_socket_false(self):
self.assertIs((P / 'fileA\x00').is_socket(), False)
def test_is_block_device_false(self):
P = self.cls(BASE)
P = self.cls(self.base)
self.assertFalse((P / 'fileA').is_block_device())
self.assertFalse((P / 'dirA').is_block_device())
self.assertFalse((P / 'non-existing').is_block_device())
@ -1654,7 +1647,7 @@ def test_is_block_device_false(self):
self.assertIs((P / 'fileA\x00').is_block_device(), False)
def test_is_char_device_false(self):
P = self.cls(BASE)
P = self.cls(self.base)
self.assertFalse((P / 'fileA').is_char_device())
self.assertFalse((P / 'dirA').is_char_device())
self.assertFalse((P / 'non-existing').is_char_device())
@ -1663,7 +1656,7 @@ def test_is_char_device_false(self):
self.assertIs((P / 'fileA\x00').is_char_device(), False)
def test_pickling_common(self):
p = self.cls(BASE, 'fileA')
p = self.cls(self.base, 'fileA')
for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
dumped = pickle.dumps(p, proto)
pp = pickle.loads(dumped)
@ -1683,7 +1676,7 @@ def _check_complex_symlinks(self, link0_target):
self.skipTest("symlinks required")
# Test solving a non-looping chain of symlinks (issue #19887).
P = self.cls(BASE)
P = self.cls(self.base)
P.joinpath('link1').symlink_to(os.path.join('link0', 'link0'), target_is_directory=True)
P.joinpath('link2').symlink_to(os.path.join('link1', 'link1'), target_is_directory=True)
P.joinpath('link3').symlink_to(os.path.join('link2', 'link2'), target_is_directory=True)
@ -1692,16 +1685,16 @@ def _check_complex_symlinks(self, link0_target):
# Resolve absolute paths.
p = (P / 'link0').resolve()
self.assertEqual(p, P)
self.assertEqualNormCase(str(p), BASE)
self.assertEqualNormCase(str(p), self.base)
p = (P / 'link1').resolve()
self.assertEqual(p, P)
self.assertEqualNormCase(str(p), BASE)
self.assertEqualNormCase(str(p), self.base)
p = (P / 'link2').resolve()
self.assertEqual(p, P)
self.assertEqualNormCase(str(p), BASE)
self.assertEqualNormCase(str(p), self.base)
p = (P / 'link3').resolve()
self.assertEqual(p, P)
self.assertEqualNormCase(str(p), BASE)
self.assertEqualNormCase(str(p), self.base)
# Resolve relative paths.
try:
@ -1709,25 +1702,25 @@ def _check_complex_symlinks(self, link0_target):
except pathlib.UnsupportedOperation:
return
old_path = os.getcwd()
os.chdir(BASE)
os.chdir(self.base)
try:
p = self.cls('link0').resolve()
self.assertEqual(p, P)
self.assertEqualNormCase(str(p), BASE)
self.assertEqualNormCase(str(p), self.base)
p = self.cls('link1').resolve()
self.assertEqual(p, P)
self.assertEqualNormCase(str(p), BASE)
self.assertEqualNormCase(str(p), self.base)
p = self.cls('link2').resolve()
self.assertEqual(p, P)
self.assertEqualNormCase(str(p), BASE)
self.assertEqualNormCase(str(p), self.base)
p = self.cls('link3').resolve()
self.assertEqual(p, P)
self.assertEqualNormCase(str(p), BASE)
self.assertEqualNormCase(str(p), self.base)
finally:
os.chdir(old_path)
def test_complex_symlinks_absolute(self):
self._check_complex_symlinks(BASE)
self._check_complex_symlinks(self.base)
def test_complex_symlinks_relative(self):
self._check_complex_symlinks('.')
@ -1750,7 +1743,7 @@ def setUpWalk(self):
# broken_link2
# TEST2/
# tmp4 a lone file
self.walk_path = self.cls(BASE, "TEST1")
self.walk_path = self.cls(self.base, "TEST1")
self.sub1_path = self.walk_path / "SUB1"
self.sub11_path = self.sub1_path / "SUB11"
self.sub2_path = self.walk_path / "SUB2"
@ -1758,8 +1751,8 @@ def setUpWalk(self):
tmp2_path = self.sub1_path / "tmp2"
tmp3_path = self.sub2_path / "tmp3"
self.link_path = self.sub2_path / "link"
t2_path = self.cls(BASE, "TEST2")
tmp4_path = self.cls(BASE, "TEST2", "tmp4")
t2_path = self.cls(self.base, "TEST2")
tmp4_path = self.cls(self.base, "TEST2", "tmp4")
broken_link_path = self.sub2_path / "broken_link"
broken_link2_path = self.sub2_path / "broken_link2"
@ -1886,7 +1879,7 @@ def test_walk_above_recursion_limit(self):
recursion_limit = 40
# directory_depth > recursion_limit
directory_depth = recursion_limit + 10
base = self.cls(BASE, 'deep')
base = self.cls(self.base, 'deep')
path = base.joinpath(*(['d'] * directory_depth))
path.mkdir(parents=True)