summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorBrett Cannon <brett@python.org>2016-08-26 21:44:48 (GMT)
committerBrett Cannon <brett@python.org>2016-08-26 21:44:48 (GMT)
commit3f9183b5aca568867f37c38501fca63911580c66 (patch)
tree77dbe8fa7c0381c665ed259a94620a860a8f73d7 /Lib
parent6ed442c48dd7f8d3097e688a36bc027df3271621 (diff)
downloadcpython-3f9183b5aca568867f37c38501fca63911580c66.zip
cpython-3f9183b5aca568867f37c38501fca63911580c66.tar.gz
cpython-3f9183b5aca568867f37c38501fca63911580c66.tar.bz2
Issue #26027, #27524: Add PEP 519/__fspath__() support to os and
os.path. Thanks to Jelle Zijlstra for the initial patch against posixmodule.c.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/genericpath.py6
-rw-r--r--Lib/ntpath.py18
-rw-r--r--Lib/os.py4
-rw-r--r--Lib/posixpath.py19
-rw-r--r--Lib/test/test_genericpath.py64
-rw-r--r--Lib/test/test_ntpath.py83
-rw-r--r--Lib/test/test_os.py83
-rw-r--r--Lib/test/test_posix.py10
-rw-r--r--Lib/test/test_posixpath.py80
9 files changed, 345 insertions, 22 deletions
diff --git a/Lib/genericpath.py b/Lib/genericpath.py
index 6714061..303b3b3 100644
--- a/Lib/genericpath.py
+++ b/Lib/genericpath.py
@@ -69,6 +69,12 @@ def getctime(filename):
def commonprefix(m):
"Given a list of pathnames, returns the longest common leading component"
if not m: return ''
+ # Some people pass in a list of pathname parts to operate in an OS-agnostic
+ # fashion; don't try to translate in that case as that's an abuse of the
+ # API and they are already doing what they need to be OS-agnostic and so
+ # they most likely won't be using an os.PathLike object in the sublists.
+ if not isinstance(m[0], (list, tuple)):
+ m = tuple(map(os.fspath, m))
s1 = min(m)
s2 = max(m)
for i, c in enumerate(s1):
diff --git a/Lib/ntpath.py b/Lib/ntpath.py
index af6a709..1fa4448 100644
--- a/Lib/ntpath.py
+++ b/Lib/ntpath.py
@@ -46,6 +46,7 @@ def normcase(s):
"""Normalize case of pathname.
Makes all characters lowercase and all slashes into backslashes."""
+ s = os.fspath(s)
try:
if isinstance(s, bytes):
return s.replace(b'/', b'\\').lower()
@@ -66,12 +67,14 @@ def normcase(s):
def isabs(s):
"""Test whether a path is absolute"""
+ s = os.fspath(s)
s = splitdrive(s)[1]
return len(s) > 0 and s[0] in _get_bothseps(s)
# Join two (or more) paths.
def join(path, *paths):
+ path = os.fspath(path)
if isinstance(path, bytes):
sep = b'\\'
seps = b'\\/'
@@ -84,7 +87,7 @@ def join(path, *paths):
if not paths:
path[:0] + sep #23780: Ensure compatible data type even if p is null.
result_drive, result_path = splitdrive(path)
- for p in paths:
+ for p in map(os.fspath, paths):
p_drive, p_path = splitdrive(p)
if p_path and p_path[0] in seps:
# Second path is absolute
@@ -136,6 +139,7 @@ def splitdrive(p):
Paths cannot contain both a drive letter and a UNC path.
"""
+ p = os.fspath(p)
if len(p) >= 2:
if isinstance(p, bytes):
sep = b'\\'
@@ -199,7 +203,7 @@ def split(p):
Return tuple (head, tail) where tail is everything after the final slash.
Either part may be empty."""
-
+ p = os.fspath(p)
seps = _get_bothseps(p)
d, p = splitdrive(p)
# set i to index beyond p's last slash
@@ -218,6 +222,7 @@ def split(p):
# It is always true that root + ext == p.
def splitext(p):
+ p = os.fspath(p)
if isinstance(p, bytes):
return genericpath._splitext(p, b'\\', b'/', b'.')
else:
@@ -278,6 +283,7 @@ except ImportError:
def ismount(path):
"""Test whether a path is a mount point (a drive root, the root of a
share, or a mounted volume)"""
+ path = os.fspath(path)
seps = _get_bothseps(path)
path = abspath(path)
root, rest = splitdrive(path)
@@ -305,6 +311,7 @@ def expanduser(path):
"""Expand ~ and ~user constructs.
If user or $HOME is unknown, do nothing."""
+ path = os.fspath(path)
if isinstance(path, bytes):
tilde = b'~'
else:
@@ -354,6 +361,7 @@ def expandvars(path):
"""Expand shell variables of the forms $var, ${var} and %var%.
Unknown variables are left unchanged."""
+ path = os.fspath(path)
if isinstance(path, bytes):
if b'$' not in path and b'%' not in path:
return path
@@ -464,6 +472,7 @@ def expandvars(path):
def normpath(path):
"""Normalize path, eliminating double slashes, etc."""
+ path = os.fspath(path)
if isinstance(path, bytes):
sep = b'\\'
altsep = b'/'
@@ -518,6 +527,7 @@ try:
except ImportError: # not running on Windows - mock up something sensible
def abspath(path):
"""Return the absolute version of a path."""
+ path = os.fspath(path)
if not isabs(path):
if isinstance(path, bytes):
cwd = os.getcwdb()
@@ -531,6 +541,7 @@ else: # use native Windows method on Windows
"""Return the absolute version of a path."""
if path: # Empty path must return current working directory.
+ path = os.fspath(path)
try:
path = _getfullpathname(path)
except OSError:
@@ -549,6 +560,7 @@ supports_unicode_filenames = (hasattr(sys, "getwindowsversion") and
def relpath(path, start=None):
"""Return a relative version of a path"""
+ path = os.fspath(path)
if isinstance(path, bytes):
sep = b'\\'
curdir = b'.'
@@ -564,6 +576,7 @@ def relpath(path, start=None):
if not path:
raise ValueError("no path specified")
+ start = os.fspath(start)
try:
start_abs = abspath(normpath(start))
path_abs = abspath(normpath(path))
@@ -607,6 +620,7 @@ def commonpath(paths):
if not paths:
raise ValueError('commonpath() arg is an empty sequence')
+ paths = tuple(map(os.fspath, paths))
if isinstance(paths[0], bytes):
sep = b'\\'
altsep = b'/'
diff --git a/Lib/os.py b/Lib/os.py
index c31ecb2..307a1de 100644
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -353,7 +353,7 @@ def walk(top, topdown=True, onerror=None, followlinks=False):
dirs.remove('CVS') # don't visit CVS directories
"""
-
+ top = fspath(top)
dirs = []
nondirs = []
walk_dirs = []
@@ -536,6 +536,8 @@ if {open, stat} <= supports_dir_fd and {listdir, stat} <= supports_fd:
if 'CVS' in dirs:
dirs.remove('CVS') # don't visit CVS directories
"""
+ if not isinstance(top, int) or not hasattr(top, '__index__'):
+ top = fspath(top)
# Note: To guard against symlink races, we use the standard
# lstat()/open()/fstat() trick.
orig_st = stat(top, follow_symlinks=False, dir_fd=dir_fd)
diff --git a/Lib/posixpath.py b/Lib/posixpath.py
index d9f3f99..6dbdab2 100644
--- a/Lib/posixpath.py
+++ b/Lib/posixpath.py
@@ -49,6 +49,7 @@ def _get_sep(path):
def normcase(s):
"""Normalize case of pathname. Has no effect under Posix"""
+ s = os.fspath(s)
if not isinstance(s, (bytes, str)):
raise TypeError("normcase() argument must be str or bytes, "
"not '{}'".format(s.__class__.__name__))
@@ -60,6 +61,7 @@ def normcase(s):
def isabs(s):
"""Test whether a path is absolute"""
+ s = os.fspath(s)
sep = _get_sep(s)
return s.startswith(sep)
@@ -73,12 +75,13 @@ def join(a, *p):
If any component is an absolute path, all previous path components
will be discarded. An empty last part will result in a path that
ends with a separator."""
+ a = os.fspath(a)
sep = _get_sep(a)
path = a
try:
if not p:
path[:0] + sep #23780: Ensure compatible data type even if p is null.
- for b in p:
+ for b in map(os.fspath, p):
if b.startswith(sep):
path = b
elif not path or path.endswith(sep):
@@ -99,6 +102,7 @@ def join(a, *p):
def split(p):
"""Split a pathname. Returns tuple "(head, tail)" where "tail" is
everything after the final slash. Either part may be empty."""
+ p = os.fspath(p)
sep = _get_sep(p)
i = p.rfind(sep) + 1
head, tail = p[:i], p[i:]
@@ -113,6 +117,7 @@ def split(p):
# It is always true that root + ext == p.
def splitext(p):
+ p = os.fspath(p)
if isinstance(p, bytes):
sep = b'/'
extsep = b'.'
@@ -128,6 +133,7 @@ splitext.__doc__ = genericpath._splitext.__doc__
def splitdrive(p):
"""Split a pathname into drive and path. On Posix, drive is always
empty."""
+ p = os.fspath(p)
return p[:0], p
@@ -135,6 +141,7 @@ def splitdrive(p):
def basename(p):
"""Returns the final component of a pathname"""
+ p = os.fspath(p)
sep = _get_sep(p)
i = p.rfind(sep) + 1
return p[i:]
@@ -144,6 +151,7 @@ def basename(p):
def dirname(p):
"""Returns the directory component of a pathname"""
+ p = os.fspath(p)
sep = _get_sep(p)
i = p.rfind(sep) + 1
head = p[:i]
@@ -222,6 +230,7 @@ def ismount(path):
def expanduser(path):
"""Expand ~ and ~user constructions. If user or $HOME is unknown,
do nothing."""
+ path = os.fspath(path)
if isinstance(path, bytes):
tilde = b'~'
else:
@@ -267,6 +276,7 @@ _varprogb = None
def expandvars(path):
"""Expand shell variables of form $var and ${var}. Unknown variables
are left unchanged."""
+ path = os.fspath(path)
global _varprog, _varprogb
if isinstance(path, bytes):
if b'$' not in path:
@@ -318,6 +328,7 @@ def expandvars(path):
def normpath(path):
"""Normalize path, eliminating double slashes, etc."""
+ path = os.fspath(path)
if isinstance(path, bytes):
sep = b'/'
empty = b''
@@ -355,6 +366,7 @@ def normpath(path):
def abspath(path):
"""Return an absolute path."""
+ path = os.fspath(path)
if not isabs(path):
if isinstance(path, bytes):
cwd = os.getcwdb()
@@ -370,6 +382,7 @@ def abspath(path):
def realpath(filename):
"""Return the canonical path of the specified filename, eliminating any
symbolic links encountered in the path."""
+ filename = os.fspath(filename)
path, ok = _joinrealpath(filename[:0], filename, {})
return abspath(path)
@@ -434,6 +447,7 @@ def relpath(path, start=None):
if not path:
raise ValueError("no path specified")
+ path = os.fspath(path)
if isinstance(path, bytes):
curdir = b'.'
sep = b'/'
@@ -445,6 +459,8 @@ def relpath(path, start=None):
if start is None:
start = curdir
+ else:
+ start = os.fspath(start)
try:
start_list = [x for x in abspath(start).split(sep) if x]
@@ -472,6 +488,7 @@ def commonpath(paths):
if not paths:
raise ValueError('commonpath() arg is an empty sequence')
+ paths = tuple(map(os.fspath, paths))
if isinstance(paths[0], bytes):
sep = b'/'
curdir = b'.'
diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py
index 5331b24..c8f158d 100644
--- a/Lib/test/test_genericpath.py
+++ b/Lib/test/test_genericpath.py
@@ -450,16 +450,15 @@ class CommonTest(GenericTest):
with self.assertRaisesRegex(TypeError, errmsg):
self.pathmodule.join('str', b'bytes')
# regression, see #15377
- errmsg = r'join\(\) argument must be str or bytes, not %r'
- with self.assertRaisesRegex(TypeError, errmsg % 'int'):
+ with self.assertRaisesRegex(TypeError, 'int'):
self.pathmodule.join(42, 'str')
- with self.assertRaisesRegex(TypeError, errmsg % 'int'):
+ with self.assertRaisesRegex(TypeError, 'int'):
self.pathmodule.join('str', 42)
- with self.assertRaisesRegex(TypeError, errmsg % 'int'):
+ with self.assertRaisesRegex(TypeError, 'int'):
self.pathmodule.join(42)
- with self.assertRaisesRegex(TypeError, errmsg % 'list'):
+ with self.assertRaisesRegex(TypeError, 'list'):
self.pathmodule.join([])
- with self.assertRaisesRegex(TypeError, errmsg % 'bytearray'):
+ with self.assertRaisesRegex(TypeError, 'bytearray'):
self.pathmodule.join(bytearray(b'foo'), bytearray(b'bar'))
def test_relpath_errors(self):
@@ -471,14 +470,59 @@ class CommonTest(GenericTest):
self.pathmodule.relpath(b'bytes', 'str')
with self.assertRaisesRegex(TypeError, errmsg):
self.pathmodule.relpath('str', b'bytes')
- errmsg = r'relpath\(\) argument must be str or bytes, not %r'
- with self.assertRaisesRegex(TypeError, errmsg % 'int'):
+ with self.assertRaisesRegex(TypeError, 'int'):
self.pathmodule.relpath(42, 'str')
- with self.assertRaisesRegex(TypeError, errmsg % 'int'):
+ with self.assertRaisesRegex(TypeError, 'int'):
self.pathmodule.relpath('str', 42)
- with self.assertRaisesRegex(TypeError, errmsg % 'bytearray'):
+ with self.assertRaisesRegex(TypeError, 'bytearray'):
self.pathmodule.relpath(bytearray(b'foo'), bytearray(b'bar'))
+class PathLikeTests(unittest.TestCase):
+
+ class PathLike:
+ def __init__(self, path=''):
+ self.path = path
+ def __fspath__(self):
+ if isinstance(self.path, BaseException):
+ raise self.path
+ else:
+ return self.path
+
+ def setUp(self):
+ self.file_name = support.TESTFN.lower()
+ self.file_path = self.PathLike(support.TESTFN)
+ self.addCleanup(support.unlink, self.file_name)
+ create_file(self.file_name, b"test_genericpath.PathLikeTests")
+
+ def assertPathEqual(self, func):
+ self.assertEqual(func(self.file_path), func(self.file_name))
+
+ def test_path_exists(self):
+ self.assertPathEqual(os.path.exists)
+
+ def test_path_isfile(self):
+ self.assertPathEqual(os.path.isfile)
+
+ def test_path_isdir(self):
+ self.assertPathEqual(os.path.isdir)
+
+ def test_path_commonprefix(self):
+ self.assertEqual(os.path.commonprefix([self.file_path, self.file_name]),
+ self.file_name)
+
+ def test_path_getsize(self):
+ self.assertPathEqual(os.path.getsize)
+
+ def test_path_getmtime(self):
+ self.assertPathEqual(os.path.getatime)
+
+ def test_path_getctime(self):
+ self.assertPathEqual(os.path.getctime)
+
+ def test_path_samefile(self):
+ self.assertTrue(os.path.samefile(self.file_path, self.file_name))
+
+
if __name__=="__main__":
unittest.main()
diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py
index 580f203..90edb6d 100644
--- a/Lib/test/test_ntpath.py
+++ b/Lib/test/test_ntpath.py
@@ -452,5 +452,88 @@ class NtCommonTest(test_genericpath.CommonTest, unittest.TestCase):
attributes = ['relpath', 'splitunc']
+class PathLikeTests(unittest.TestCase):
+
+ path = ntpath
+
+ class PathLike:
+ def __init__(self, path=''):
+ self.path = path
+ def __fspath__(self):
+ if isinstance(self.path, BaseException):
+ raise self.path
+ else:
+ return self.path
+
+ def setUp(self):
+ self.file_name = support.TESTFN.lower()
+ self.file_path = self.PathLike(support.TESTFN)
+ self.addCleanup(support.unlink, self.file_name)
+ with open(self.file_name, 'xb', 0) as file:
+ file.write(b"test_ntpath.PathLikeTests")
+
+ def assertPathEqual(self, func):
+ self.assertEqual(func(self.file_path), func(self.file_name))
+
+ def test_path_normcase(self):
+ self.assertPathEqual(self.path.normcase)
+
+ def test_path_isabs(self):
+ self.assertPathEqual(self.path.isabs)
+
+ def test_path_join(self):
+ self.assertEqual(self.path.join('a', self.PathLike('b'), 'c'),
+ self.path.join('a', 'b', 'c'))
+
+ def test_path_split(self):
+ self.assertPathEqual(self.path.split)
+
+ def test_path_splitext(self):
+ self.assertPathEqual(self.path.splitext)
+
+ def test_path_splitdrive(self):
+ self.assertPathEqual(self.path.splitdrive)
+
+ def test_path_basename(self):
+ self.assertPathEqual(self.path.basename)
+
+ def test_path_dirname(self):
+ self.assertPathEqual(self.path.dirname)
+
+ def test_path_islink(self):
+ self.assertPathEqual(self.path.islink)
+
+ def test_path_lexists(self):
+ self.assertPathEqual(self.path.lexists)
+
+ def test_path_ismount(self):
+ self.assertPathEqual(self.path.ismount)
+
+ def test_path_expanduser(self):
+ self.assertPathEqual(self.path.expanduser)
+
+ def test_path_expandvars(self):
+ self.assertPathEqual(self.path.expandvars)
+
+ def test_path_normpath(self):
+ self.assertPathEqual(self.path.normpath)
+
+ def test_path_abspath(self):
+ self.assertPathEqual(self.path.abspath)
+
+ def test_path_realpath(self):
+ self.assertPathEqual(self.path.realpath)
+
+ def test_path_relpath(self):
+ self.assertPathEqual(self.path.relpath)
+
+ def test_path_commonpath(self):
+ common_path = self.path.commonpath([self.file_path, self.file_name])
+ self.assertEqual(common_path, self.file_name)
+
+ def test_path_isdir(self):
+ self.assertPathEqual(self.path.isdir)
+
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index d8920d9..5ac4d64 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -874,10 +874,12 @@ class WalkTests(unittest.TestCase):
self.assertEqual(all[2 + flipped], (self.sub11_path, [], []))
self.assertEqual(all[3 - 2 * flipped], self.sub2_tree)
- def test_walk_prune(self):
+ def test_walk_prune(self, walk_path=None):
+ if walk_path is None:
+ walk_path = self.walk_path
# Prune the search.
all = []
- for root, dirs, files in self.walk(self.walk_path):
+ for root, dirs, files in self.walk(walk_path):
all.append((root, dirs, files))
# Don't descend into SUB1.
if 'SUB1' in dirs:
@@ -886,11 +888,22 @@ class WalkTests(unittest.TestCase):
self.assertEqual(len(all), 2)
self.assertEqual(all[0],
- (self.walk_path, ["SUB2"], ["tmp1"]))
+ (str(walk_path), ["SUB2"], ["tmp1"]))
all[1][-1].sort()
self.assertEqual(all[1], self.sub2_tree)
+ def test_file_like_path(self):
+ class FileLike:
+ def __init__(self, path):
+ self._path = path
+ def __str__(self):
+ return str(self._path)
+ def __fspath__(self):
+ return self._path
+
+ self.test_walk_prune(FileLike(self.walk_path))
+
def test_walk_bottom_up(self):
# Walk bottom-up.
all = list(self.walk(self.walk_path, topdown=False))
@@ -2807,6 +2820,70 @@ class FDInheritanceTests(unittest.TestCase):
self.assertEqual(os.get_inheritable(slave_fd), False)
+class PathTConverterTests(unittest.TestCase):
+ # tuples of (function name, allows fd arguments, additional arguments to
+ # function, cleanup function)
+ functions = [
+ ('stat', True, (), None),
+ ('lstat', False, (), None),
+ ('access', True, (os.F_OK,), None),
+ ('chflags', False, (0,), None),
+ ('lchflags', False, (0,), None),
+ ('open', False, (0,), getattr(os, 'close', None)),
+ ]
+
+ def test_path_t_converter(self):
+ class PathLike:
+ def __init__(self, path):
+ self.path = path
+
+ def __fspath__(self):
+ return self.path
+
+ str_filename = support.TESTFN
+ bytes_filename = support.TESTFN.encode('ascii')
+ bytearray_filename = bytearray(bytes_filename)
+ fd = os.open(PathLike(str_filename), os.O_WRONLY|os.O_CREAT)
+ self.addCleanup(os.close, fd)
+ self.addCleanup(support.unlink, support.TESTFN)
+
+ int_fspath = PathLike(fd)
+ str_fspath = PathLike(str_filename)
+ bytes_fspath = PathLike(bytes_filename)
+ bytearray_fspath = PathLike(bytearray_filename)
+
+ for name, allow_fd, extra_args, cleanup_fn in self.functions:
+ with self.subTest(name=name):
+ try:
+ fn = getattr(os, name)
+ except AttributeError:
+ continue
+
+ for path in (str_filename, bytes_filename, bytearray_filename,
+ str_fspath, bytes_fspath):
+ with self.subTest(name=name, path=path):
+ result = fn(path, *extra_args)
+ if cleanup_fn is not None:
+ cleanup_fn(result)
+
+ with self.assertRaisesRegex(
+ TypeError, 'should be string, bytes'):
+ fn(int_fspath, *extra_args)
+ with self.assertRaisesRegex(
+ TypeError, 'should be string, bytes'):
+ fn(bytearray_fspath, *extra_args)
+
+ if allow_fd:
+ result = fn(fd, *extra_args) # should not fail
+ if cleanup_fn is not None:
+ cleanup_fn(result)
+ else:
+ with self.assertRaisesRegex(
+ TypeError,
+ 'os.PathLike'):
+ fn(fd, *extra_args)
+
+
@unittest.skipUnless(hasattr(os, 'get_blocking'),
'needs os.get_blocking() and os.set_blocking()')
class BlockingTests(unittest.TestCase):
diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py
index de22513..d2f58ba 100644
--- a/Lib/test/test_posix.py
+++ b/Lib/test/test_posix.py
@@ -397,7 +397,7 @@ class PosixTester(unittest.TestCase):
self.assertTrue(posix.stat(fp.fileno()))
self.assertRaisesRegex(TypeError,
- 'should be string, bytes or integer, not',
+ 'should be string, bytes, os.PathLike or integer, not',
posix.stat, float(fp.fileno()))
finally:
fp.close()
@@ -409,16 +409,16 @@ class PosixTester(unittest.TestCase):
self.assertTrue(posix.stat(os.fsencode(support.TESTFN)))
self.assertWarnsRegex(DeprecationWarning,
- 'should be string, bytes or integer, not',
+ 'should be string, bytes, os.PathLike or integer, not',
posix.stat, bytearray(os.fsencode(support.TESTFN)))
self.assertRaisesRegex(TypeError,
- 'should be string, bytes or integer, not',
+ 'should be string, bytes, os.PathLike or integer, not',
posix.stat, None)
self.assertRaisesRegex(TypeError,
- 'should be string, bytes or integer, not',
+ 'should be string, bytes, os.PathLike or integer, not',
posix.stat, list(support.TESTFN))
self.assertRaisesRegex(TypeError,
- 'should be string, bytes or integer, not',
+ 'should be string, bytes, os.PathLike or integer, not',
posix.stat, list(os.fsencode(support.TESTFN)))
@unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py
index 0783c36..8a1e33b 100644
--- a/Lib/test/test_posixpath.py
+++ b/Lib/test/test_posixpath.py
@@ -596,5 +596,85 @@ class PosixCommonTest(test_genericpath.CommonTest, unittest.TestCase):
attributes = ['relpath', 'samefile', 'sameopenfile', 'samestat']
+class PathLikeTests(unittest.TestCase):
+
+ path = posixpath
+
+ class PathLike:
+ def __init__(self, path=''):
+ self.path = path
+ def __fspath__(self):
+ if isinstance(self.path, BaseException):
+ raise self.path
+ else:
+ return self.path
+
+ def setUp(self):
+ self.file_name = support.TESTFN.lower()
+ self.file_path = self.PathLike(support.TESTFN)
+ self.addCleanup(support.unlink, self.file_name)
+ with open(self.file_name, 'xb', 0) as file:
+ file.write(b"test_posixpath.PathLikeTests")
+
+ def assertPathEqual(self, func):
+ self.assertEqual(func(self.file_path), func(self.file_name))
+
+ def test_path_normcase(self):
+ self.assertPathEqual(self.path.normcase)
+
+ def test_path_isabs(self):
+ self.assertPathEqual(self.path.isabs)
+
+ def test_path_join(self):
+ self.assertEqual(self.path.join('a', self.PathLike('b'), 'c'),
+ self.path.join('a', 'b', 'c'))
+
+ def test_path_split(self):
+ self.assertPathEqual(self.path.split)
+
+ def test_path_splitext(self):
+ self.assertPathEqual(self.path.splitext)
+
+ def test_path_splitdrive(self):
+ self.assertPathEqual(self.path.splitdrive)
+
+ def test_path_basename(self):
+ self.assertPathEqual(self.path.basename)
+
+ def test_path_dirname(self):
+ self.assertPathEqual(self.path.dirname)
+
+ def test_path_islink(self):
+ self.assertPathEqual(self.path.islink)
+
+ def test_path_lexists(self):
+ self.assertPathEqual(self.path.lexists)
+
+ def test_path_ismount(self):
+ self.assertPathEqual(self.path.ismount)
+
+ def test_path_expanduser(self):
+ self.assertPathEqual(self.path.expanduser)
+
+ def test_path_expandvars(self):
+ self.assertPathEqual(self.path.expandvars)
+
+ def test_path_normpath(self):
+ self.assertPathEqual(self.path.normpath)
+
+ def test_path_abspath(self):
+ self.assertPathEqual(self.path.abspath)
+
+ def test_path_realpath(self):
+ self.assertPathEqual(self.path.realpath)
+
+ def test_path_relpath(self):
+ self.assertPathEqual(self.path.relpath)
+
+ def test_path_commonpath(self):
+ common_path = self.path.commonpath([self.file_path, self.file_name])
+ self.assertEqual(common_path, self.file_name)
+
+
if __name__=="__main__":
unittest.main()