Skip to content
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

GH-130614: Add test suites for readable and writable pathlib paths #130648

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
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
Empty file.
180 changes: 180 additions & 0 deletions Lib/test/test_pathlib/support/local_path.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import os
import pathlib.types
import posixpath

from test.support import os_helper


class LocalPathInfo(pathlib.types.PathInfo):
"""
Simple implementation of PathInfo for a local path
"""
def __init__(self, path):
self._path = str(path)
self._exists = None
self._is_dir = None
self._is_file = None
self._is_symlink = None

def exists(self, *, follow_symlinks=True):
"""Whether this path exists."""
if not follow_symlinks and self.is_symlink():
return True
if self._exists is None:
self._exists = os.path.exists(self._path)
return self._exists

def is_dir(self, *, follow_symlinks=True):
"""Whether this path is a directory."""
if not follow_symlinks and self.is_symlink():
return False
if self._is_dir is None:
self._is_dir = os.path.isdir(self._path)
return self._is_dir

def is_file(self, *, follow_symlinks=True):
"""Whether this path is a regular file."""
if not follow_symlinks and self.is_symlink():
return False
if self._is_file is None:
self._is_file = os.path.isfile(self._path)
return self._is_file

def is_symlink(self):
"""Whether this path is a symbolic link."""
if self._is_symlink is None:
self._is_symlink = os.path.islink(self._path)
return self._is_symlink


class ReadableLocalPath(pathlib.types._ReadablePath):
"""
Simple implementation of a ReadablePath class for local filesystem paths.
"""
parser = os.path

def __init__(self, *pathsegments):
self._segments = pathsegments
self._info = None

def __str__(self):
if not self._segments:
return ''
return self.parser.join(*self._segments)

def __fspath__(self):
return str(self)

def with_segments(self, *pathsegments):
return type(self)(*pathsegments)

def __open_rb__(self, buffering=-1):
return open(self, 'rb')

def iterdir(self):
return (self / name for name in os.listdir(self))

def readlink(self):
return self.with_segments(os.readlink(self))

@property
def info(self):
if self._info is None:
self._info = LocalPathInfo(self)
return self._info


class WritableLocalPath(pathlib.types._WritablePath):
"""
Simple implementation of a WritablePath class for local filesystem paths.
"""

__slots__ = ('_segments',)
parser = posixpath

def __init__(self, *pathsegments):
self._segments = pathsegments

def __str__(self):
if not self._segments:
return ''
return self.parser.join(*self._segments)

def __fspath__(self):
return str(self)

def with_segments(self, *pathsegments):
return type(self)(*pathsegments)

def __open_wb__(self, buffering=-1):
return open(self, 'wb')

def mkdir(self, mode=0o777):
os.mkdir(self, mode)

def symlink_to(self, target, target_is_directory=False):
os.symlink(target, self, target_is_directory)


class LocalPathGround:
can_symlink = os_helper.can_symlink()

def __init__(self, path_cls):
self.path_cls = path_cls

def setup(self, local_suffix=""):
root = self.path_cls(os_helper.TESTFN + local_suffix)
os.mkdir(root)
return root

def teardown(self, root):
os_helper.rmtree(root)

def create_file(self, p, data=b''):
with open(p, 'wb') as f:
f.write(data)

def create_hierarchy(self, p):
os.mkdir(os.path.join(p, 'dirA'))
os.mkdir(os.path.join(p, 'dirB'))
os.mkdir(os.path.join(p, 'dirC'))
os.mkdir(os.path.join(p, 'dirC', 'dirD'))
with open(os.path.join(p, 'fileA'), 'wb') as f:
f.write(b"this is file A\n")
with open(os.path.join(p, 'dirB', 'fileB'), 'wb') as f:
f.write(b"this is file B\n")
with open(os.path.join(p, 'dirC', 'fileC'), 'wb') as f:
f.write(b"this is file C\n")
with open(os.path.join(p, 'dirC', 'novel.txt'), 'wb') as f:
f.write(b"this is a novel\n")
with open(os.path.join(p, 'dirC', 'dirD', 'fileD'), 'wb') as f:
f.write(b"this is file D\n")
if self.can_symlink:
# Relative symlinks.
os.symlink('fileA', os.path.join(p, 'linkA'))
os.symlink('non-existing', os.path.join(p, 'brokenLink'))
os.symlink('dirB',
os.path.join(p, 'linkB'),
target_is_directory=True)
os.symlink(os.path.join('..', 'dirB'),
os.path.join(p, 'dirA', 'linkC'),
target_is_directory=True)
# This one goes upwards, creating a loop.
os.symlink(os.path.join('..', 'dirB'),
os.path.join(p, 'dirB', 'linkD'),
target_is_directory=True)
# Broken symlink (pointing to itself).
os.symlink('brokenLinkLoop', os.path.join(p, 'brokenLinkLoop'))

isdir = staticmethod(os.path.isdir)
isfile = staticmethod(os.path.isfile)
islink = staticmethod(os.path.islink)
readlink = staticmethod(os.readlink)

def readtext(self, p):
with open(p, 'r') as f:
return f.read()

def readbytes(self, p):
with open(p, 'rb') as f:
return f.read()
Loading
Loading