Skip to content

GH-110109: Simplify pathlib test setup #110308

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Oct 10, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 42 additions & 76 deletions Lib/test/test_pathlib.py
Original file line number Diff line number Diff line change
@@ -1731,17 +1731,21 @@ def iterdir(self):
raise FileNotFoundError(errno.ENOENT, "File not found", path)

def mkdir(self, mode=0o777, parents=False, exist_ok=False):
path = str(self.resolve())
if path in self._directories:
if exist_ok:
return
else:
raise FileExistsError(errno.EEXIST, "File exists", path)
try:
self._directories[str(self.parent)].add(self.name)
self._directories[str(self)] = set()
if self.name:
self._directories[str(self.parent)].add(self.name)
self._directories[path] = set()
except KeyError:
if not parents or self.parent == self:
if not parents:
raise FileNotFoundError(errno.ENOENT, "File not found", str(self.parent)) from None
self.parent.mkdir(parents=True, exist_ok=True)
self.mkdir(mode, parents=False, exist_ok=exist_ok)
except FileExistsError:
if not exist_ok:
raise


class DummyPathTest(unittest.TestCase):
@@ -1771,33 +1775,37 @@ class DummyPathTest(unittest.TestCase):
#

def setUp(self):
# note: this must be kept in sync with `PathTest.setUp()`
pathmod = self.cls.pathmod
p = self.cls(BASE)
p.mkdir(parents=True)
p.joinpath('dirA').mkdir()
p.joinpath('dirB').mkdir()
p.joinpath('dirC').mkdir()
p.joinpath('dirC', 'dirD').mkdir()
p.joinpath('dirE').mkdir()
with p.joinpath('fileA').open('wb') as f:
f.write(b"this is file A\n")
with p.joinpath('dirB', 'fileB').open('wb') as f:
f.write(b"this is file B\n")
with p.joinpath('dirC', 'fileC').open('wb') as f:
f.write(b"this is file C\n")
with p.joinpath('dirC', 'novel.txt').open('wb') as f:
f.write(b"this is a novel\n")
with p.joinpath('dirC', 'dirD', 'fileD').open('wb') as f:
f.write(b"this is file D\n")
if self.can_symlink:
p.joinpath('linkA').symlink_to('fileA')
p.joinpath('brokenLink').symlink_to('non-existing')
p.joinpath('linkB').symlink_to('dirB')
p.joinpath('dirA', 'linkC').symlink_to(pathmod.join('..', 'dirB'))
p.joinpath('dirB', 'linkD').symlink_to(pathmod.join('..', 'dirB'))
p.joinpath('brokenLinkLoop').symlink_to('brokenLinkLoop')

def tearDown(self):
cls = self.cls
cls._files.clear()
cls._directories.clear()
cls._symlinks.clear()
join = cls.pathmod.join
cls._files.update({
join(BASE, 'fileA'): b'this is file A\n',
join(BASE, 'dirB', 'fileB'): b'this is file B\n',
join(BASE, 'dirC', 'fileC'): b'this is file C\n',
join(BASE, 'dirC', 'dirD', 'fileD'): b'this is file D\n',
join(BASE, 'dirC', 'novel.txt'): b'this is a novel\n',
})
cls._directories.update({
BASE: {'dirA', 'dirB', 'dirC', 'dirE', 'fileA'},
join(BASE, 'dirA'): set(),
join(BASE, 'dirB'): {'fileB'},
join(BASE, 'dirC'): {'dirD', 'fileC', 'novel.txt'},
join(BASE, 'dirC', 'dirD'): {'fileD'},
join(BASE, 'dirE'): {},
})
dirname = BASE
while True:
dirname, basename = cls.pathmod.split(dirname)
if not basename:
break
cls._directories[dirname] = {basename}

def tempdir(self):
path = self.cls(BASE).with_name('tmp-dirD')
@@ -2626,22 +2634,6 @@ class DummyPathWithSymlinksTest(DummyPathTest):
cls = DummyPathWithSymlinks
can_symlink = True

def setUp(self):
super().setUp()
cls = self.cls
join = cls.pathmod.join
cls._symlinks.update({
join(BASE, 'linkA'): 'fileA',
join(BASE, 'linkB'): 'dirB',
join(BASE, 'dirA', 'linkC'): join('..', 'dirB'),
join(BASE, 'dirB', 'linkD'): join('..', 'dirB'),
join(BASE, 'brokenLink'): 'non-existing',
join(BASE, 'brokenLinkLoop'): 'brokenLinkLoop',
})
cls._directories[BASE].update({'linkA', 'linkB', 'brokenLink', 'brokenLinkLoop'})
cls._directories[join(BASE, 'dirA')].add('linkC')
cls._directories[join(BASE, 'dirB')].add('linkD')


#
# Tests for the concrete classes.
@@ -2653,38 +2645,12 @@ class PathTest(DummyPathTest):
can_symlink = os_helper.can_symlink()

def setUp(self):
# note: this must be kept in sync with `DummyPathTest.setUp()`
def cleanup():
os.chmod(join('dirE'), 0o777)
os_helper.rmtree(BASE)
self.addCleanup(cleanup)
os.mkdir(BASE)
os.mkdir(join('dirA'))
os.mkdir(join('dirB'))
os.mkdir(join('dirC'))
os.mkdir(join('dirC', 'dirD'))
os.mkdir(join('dirE'))
with open(join('fileA'), 'wb') as f:
f.write(b"this is file A\n")
with open(join('dirB', 'fileB'), 'wb') as f:
f.write(b"this is file B\n")
with open(join('dirC', 'fileC'), 'wb') as f:
f.write(b"this is file C\n")
with open(join('dirC', 'novel.txt'), 'wb') as f:
f.write(b"this is a novel\n")
with open(join('dirC', 'dirD', 'fileD'), 'wb') as f:
f.write(b"this is file D\n")
super().setUp()
os.chmod(join('dirE'), 0)
if self.can_symlink:
# Relative symlinks.
os.symlink('fileA', join('linkA'))
os.symlink('non-existing', join('brokenLink'))
os.symlink('dirB', join('linkB'), target_is_directory=True)
os.symlink(os.path.join('..', 'dirB'), join('dirA', 'linkC'), target_is_directory=True)
# This one goes upwards, creating a loop.
os.symlink(os.path.join('..', 'dirB'), join('dirB', 'linkD'), target_is_directory=True)
# Broken symlink (pointing to itself).
os.symlink('brokenLinkLoop', join('brokenLinkLoop'))

def tearDown(self):
os.chmod(join('dirE'), 0o777)
os_helper.rmtree(BASE)

def tempdir(self):
d = os_helper._longpath(tempfile.mkdtemp(suffix='-dirD',