+import errno
import inspect
import ntpath
import os
import sys
import unittest
import warnings
-from ntpath import ALLOW_MISSING
+from ntpath import ALL_BUT_LAST, ALLOW_MISSING
from test import support
from test.support import TestFailed, cpython_only, os_helper
from test.support.os_helper import FakePath
# gh-106242: Embedded nulls and non-strict fallback to abspath
self.assertEqual(realpath(path, strict=False), path)
# gh-106242: Embedded nulls should raise OSError (not ValueError)
+ self.assertRaises(OSError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(OSError, realpath, path, strict=True)
self.assertRaises(OSError, realpath, path, strict=ALLOW_MISSING)
path = ABSTFNb + b'\x00'
self.assertEqual(realpath(path, strict=False), path)
+ self.assertRaises(OSError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(OSError, realpath, path, strict=True)
self.assertRaises(OSError, realpath, path, strict=ALLOW_MISSING)
path = ABSTFN + '\\nonexistent\\x\x00'
self.assertEqual(realpath(path, strict=False), path)
+ self.assertRaises(OSError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(OSError, realpath, path, strict=True)
self.assertRaises(OSError, realpath, path, strict=ALLOW_MISSING)
path = ABSTFNb + b'\\nonexistent\\x\x00'
self.assertEqual(realpath(path, strict=False), path)
+ self.assertRaises(OSError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(OSError, realpath, path, strict=True)
self.assertRaises(OSError, realpath, path, strict=ALLOW_MISSING)
path = ABSTFN + '\x00\\..'
self.assertEqual(realpath(path, strict=False), os.getcwd())
+ self.assertEqual(realpath(path, strict=ALL_BUT_LAST), os.getcwd())
self.assertEqual(realpath(path, strict=True), os.getcwd())
self.assertEqual(realpath(path, strict=ALLOW_MISSING), os.getcwd())
path = ABSTFNb + b'\x00\\..'
self.assertEqual(realpath(path, strict=False), os.getcwdb())
+ self.assertEqual(realpath(path, strict=ALL_BUT_LAST), os.getcwdb())
self.assertEqual(realpath(path, strict=True), os.getcwdb())
self.assertEqual(realpath(path, strict=ALLOW_MISSING), os.getcwdb())
path = ABSTFN + '\\nonexistent\\x\x00\\..'
self.assertEqual(realpath(path, strict=False), ABSTFN + '\\nonexistent')
+ self.assertRaises(OSError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(OSError, realpath, path, strict=True)
self.assertEqual(realpath(path, strict=ALLOW_MISSING), ABSTFN + '\\nonexistent')
path = ABSTFNb + b'\\nonexistent\\x\x00\\..'
self.assertEqual(realpath(path, strict=False), ABSTFNb + b'\\nonexistent')
+ self.assertRaises(OSError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(OSError, realpath, path, strict=True)
self.assertEqual(realpath(path, strict=ALLOW_MISSING), ABSTFNb + b'\\nonexistent')
@unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
- @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING})
+ @_parameterize({}, {'strict': True}, {'strict': ALL_BUT_LAST}, {'strict': ALLOW_MISSING})
def test_realpath_invalid_unicode_paths(self, kwargs):
realpath = ntpath.realpath
ABSTFN = ntpath.abspath(os_helper.TESTFN)
ABSTFNb = os.fsencode(ABSTFN)
path = ABSTFNb + b'\xff'
self.assertRaises(UnicodeDecodeError, realpath, path, **kwargs)
- self.assertRaises(UnicodeDecodeError, realpath, path, **kwargs)
path = ABSTFNb + b'\\nonexistent\\\xff'
self.assertRaises(UnicodeDecodeError, realpath, path, **kwargs)
- self.assertRaises(UnicodeDecodeError, realpath, path, **kwargs)
path = ABSTFNb + b'\xff\\..'
self.assertRaises(UnicodeDecodeError, realpath, path, **kwargs)
- self.assertRaises(UnicodeDecodeError, realpath, path, **kwargs)
path = ABSTFNb + b'\\nonexistent\\\xff\\..'
self.assertRaises(UnicodeDecodeError, realpath, path, **kwargs)
- self.assertRaises(UnicodeDecodeError, realpath, path, **kwargs)
@os_helper.skip_unless_symlink
@unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
- @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING})
+ @_parameterize({}, {'strict': True}, {'strict': ALL_BUT_LAST}, {'strict': ALLOW_MISSING})
def test_realpath_relative(self, kwargs):
ABSTFN = ntpath.abspath(os_helper.TESTFN)
open(ABSTFN, "wb").close()
self.addCleanup(os_helper.unlink, ABSTFN + "a")
os.symlink(ABSTFN, ABSTFN)
+ self.assertRaises(OSError, ntpath.realpath, ABSTFN, strict=ALL_BUT_LAST)
self.assertRaises(OSError, ntpath.realpath, ABSTFN, strict=True)
os.symlink(ABSTFN + "1", ABSTFN + "2")
os.symlink(ABSTFN + "2", ABSTFN + "1")
+ self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1", strict=ALL_BUT_LAST)
self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1", strict=True)
+ self.assertRaises(OSError, ntpath.realpath, ABSTFN + "2", strict=ALL_BUT_LAST)
self.assertRaises(OSError, ntpath.realpath, ABSTFN + "2", strict=True)
+ self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1\\x", strict=ALL_BUT_LAST)
self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1\\x", strict=True)
# Windows eliminates '..' components before resolving links, so the
# following call is not expected to raise.
+ self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..", strict=ALL_BUT_LAST),
+ ntpath.dirname(ABSTFN))
self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..", strict=True),
ntpath.dirname(ABSTFN))
+ self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..\\x", strict=ALL_BUT_LAST),
+ ntpath.dirname(ABSTFN) + "\\x")
self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1\\..\\x", strict=True)
os.symlink(ABSTFN + "x", ABSTFN + "y")
+ self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..\\"
+ + ntpath.basename(ABSTFN) + "y",
+ strict=ALL_BUT_LAST),
+ ABSTFN + "x")
self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1\\..\\"
+ ntpath.basename(ABSTFN) + "y",
strict=True)
+ self.assertRaises(OSError, ntpath.realpath,
+ ABSTFN + "1\\..\\" + ntpath.basename(ABSTFN) + "1",
+ strict=ALL_BUT_LAST)
self.assertRaises(OSError, ntpath.realpath,
ABSTFN + "1\\..\\" + ntpath.basename(ABSTFN) + "1",
strict=True)
os.symlink(ntpath.basename(ABSTFN) + "a\\b", ABSTFN + "a")
+ self.assertRaises(OSError, ntpath.realpath, ABSTFN + "a", strict=ALL_BUT_LAST)
self.assertRaises(OSError, ntpath.realpath, ABSTFN + "a", strict=True)
os.symlink("..\\" + ntpath.basename(ntpath.dirname(ABSTFN))
+ "\\" + ntpath.basename(ABSTFN) + "c", ABSTFN + "c")
+ self.assertRaises(OSError, ntpath.realpath, ABSTFN + "c", strict=ALL_BUT_LAST)
self.assertRaises(OSError, ntpath.realpath, ABSTFN + "c", strict=True)
# Test using relative path as well.
+ self.assertRaises(OSError, ntpath.realpath, ntpath.basename(ABSTFN),
+ strict=ALL_BUT_LAST)
self.assertRaises(OSError, ntpath.realpath, ntpath.basename(ABSTFN),
strict=True)
@os_helper.skip_unless_symlink
@unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
- @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING})
+ @_parameterize({}, {'strict': True}, {'strict': ALL_BUT_LAST}, {'strict': ALLOW_MISSING})
def test_realpath_symlink_prefix(self, kwargs):
ABSTFN = ntpath.abspath(os_helper.TESTFN)
self.addCleanup(os_helper.unlink, ABSTFN + "3")
tester("ntpath.realpath('NUL')", r'\\.\NUL')
tester("ntpath.realpath('NUL', strict=False)", r'\\.\NUL')
tester("ntpath.realpath('NUL', strict=True)", r'\\.\NUL')
+ tester("ntpath.realpath('NUL', strict=ALL_BUT_LAST)", r'\\.\NUL')
tester("ntpath.realpath('NUL', strict=ALLOW_MISSING)", r'\\.\NUL')
@unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
self.assertPathEqual(test_file_long, ntpath.realpath(test_file_short))
- for kwargs in {}, {'strict': True}, {'strict': ALLOW_MISSING}:
+ for kwargs in {}, {'strict': True}, {'strict': ALL_BUT_LAST}, {'strict': ALLOW_MISSING}:
with self.subTest(**kwargs):
with os_helper.change_cwd(test_dir_long):
self.assertPathEqual(
self.assertPathEqual(test_file, ntpath.realpath(test_file_short))
+ @os_helper.skip_unless_symlink
+ @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
+ def test_realpath_mode(self):
+ realpath = ntpath.realpath
+ ABSTFN = ntpath.abspath(os_helper.TESTFN)
+ self.addCleanup(os_helper.rmdir, ABSTFN)
+ self.addCleanup(os_helper.rmdir, ABSTFN + "/dir")
+ self.addCleanup(os_helper.unlink, ABSTFN + "/file")
+ self.addCleanup(os_helper.unlink, ABSTFN + "/dir/file2")
+ self.addCleanup(os_helper.unlink, ABSTFN + "/link")
+ self.addCleanup(os_helper.unlink, ABSTFN + "/link2")
+ self.addCleanup(os_helper.unlink, ABSTFN + "/broken")
+ self.addCleanup(os_helper.unlink, ABSTFN + "/cycle")
+
+ os.mkdir(ABSTFN)
+ os.mkdir(ABSTFN + "\\dir")
+ open(ABSTFN + "\\file", "wb").close()
+ open(ABSTFN + "\\dir\\file2", "wb").close()
+ os.symlink("file", ABSTFN + "\\link")
+ os.symlink("dir", ABSTFN + "\\link2")
+ os.symlink("nonexistent", ABSTFN + "\\broken")
+ os.symlink("cycle", ABSTFN + "\\cycle")
+ def check(path, modes, expected, errno=None):
+ path = path.replace('/', '\\')
+ if isinstance(expected, str):
+ assert errno is None
+ expected = expected.replace('/', os.sep)
+ for mode in modes:
+ with self.subTest(mode=mode):
+ self.assertEqual(realpath(path, strict=mode),
+ ABSTFN + expected)
+ else:
+ for mode in modes:
+ with self.subTest(mode=mode):
+ with self.assertRaises(expected) as cm:
+ realpath(path, strict=mode)
+ if errno is not None:
+ self.assertEqual(cm.exception.errno, errno)
+
+ self.enterContext(os_helper.change_cwd(ABSTFN))
+ all_modes = [False, ALLOW_MISSING, ALL_BUT_LAST, True]
+ check("file", all_modes, "/file")
+ check("file/", all_modes, "/file")
+ check("file/file2", [False, ALLOW_MISSING], "/file/file2")
+ check("file/file2", [ALL_BUT_LAST, True], FileNotFoundError)
+ check("file/.", all_modes, "/file")
+ check("file/../link2", all_modes, "/dir")
+
+ check("dir", all_modes, "/dir")
+ check("dir/", all_modes, "/dir")
+ check("dir/file2", all_modes, "/dir/file2")
+
+ check("link", all_modes, "/file")
+ check("link/", all_modes, "/file")
+ check("link/file2", [False, ALLOW_MISSING], "/file/file2")
+ check("link/file2", [ALL_BUT_LAST, True], FileNotFoundError)
+ check("link/.", all_modes, "/file")
+ check("link/../link", all_modes, "/file")
+
+ check("link2", all_modes, "/dir")
+ check("link2/", all_modes, "/dir")
+ check("link2/file2", all_modes, "/dir/file2")
+
+ check("nonexistent", [False, ALLOW_MISSING, ALL_BUT_LAST], "/nonexistent")
+ check("nonexistent", [True], FileNotFoundError)
+ check("nonexistent/", [False, ALLOW_MISSING, ALL_BUT_LAST], "/nonexistent")
+ check("nonexistent/", [True], FileNotFoundError)
+ check("nonexistent/file", [False, ALLOW_MISSING], "/nonexistent/file")
+ check("nonexistent/file", [ALL_BUT_LAST, True], FileNotFoundError)
+ check("nonexistent/../link", all_modes, "/file")
+
+ check("broken", [False, ALLOW_MISSING, ALL_BUT_LAST], "/nonexistent")
+ check("broken", [True], FileNotFoundError)
+ check("broken/", [False, ALLOW_MISSING, ALL_BUT_LAST], "/nonexistent")
+ check("broken/", [True], FileNotFoundError)
+ check("broken/file", [False, ALLOW_MISSING], "/nonexistent/file")
+ check("broken/file", [ALL_BUT_LAST, True], FileNotFoundError)
+ check("broken/../link", all_modes, "/file")
+
+ check("cycle", [False], "/cycle")
+ check("cycle", [ALLOW_MISSING, ALL_BUT_LAST, True], OSError, errno.EINVAL)
+ check("cycle/", [False], "/cycle")
+ check("cycle/", [ALLOW_MISSING, ALL_BUT_LAST, True], OSError, errno.EINVAL)
+ check("cycle/file", [False], "/cycle/file")
+ check("cycle/file", [ALLOW_MISSING, ALL_BUT_LAST, True], OSError, errno.EINVAL)
+ check("cycle/../link", all_modes, "/file")
+
def test_expandvars(self):
with os_helper.EnvironmentVarGuard() as env:
env.clear()
+import errno
import inspect
import os
import posixpath
import sys
import unittest
from functools import partial
-from posixpath import realpath, abspath, dirname, basename, ALLOW_MISSING
+from posixpath import realpath, abspath, dirname, basename, ALL_BUT_LAST, ALLOW_MISSING
from test import support
from test import test_genericpath
from test.support import import_helper
self.assertEqual(result, expected)
@skip_if_ABSTFN_contains_backslash
- @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING})
+ @_parameterize({}, {'strict': True}, {'strict': ALL_BUT_LAST}, {'strict': ALLOW_MISSING})
def test_realpath_curdir(self, kwargs):
self.assertEqual(realpath('.', **kwargs), os.getcwd())
self.assertEqual(realpath('./.', **kwargs), os.getcwd())
self.assertEqual(realpath(b'/'.join([b'.'] * 100), **kwargs), os.getcwdb())
@skip_if_ABSTFN_contains_backslash
- @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING})
+ @_parameterize({}, {'strict': True}, {'strict': ALL_BUT_LAST}, {'strict': ALLOW_MISSING})
def test_realpath_pardir(self, kwargs):
self.assertEqual(realpath('..', **kwargs), dirname(os.getcwd()))
self.assertEqual(realpath('../..', **kwargs), dirname(dirname(os.getcwd())))
def test_realpath_invalid_paths(self):
path = '/\x00'
self.assertRaises(ValueError, realpath, path, strict=False)
+ self.assertRaises(ValueError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(ValueError, realpath, path, strict=True)
self.assertRaises(ValueError, realpath, path, strict=ALLOW_MISSING)
path = b'/\x00'
self.assertRaises(ValueError, realpath, path, strict=False)
+ self.assertRaises(ValueError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(ValueError, realpath, path, strict=True)
self.assertRaises(ValueError, realpath, path, strict=ALLOW_MISSING)
path = '/nonexistent/x\x00'
self.assertRaises(ValueError, realpath, path, strict=False)
+ self.assertRaises(FileNotFoundError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(FileNotFoundError, realpath, path, strict=True)
self.assertRaises(ValueError, realpath, path, strict=ALLOW_MISSING)
path = b'/nonexistent/x\x00'
self.assertRaises(ValueError, realpath, path, strict=False)
+ self.assertRaises(FileNotFoundError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(FileNotFoundError, realpath, path, strict=True)
self.assertRaises(ValueError, realpath, path, strict=ALLOW_MISSING)
path = '/\x00/..'
self.assertRaises(ValueError, realpath, path, strict=False)
+ self.assertRaises(ValueError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(ValueError, realpath, path, strict=True)
self.assertRaises(ValueError, realpath, path, strict=ALLOW_MISSING)
path = b'/\x00/..'
self.assertRaises(ValueError, realpath, path, strict=False)
+ self.assertRaises(ValueError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(ValueError, realpath, path, strict=True)
self.assertRaises(ValueError, realpath, path, strict=ALLOW_MISSING)
path = '/nonexistent/x\x00/..'
self.assertRaises(ValueError, realpath, path, strict=False)
+ self.assertRaises(FileNotFoundError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(FileNotFoundError, realpath, path, strict=True)
self.assertRaises(ValueError, realpath, path, strict=ALLOW_MISSING)
path = b'/nonexistent/x\x00/..'
self.assertRaises(ValueError, realpath, path, strict=False)
+ self.assertRaises(FileNotFoundError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(FileNotFoundError, realpath, path, strict=True)
self.assertRaises(ValueError, realpath, path, strict=ALLOW_MISSING)
self.assertEqual(realpath(path, strict=ALLOW_MISSING), path)
else:
self.assertRaises(UnicodeEncodeError, realpath, path, strict=False)
+ self.assertRaises(UnicodeEncodeError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(UnicodeEncodeError, realpath, path, strict=True)
self.assertRaises(UnicodeEncodeError, realpath, path, strict=ALLOW_MISSING)
path = '/nonexistent/\udfff'
else:
self.assertRaises(UnicodeEncodeError, realpath, path, strict=False)
self.assertRaises(UnicodeEncodeError, realpath, path, strict=ALLOW_MISSING)
+ self.assertRaises(FileNotFoundError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(FileNotFoundError, realpath, path, strict=True)
path = '/\udfff/..'
if sys.platform == 'win32':
self.assertEqual(realpath(path, strict=ALLOW_MISSING), '/')
else:
self.assertRaises(UnicodeEncodeError, realpath, path, strict=False)
+ self.assertRaises(UnicodeEncodeError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(UnicodeEncodeError, realpath, path, strict=True)
self.assertRaises(UnicodeEncodeError, realpath, path, strict=ALLOW_MISSING)
path = '/nonexistent/\udfff/..'
else:
self.assertRaises(UnicodeEncodeError, realpath, path, strict=False)
self.assertRaises(UnicodeEncodeError, realpath, path, strict=ALLOW_MISSING)
+ self.assertRaises(FileNotFoundError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(FileNotFoundError, realpath, path, strict=True)
path = b'/\xff'
else:
self.assertEqual(realpath(path, strict=False), path)
if support.is_wasi:
+ self.assertRaises(OSError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(OSError, realpath, path, strict=True)
self.assertRaises(OSError, realpath, path, strict=ALLOW_MISSING)
else:
+ self.assertEqual(realpath(path, strict=ALL_BUT_LAST), path)
self.assertRaises(FileNotFoundError, realpath, path, strict=True)
self.assertEqual(realpath(path, strict=ALLOW_MISSING), path)
path = b'/nonexistent/\xff'
else:
self.assertEqual(realpath(path, strict=False), path)
if support.is_wasi:
+ self.assertRaises(OSError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(OSError, realpath, path, strict=True)
self.assertRaises(OSError, realpath, path, strict=ALLOW_MISSING)
else:
+ self.assertRaises(FileNotFoundError, realpath, path, strict=ALL_BUT_LAST)
self.assertRaises(FileNotFoundError, realpath, path, strict=True)
@os_helper.skip_unless_symlink
@skip_if_ABSTFN_contains_backslash
- @_parameterize({}, {'strict': ALLOW_MISSING})
+ @_parameterize({}, {'strict': ALL_BUT_LAST}, {'strict': ALLOW_MISSING})
def test_realpath_relative(self, kwargs):
try:
os.symlink(posixpath.relpath(ABSTFN+"1"), ABSTFN)
@os_helper.skip_unless_symlink
@skip_if_ABSTFN_contains_backslash
- @_parameterize({}, {'strict': ALLOW_MISSING})
- def test_realpath_missing_pardir(self, kwargs):
+ def test_realpath_missing_pardir(self):
try:
os.symlink(TESTFN + "1", TESTFN)
- self.assertEqual(
- realpath("nonexistent/../" + TESTFN, **kwargs), ABSTFN + "1")
+ path = "nonexistent/../" + TESTFN
+ self.assertEqual(realpath(path), ABSTFN + "1")
+ self.assertEqual(realpath(path, strict=ALLOW_MISSING), ABSTFN + "1")
+ self.assertRaises(FileNotFoundError, realpath, path, strict=ALL_BUT_LAST)
+ self.assertRaises(FileNotFoundError, realpath, path, strict=True)
finally:
os_helper.unlink(TESTFN)
@os_helper.skip_unless_symlink
@skip_if_ABSTFN_contains_backslash
- @_parameterize({'strict': True}, {'strict': ALLOW_MISSING})
+ @_parameterize({'strict': True}, {'strict': ALL_BUT_LAST}, {'strict': ALLOW_MISSING})
def test_realpath_symlink_loops_strict(self, kwargs):
# Bug #43757, raise OSError if we get into an infinite symlink loop in
# the strict modes.
@os_helper.skip_unless_symlink
@skip_if_ABSTFN_contains_backslash
- @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING})
+ @_parameterize({}, {'strict': True}, {'strict': ALL_BUT_LAST}, {'strict': ALLOW_MISSING})
def test_realpath_repeated_indirect_symlinks(self, kwargs):
# Issue #6975.
try:
@os_helper.skip_unless_symlink
@skip_if_ABSTFN_contains_backslash
- @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING})
+ @_parameterize({}, {'strict': True}, {'strict': ALL_BUT_LAST}, {'strict': ALLOW_MISSING})
def test_realpath_deep_recursion(self, kwargs):
depth = 10
try:
@os_helper.skip_unless_symlink
@skip_if_ABSTFN_contains_backslash
- @_parameterize({}, {'strict': ALLOW_MISSING})
+ @_parameterize({}, {'strict': ALL_BUT_LAST}, {'strict': ALLOW_MISSING})
def test_realpath_resolve_parents(self, kwargs):
# We also need to resolve any symlinks in the parents of a relative
# path passed to realpath. E.g.: current working directory is
@os_helper.skip_unless_symlink
@skip_if_ABSTFN_contains_backslash
- @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING})
+ @_parameterize({}, {'strict': True}, {'strict': ALL_BUT_LAST}, {'strict': ALLOW_MISSING})
def test_realpath_resolve_before_normalizing(self, kwargs):
# Bug #990669: Symbolic links should be resolved before we
# normalize the path. E.g.: if we have directories 'a', 'k' and 'y'
@os_helper.skip_unless_symlink
@skip_if_ABSTFN_contains_backslash
- @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING})
+ @_parameterize({}, {'strict': True}, {'strict': ALL_BUT_LAST}, {'strict': ALLOW_MISSING})
def test_realpath_resolve_first(self, kwargs):
# Bug #1213894: The first component of the path, if not absolute,
# must be resolved too.
@skip_if_ABSTFN_contains_backslash
@unittest.skipIf(os.chmod not in os.supports_follow_symlinks, "Can't set symlink permissions")
@unittest.skipIf(sys.platform != "darwin", "only macOS requires read permission to readlink()")
- @_parameterize({'strict': True}, {'strict': ALLOW_MISSING})
+ @_parameterize({'strict': True}, {'strict': ALL_BUT_LAST}, {'strict': ALLOW_MISSING})
def test_realpath_unreadable_symlink_strict(self, kwargs):
try:
os.symlink(ABSTFN+"1", ABSTFN)
os.chmod(ABSTFN, 0o000)
self.assertEqual(realpath(ABSTFN, strict=False), ABSTFN)
self.assertEqual(realpath(ABSTFN, strict=True), ABSTFN)
+ self.assertEqual(realpath(ABSTFN, strict=ALL_BUT_LAST), ABSTFN)
self.assertEqual(realpath(ABSTFN, strict=ALLOW_MISSING), ABSTFN)
try:
ABSTFN + '/k')
self.assertRaises(PermissionError, realpath, ABSTFN + '/k',
strict=True)
+ self.assertRaises(PermissionError, realpath, ABSTFN + '/k',
+ strict=ALL_BUT_LAST)
self.assertRaises(PermissionError, realpath, ABSTFN + '/k',
strict=ALLOW_MISSING)
ABSTFN + '/missing')
self.assertRaises(PermissionError, realpath, ABSTFN + '/missing',
strict=True)
+ self.assertRaises(PermissionError, realpath, ABSTFN + '/missing',
+ strict=ALL_BUT_LAST)
self.assertRaises(PermissionError, realpath, ABSTFN + '/missing',
strict=ALLOW_MISSING)
finally:
with open(ABSTFN, 'w') as f:
f.write('test_posixpath wuz ere')
self.assertEqual(realpath(ABSTFN, strict=False), ABSTFN)
+ self.assertEqual(realpath(ABSTFN, strict=ALL_BUT_LAST), ABSTFN)
self.assertEqual(realpath(ABSTFN, strict=True), ABSTFN)
self.assertEqual(realpath(ABSTFN, strict=ALLOW_MISSING), ABSTFN)
self.assertEqual(realpath(ABSTFN + "/", strict=False), ABSTFN)
+ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/", strict=ALL_BUT_LAST)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/", strict=True)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/",
strict=ALLOW_MISSING)
self.assertEqual(realpath(ABSTFN + "/.", strict=False), ABSTFN)
+ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.", strict=ALL_BUT_LAST)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.", strict=True)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.",
strict=ALLOW_MISSING)
self.assertEqual(realpath(ABSTFN + "/..", strict=False), dirname(ABSTFN))
+ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..", strict=ALL_BUT_LAST)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..", strict=True)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..",
strict=ALLOW_MISSING)
self.assertEqual(realpath(ABSTFN + "/subdir", strict=False), ABSTFN + "/subdir")
+ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir", strict=ALL_BUT_LAST)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir", strict=True)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir",
strict=ALLOW_MISSING)
f.write('test_posixpath wuz ere')
os.symlink(ABSTFN + "1", ABSTFN)
self.assertEqual(realpath(ABSTFN, strict=False), ABSTFN + "1")
+ self.assertEqual(realpath(ABSTFN, strict=ALL_BUT_LAST), ABSTFN + "1")
self.assertEqual(realpath(ABSTFN, strict=True), ABSTFN + "1")
self.assertEqual(realpath(ABSTFN, strict=ALLOW_MISSING), ABSTFN + "1")
self.assertEqual(realpath(ABSTFN + "/", strict=False), ABSTFN + "1")
+ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/", strict=ALL_BUT_LAST)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/", strict=True)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/",
strict=ALLOW_MISSING)
self.assertEqual(realpath(ABSTFN + "/.", strict=False), ABSTFN + "1")
+ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.", strict=ALL_BUT_LAST)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.", strict=True)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.",
strict=ALLOW_MISSING)
self.assertEqual(realpath(ABSTFN + "/..", strict=False), dirname(ABSTFN))
+ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..", strict=ALL_BUT_LAST)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..", strict=True)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..",
strict=ALLOW_MISSING)
self.assertEqual(realpath(ABSTFN + "/subdir", strict=False), ABSTFN + "1/subdir")
+ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir", strict=ALL_BUT_LAST)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir", strict=True)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir",
strict=ALLOW_MISSING)
os.symlink(ABSTFN + "2", ABSTFN + "1")
os.symlink(ABSTFN + "1", ABSTFN)
self.assertEqual(realpath(ABSTFN, strict=False), ABSTFN + "2")
+ self.assertEqual(realpath(ABSTFN, strict=ALL_BUT_LAST), ABSTFN + "2")
self.assertEqual(realpath(ABSTFN, strict=True), ABSTFN + "2")
self.assertEqual(realpath(ABSTFN, strict=True), ABSTFN + "2")
self.assertEqual(realpath(ABSTFN + "/", strict=False), ABSTFN + "2")
+ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/", strict=ALL_BUT_LAST)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/", strict=True)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/",
strict=ALLOW_MISSING)
self.assertEqual(realpath(ABSTFN + "/.", strict=False), ABSTFN + "2")
+ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.", strict=ALL_BUT_LAST)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.", strict=True)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.",
strict=ALLOW_MISSING)
self.assertEqual(realpath(ABSTFN + "/..", strict=False), dirname(ABSTFN))
+ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..", strict=ALL_BUT_LAST)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..", strict=True)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..",
strict=ALLOW_MISSING)
self.assertEqual(realpath(ABSTFN + "/subdir", strict=False), ABSTFN + "2/subdir")
+ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir", strict=ALL_BUT_LAST)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir", strict=True)
self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir",
strict=ALLOW_MISSING)
os_helper.unlink(ABSTFN + "1")
os_helper.unlink(ABSTFN + "2")
+ @os_helper.skip_unless_symlink
+ def test_realpath_mode(self):
+ self.addCleanup(os_helper.rmdir, ABSTFN)
+ self.addCleanup(os_helper.rmdir, ABSTFN + "/dir")
+ self.addCleanup(os_helper.unlink, ABSTFN + "/file")
+ self.addCleanup(os_helper.unlink, ABSTFN + "/dir/file2")
+ self.addCleanup(os_helper.unlink, ABSTFN + "/link")
+ self.addCleanup(os_helper.unlink, ABSTFN + "/link2")
+ self.addCleanup(os_helper.unlink, ABSTFN + "/broken")
+ self.addCleanup(os_helper.unlink, ABSTFN + "/cycle")
+
+ os.mkdir(ABSTFN)
+ os.mkdir(ABSTFN + "/dir")
+ open(ABSTFN + "/file", "wb").close()
+ open(ABSTFN + "/dir/file2", "wb").close()
+ os.symlink("file", ABSTFN + "/link")
+ os.symlink("dir", ABSTFN + "/link2")
+ os.symlink("nonexistent", ABSTFN + "/broken")
+ os.symlink("cycle", ABSTFN + "/cycle")
+ def check(path, modes, expected, errno=None):
+ if isinstance(expected, str):
+ assert errno is None
+ expected = expected.replace('/', os.sep)
+ for mode in modes:
+ with self.subTest(mode=mode):
+ self.assertEqual(realpath(path, strict=mode).replace('/', os.sep),
+ ABSTFN.replace('/', os.sep) + expected)
+ else:
+ for mode in modes:
+ with self.subTest(mode=mode):
+ with self.assertRaises(expected) as cm:
+ realpath(path, strict=mode)
+ if errno is not None:
+ self.assertEqual(cm.exception.errno, errno)
+
+ self.enterContext(os_helper.change_cwd(ABSTFN))
+ all_modes = [False, ALLOW_MISSING, ALL_BUT_LAST, True]
+ check("file", all_modes, "/file")
+ check("file/", [False], "/file")
+ check("file/", [ALLOW_MISSING, ALL_BUT_LAST, True], NotADirectoryError)
+ check("file/file2", [False], "/file/file2")
+ check("file/file2", [ALLOW_MISSING, ALL_BUT_LAST, True], NotADirectoryError)
+ check("file/.", [False], "/file")
+ check("file/.", [ALLOW_MISSING, ALL_BUT_LAST, True], NotADirectoryError)
+ check("file/../link2", [False], "/dir")
+ check("file/../link2", [ALLOW_MISSING, ALL_BUT_LAST, True], NotADirectoryError)
+
+ check("dir", all_modes, "/dir")
+ check("dir/", all_modes, "/dir")
+ check("dir/file2", all_modes, "/dir/file2")
+
+ check("link", all_modes, "/file")
+ check("link/", [False], "/file")
+ check("link/", [ALLOW_MISSING, ALL_BUT_LAST, True], NotADirectoryError)
+ check("link/file2", [False], "/file/file2")
+ check("link/file2", [ALLOW_MISSING, ALL_BUT_LAST, True], NotADirectoryError)
+ check("link/.", [False], "/file")
+ check("link/.", [ALLOW_MISSING, ALL_BUT_LAST, True], NotADirectoryError)
+ check("link/../link", [False], "/file")
+ check("link/../link", [ALLOW_MISSING, ALL_BUT_LAST, True], NotADirectoryError)
+
+ check("link2", all_modes, "/dir")
+ check("link2/", all_modes, "/dir")
+ check("link2/file2", all_modes, "/dir/file2")
+
+ check("nonexistent", [False, ALLOW_MISSING, ALL_BUT_LAST], "/nonexistent")
+ check("nonexistent", [True], FileNotFoundError)
+ check("nonexistent/", [False, ALLOW_MISSING, ALL_BUT_LAST], "/nonexistent")
+ check("nonexistent/", [True], FileNotFoundError)
+ check("nonexistent/file", [False, ALLOW_MISSING], "/nonexistent/file")
+ check("nonexistent/file", [ALL_BUT_LAST, True], FileNotFoundError)
+ check("nonexistent/../link", [False, ALLOW_MISSING], "/file")
+ check("nonexistent/../link", [ALL_BUT_LAST, True], FileNotFoundError)
+
+ check("broken", [False, ALLOW_MISSING, ALL_BUT_LAST], "/nonexistent")
+ check("broken", [True], FileNotFoundError)
+ check("broken/", [False, ALLOW_MISSING, ALL_BUT_LAST], "/nonexistent")
+ check("broken/", [True], FileNotFoundError)
+ check("broken/file", [False, ALLOW_MISSING], "/nonexistent/file")
+ check("broken/file", [ALL_BUT_LAST, True], FileNotFoundError)
+ check("broken/../link", [False, ALLOW_MISSING], "/file")
+ check("broken/../link", [ALL_BUT_LAST, True], FileNotFoundError)
+
+ check("cycle", [False], "/cycle")
+ check("cycle", [ALLOW_MISSING, ALL_BUT_LAST, True], OSError, errno.ELOOP)
+ check("cycle/", [False], "/cycle")
+ check("cycle/", [ALLOW_MISSING, ALL_BUT_LAST, True], OSError, errno.ELOOP)
+ check("cycle/file", [False], "/cycle/file")
+ check("cycle/file", [ALLOW_MISSING, ALL_BUT_LAST, True], OSError, errno.ELOOP)
+ check("cycle/../link", [False], "/file")
+ check("cycle/../link", [ALLOW_MISSING, ALL_BUT_LAST, True], OSError, errno.ELOOP)
+
def test_relpath(self):
(real_getcwd, os.getcwd) = (os.getcwd, lambda: r"/home/user/bar")
try:
def test_path_abspath(self):
self.assertPathEqual(self.path.abspath)
- @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING})
+ @_parameterize({}, {'strict': True}, {'strict': ALL_BUT_LAST}, {'strict': ALLOW_MISSING})
def test_path_realpath(self, kwargs):
self.assertPathEqual(self.path.realpath)