Update {test_}posix{path} from CPython 3.10.6

This commit is contained in:
CPython Developers
2022-08-15 01:56:50 +09:00
committed by Jeong YunWon
parent cee42ca8bd
commit a27218b8b3
3 changed files with 341 additions and 263 deletions

30
Lib/posixpath.py vendored
View File

@@ -265,6 +265,9 @@ def expanduser(path):
# password database, return the path unchanged
return path
userhome = pwent.pw_dir
# if no user home, return the path unchanged on VxWorks
if userhome is None and sys.platform == "vxworks":
return path
if isinstance(path, bytes):
userhome = os.fsencode(userhome)
root = b'/'
@@ -352,6 +355,7 @@ def normpath(path):
initial_slashes = path.startswith(sep)
# POSIX allows one or two initial slashes, but treats three or more
# as single slash.
# (see http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13)
if (initial_slashes and
path.startswith(sep*2) and not path.startswith(sep*3)):
initial_slashes = 2
@@ -387,16 +391,16 @@ def abspath(path):
# Return a canonical path (i.e. the absolute location of a file on the
# filesystem).
def realpath(filename):
def realpath(filename, *, strict=False):
"""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, {})
path, ok = _joinrealpath(filename[:0], filename, strict, {})
return abspath(path)
# Join two paths, normalizing and eliminating any symbolic links
# encountered in the second path.
def _joinrealpath(path, rest, seen):
def _joinrealpath(path, rest, strict, seen):
if isinstance(path, bytes):
sep = b'/'
curdir = b'.'
@@ -425,7 +429,15 @@ def _joinrealpath(path, rest, seen):
path = pardir
continue
newpath = join(path, name)
if not islink(newpath):
try:
st = os.lstat(newpath)
except OSError:
if strict:
raise
is_link = False
else:
is_link = stat.S_ISLNK(st.st_mode)
if not is_link:
path = newpath
continue
# Resolve the symbolic link
@@ -436,10 +448,14 @@ def _joinrealpath(path, rest, seen):
# use cached value
continue
# The symlink is not resolved, so we must have a symlink loop.
# Return already resolved part + rest of the path unchanged.
return join(newpath, rest), False
if strict:
# Raise OSError(errno.ELOOP)
os.stat(newpath)
else:
# Return already resolved part + rest of the path unchanged.
return join(newpath, rest), False
seen[newpath] = None # not resolved symlink
path, ok = _joinrealpath(path, os.readlink(newpath), seen)
path, ok = _joinrealpath(path, os.readlink(newpath), strict, seen)
if not ok:
return join(path, rest), False
seen[newpath] = path # resolved symlink

507
Lib/test/test_posix.py vendored
View File

@@ -1,7 +1,9 @@
"Test posix functions"
from test import support
from test.support import os_helper, import_helper, warnings_helper
from test.support import import_helper
from test.support import os_helper
from test.support import warnings_helper
from test.support.script_helper import assert_python_ok
# Skip these tests if there is no posix module.
@@ -19,6 +21,7 @@ import tempfile
import unittest
import warnings
import textwrap
from contextlib import contextmanager
_DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(),
os_helper.TESTFN + '-dummy-symlink')
@@ -43,8 +46,8 @@ class PosixTester(unittest.TestCase):
def setUp(self):
# create empty file
fp = open(os_helper.TESTFN, 'w+')
fp.close()
with open(os_helper.TESTFN, "wb"):
pass
self.teardown_files = [ os_helper.TESTFN ]
self._warnings_manager = warnings_helper.check_warnings()
self._warnings_manager.__enter__()
@@ -460,10 +463,14 @@ class PosixTester(unittest.TestCase):
def test_utime_nofollow_symlinks(self):
now = time.time()
posix.utime(os_helper.TESTFN, None, follow_symlinks=False)
self.assertRaises(TypeError, posix.utime, os_helper.TESTFN, (None, None), follow_symlinks=False)
self.assertRaises(TypeError, posix.utime, os_helper.TESTFN, (now, None), follow_symlinks=False)
self.assertRaises(TypeError, posix.utime, os_helper.TESTFN, (None, now), follow_symlinks=False)
posix.utime(os_helper.TESTFN, (int(now), int(now)), follow_symlinks=False)
self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
(None, None), follow_symlinks=False)
self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
(now, None), follow_symlinks=False)
self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
(None, now), follow_symlinks=False)
posix.utime(os_helper.TESTFN, (int(now), int(now)),
follow_symlinks=False)
posix.utime(os_helper.TESTFN, (now, now), follow_symlinks=False)
posix.utime(os_helper.TESTFN, follow_symlinks=False)
@@ -638,12 +645,17 @@ class PosixTester(unittest.TestCase):
@unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
def test_mkfifo(self):
os_helper.unlink(os_helper.TESTFN)
if sys.platform == "vxworks":
fifo_path = os.path.join("/fifos/", os_helper.TESTFN)
else:
fifo_path = os_helper.TESTFN
os_helper.unlink(fifo_path)
self.addCleanup(os_helper.unlink, fifo_path)
try:
posix.mkfifo(os_helper.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
posix.mkfifo(fifo_path, stat.S_IRUSR | stat.S_IWUSR)
except PermissionError as e:
self.skipTest('posix.mkfifo(): %s' % e)
self.assertTrue(stat.S_ISFIFO(posix.stat(os_helper.TESTFN).st_mode))
self.assertTrue(stat.S_ISFIFO(posix.stat(fifo_path).st_mode))
@unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
"don't have mknod()/S_IFIFO")
@@ -715,11 +727,20 @@ class PosixTester(unittest.TestCase):
chown_func(first_param, uid, -1)
check_stat(uid, gid)
if uid == 0:
if sys.platform == "vxworks":
# On VxWorks, root user id is 1 and 0 means no login user:
# both are super users.
is_root = (uid in (0, 1))
else:
is_root = (uid == 0)
if is_root:
# Try an amusingly large uid/gid to make sure we handle
# large unsigned values. (chown lets you use any
# uid/gid you like, even if they aren't defined.)
#
# On VxWorks uid_t is defined as unsigned short. A big
# value greater than 65535 will result in underflow error.
#
# This problem keeps coming up:
# http://bugs.python.org/issue1747858
# http://bugs.python.org/issue4591
@@ -729,7 +750,7 @@ class PosixTester(unittest.TestCase):
# This part of the test only runs when run as root.
# Only scary people run their tests as root.
big_value = 2**31
big_value = (2**31 if sys.platform != "vxworks" else 2**15)
chown_func(first_param, big_value, big_value)
check_stat(big_value, big_value)
chown_func(first_param, -1, -1)
@@ -893,9 +914,12 @@ class PosixTester(unittest.TestCase):
def test_utime(self):
now = time.time()
posix.utime(os_helper.TESTFN, None)
self.assertRaises(TypeError, posix.utime, os_helper.TESTFN, (None, None))
self.assertRaises(TypeError, posix.utime, os_helper.TESTFN, (now, None))
self.assertRaises(TypeError, posix.utime, os_helper.TESTFN, (None, now))
self.assertRaises(TypeError, posix.utime,
os_helper.TESTFN, (None, None))
self.assertRaises(TypeError, posix.utime,
os_helper.TESTFN, (now, None))
self.assertRaises(TypeError, posix.utime,
os_helper.TESTFN, (None, now))
posix.utime(os_helper.TESTFN, (int(now), int(now)))
posix.utime(os_helper.TESTFN, (now, now))
@@ -930,7 +954,8 @@ class PosixTester(unittest.TestCase):
@unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
def test_lchflags_regular_file(self):
self._test_chflags_regular_file(posix.lchflags, os_helper.TESTFN)
self._test_chflags_regular_file(posix.chflags, os_helper.TESTFN, follow_symlinks=False)
self._test_chflags_regular_file(posix.chflags, os_helper.TESTFN,
follow_symlinks=False)
@unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
def test_lchflags_symlink(self):
@@ -1034,6 +1059,7 @@ class PosixTester(unittest.TestCase):
@unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
@unittest.skipUnless(hasattr(os, 'popen'), "test needs os.popen()")
def test_getgroups(self):
with os.popen('id -G 2>/dev/null') as idg:
groups = idg.read().strip()
@@ -1049,8 +1075,8 @@ class PosixTester(unittest.TestCase):
# Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
if sys.platform == 'darwin':
import sysconfig
dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
if tuple(int(n) for n in str(dt).split('.')[0:2]) < (10, 6):
dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.3'
if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6):
raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
# 'id -G' and 'os.getgroups()' should return the same
@@ -1060,176 +1086,6 @@ class PosixTester(unittest.TestCase):
symdiff = idg_groups.symmetric_difference(posix.getgroups())
self.assertTrue(not symdiff or symdiff == {posix.getegid()})
# tests for the posix *at functions follow
@unittest.skipUnless(os.access in os.supports_dir_fd, "test needs dir_fd support for os.access()")
def test_access_dir_fd(self):
f = posix.open(posix.getcwd(), posix.O_RDONLY)
try:
self.assertTrue(posix.access(os_helper.TESTFN, os.R_OK, dir_fd=f))
finally:
posix.close(f)
@unittest.skipUnless(os.chmod in os.supports_dir_fd, "test needs dir_fd support in os.chmod()")
def test_chmod_dir_fd(self):
os.chmod(os_helper.TESTFN, stat.S_IRUSR)
f = posix.open(posix.getcwd(), posix.O_RDONLY)
try:
posix.chmod(os_helper.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
s = posix.stat(os_helper.TESTFN)
self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
finally:
posix.close(f)
@unittest.skipUnless(os.chown in os.supports_dir_fd, "test needs dir_fd support in os.chown()")
def test_chown_dir_fd(self):
os_helper.unlink(os_helper.TESTFN)
os_helper.create_empty_file(os_helper.TESTFN)
f = posix.open(posix.getcwd(), posix.O_RDONLY)
try:
posix.chown(os_helper.TESTFN, os.getuid(), os.getgid(), dir_fd=f)
finally:
posix.close(f)
@unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()")
def test_stat_dir_fd(self):
os_helper.unlink(os_helper.TESTFN)
with open(os_helper.TESTFN, 'w') as outfile:
outfile.write("testline\n")
f = posix.open(posix.getcwd(), posix.O_RDONLY)
try:
s1 = posix.stat(os_helper.TESTFN)
s2 = posix.stat(os_helper.TESTFN, dir_fd=f)
self.assertEqual(s1, s2)
s2 = posix.stat(os_helper.TESTFN, dir_fd=None)
self.assertEqual(s1, s2)
self.assertRaisesRegex(TypeError, 'should be integer or None, not',
posix.stat, os_helper.TESTFN, dir_fd=posix.getcwd())
self.assertRaisesRegex(TypeError, 'should be integer or None, not',
posix.stat, os_helper.TESTFN, dir_fd=float(f))
self.assertRaises(OverflowError,
posix.stat, os_helper.TESTFN, dir_fd=10**20)
finally:
posix.close(f)
@unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()")
def test_utime_dir_fd(self):
f = posix.open(posix.getcwd(), posix.O_RDONLY)
try:
now = time.time()
posix.utime(os_helper.TESTFN, None, dir_fd=f)
posix.utime(os_helper.TESTFN, dir_fd=f)
self.assertRaises(TypeError, posix.utime, os_helper.TESTFN, now, dir_fd=f)
self.assertRaises(TypeError, posix.utime, os_helper.TESTFN, (None, None), dir_fd=f)
self.assertRaises(TypeError, posix.utime, os_helper.TESTFN, (now, None), dir_fd=f)
self.assertRaises(TypeError, posix.utime, os_helper.TESTFN, (None, now), dir_fd=f)
self.assertRaises(TypeError, posix.utime, os_helper.TESTFN, (now, "x"), dir_fd=f)
posix.utime(os_helper.TESTFN, (int(now), int(now)), dir_fd=f)
posix.utime(os_helper.TESTFN, (now, now), dir_fd=f)
posix.utime(os_helper.TESTFN,
(int(now), int((now - int(now)) * 1e9)), dir_fd=f)
posix.utime(os_helper.TESTFN, dir_fd=f,
times=(int(now), int((now - int(now)) * 1e9)))
# try dir_fd and follow_symlinks together
if os.utime in os.supports_follow_symlinks:
try:
posix.utime(os_helper.TESTFN, follow_symlinks=False, dir_fd=f)
except ValueError:
# whoops! using both together not supported on this platform.
pass
finally:
posix.close(f)
@unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()")
def test_link_dir_fd(self):
f = posix.open(posix.getcwd(), posix.O_RDONLY)
try:
posix.link(os_helper.TESTFN, os_helper.TESTFN + 'link', src_dir_fd=f, dst_dir_fd=f)
except PermissionError as e:
self.skipTest('posix.link(): %s' % e)
else:
# should have same inodes
self.assertEqual(posix.stat(os_helper.TESTFN)[1],
posix.stat(os_helper.TESTFN + 'link')[1])
finally:
posix.close(f)
os_helper.unlink(os_helper.TESTFN + 'link')
@unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()")
def test_mkdir_dir_fd(self):
f = posix.open(posix.getcwd(), posix.O_RDONLY)
try:
posix.mkdir(os_helper.TESTFN + 'dir', dir_fd=f)
posix.stat(os_helper.TESTFN + 'dir') # should not raise exception
finally:
posix.close(f)
os_helper.rmtree(os_helper.TESTFN + 'dir')
@unittest.skipUnless((os.mknod in os.supports_dir_fd) and hasattr(stat, 'S_IFIFO'),
"test requires both stat.S_IFIFO and dir_fd support for os.mknod()")
def test_mknod_dir_fd(self):
# Test using mknodat() to create a FIFO (the only use specified
# by POSIX).
os_helper.unlink(os_helper.TESTFN)
mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
f = posix.open(posix.getcwd(), posix.O_RDONLY)
try:
posix.mknod(os_helper.TESTFN, mode, 0, dir_fd=f)
except OSError as e:
# Some old systems don't allow unprivileged users to use
# mknod(), or only support creating device nodes.
self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
else:
self.assertTrue(stat.S_ISFIFO(posix.stat(os_helper.TESTFN).st_mode))
finally:
posix.close(f)
@unittest.skipUnless(os.open in os.supports_dir_fd, "test needs dir_fd support in os.open()")
def test_open_dir_fd(self):
os_helper.unlink(os_helper.TESTFN)
with open(os_helper.TESTFN, 'w') as outfile:
outfile.write("testline\n")
a = posix.open(posix.getcwd(), posix.O_RDONLY)
b = posix.open(os_helper.TESTFN, posix.O_RDONLY, dir_fd=a)
try:
res = posix.read(b, 9).decode(encoding="utf-8")
self.assertEqual("testline\n", res)
finally:
posix.close(a)
posix.close(b)
@unittest.skipUnless(os.readlink in os.supports_dir_fd, "test needs dir_fd support in os.readlink()")
def test_readlink_dir_fd(self):
os.symlink(os_helper.TESTFN, os_helper.TESTFN + 'link')
f = posix.open(posix.getcwd(), posix.O_RDONLY)
try:
self.assertEqual(posix.readlink(os_helper.TESTFN + 'link'),
posix.readlink(os_helper.TESTFN + 'link', dir_fd=f))
finally:
os_helper.unlink(os_helper.TESTFN + 'link')
posix.close(f)
@unittest.skipUnless(os.rename in os.supports_dir_fd, "test needs dir_fd support in os.rename()")
def test_rename_dir_fd(self):
os_helper.unlink(os_helper.TESTFN)
os_helper.create_empty_file(os_helper.TESTFN + 'ren')
f = posix.open(posix.getcwd(), posix.O_RDONLY)
try:
posix.rename(os_helper.TESTFN + 'ren', os_helper.TESTFN, src_dir_fd=f, dst_dir_fd=f)
except:
posix.rename(os_helper.TESTFN + 'ren', os_helper.TESTFN)
raise
else:
posix.stat(os_helper.TESTFN) # should not raise exception
finally:
posix.close(f)
@unittest.skipUnless(hasattr(signal, 'SIGCHLD'), 'CLD_XXXX be placed in si_code for a SIGCHLD signal')
@unittest.skipUnless(hasattr(os, 'waitid_result'), "test needs os.waitid_result")
def test_cld_xxxx_constants(self):
@@ -1240,48 +1096,6 @@ class PosixTester(unittest.TestCase):
os.CLD_STOPPED
os.CLD_CONTINUED
@unittest.skipUnless(os.symlink in os.supports_dir_fd, "test needs dir_fd support in os.symlink()")
def test_symlink_dir_fd(self):
f = posix.open(posix.getcwd(), posix.O_RDONLY)
try:
posix.symlink(os_helper.TESTFN, os_helper.TESTFN + 'link', dir_fd=f)
self.assertEqual(posix.readlink(os_helper.TESTFN + 'link'), os_helper.TESTFN)
finally:
posix.close(f)
os_helper.unlink(os_helper.TESTFN + 'link')
@unittest.skipUnless(os.unlink in os.supports_dir_fd, "test needs dir_fd support in os.unlink()")
def test_unlink_dir_fd(self):
f = posix.open(posix.getcwd(), posix.O_RDONLY)
os_helper.create_empty_file(os_helper.TESTFN + 'del')
posix.stat(os_helper.TESTFN + 'del') # should not raise exception
try:
posix.unlink(os_helper.TESTFN + 'del', dir_fd=f)
except:
os_helper.unlink(os_helper.TESTFN + 'del')
raise
else:
self.assertRaises(OSError, posix.stat, os_helper.TESTFN + 'link')
finally:
posix.close(f)
# TODO: RUSTPYTHON: AttributeError: module 'os' has no attribute 'mkfifo'
#
# @unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()")
@unittest.expectedFailure
def test_mkfifo_dir_fd(self):
os_helper.unlink(os_helper.TESTFN)
f = posix.open(posix.getcwd(), posix.O_RDONLY)
try:
try:
posix.mkfifo(os_helper.TESTFN,
stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
except PermissionError as e:
self.skipTest('posix.mkfifo(): %s' % e)
self.assertTrue(stat.S_ISFIFO(posix.stat(os_helper.TESTFN).st_mode))
finally:
posix.close(f)
requires_sched_h = unittest.skipUnless(hasattr(posix, 'sched_yield'),
"don't have scheduling support")
requires_sched_affinity = unittest.skipUnless(hasattr(posix, 'sched_setaffinity'),
@@ -1369,7 +1183,9 @@ class PosixTester(unittest.TestCase):
mask = posix.sched_getaffinity(0)
self.assertIsInstance(mask, set)
self.assertGreaterEqual(len(mask), 1)
self.assertRaises(OSError, posix.sched_getaffinity, -1)
if not sys.platform.startswith("freebsd"):
# bpo-47205: does not raise OSError on FreeBSD
self.assertRaises(OSError, posix.sched_getaffinity, -1)
for cpu in mask:
self.assertIsInstance(cpu, int)
self.assertGreaterEqual(cpu, 0)
@@ -1387,7 +1203,9 @@ class PosixTester(unittest.TestCase):
self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10])
self.assertRaises(ValueError, posix.sched_setaffinity, 0, map(int, "0X"))
self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128])
self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
if not sys.platform.startswith("freebsd"):
# bpo-47205: does not raise OSError on FreeBSD
self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
def test_rtld_constants(self):
# check presence of major RTLD_* constants
@@ -1488,6 +1306,200 @@ class PosixTester(unittest.TestCase):
self.assertEqual(cm.exception.errno, errno.EINVAL)
os.close(os.pidfd_open(os.getpid(), 0))
# tests for the posix *at functions follow
class TestPosixDirFd(unittest.TestCase):
count = 0
@contextmanager
def prepare(self):
TestPosixDirFd.count += 1
name = f'{os_helper.TESTFN}_{self.count}'
base_dir = f'{os_helper.TESTFN}_{self.count}base'
posix.mkdir(base_dir)
self.addCleanup(posix.rmdir, base_dir)
fullname = os.path.join(base_dir, name)
assert not os.path.exists(fullname)
with os_helper.open_dir_fd(base_dir) as dir_fd:
yield (dir_fd, name, fullname)
@contextmanager
def prepare_file(self):
with self.prepare() as (dir_fd, name, fullname):
os_helper.create_empty_file(fullname)
self.addCleanup(posix.unlink, fullname)
yield (dir_fd, name, fullname)
@unittest.skipUnless(os.access in os.supports_dir_fd, "test needs dir_fd support for os.access()")
def test_access_dir_fd(self):
with self.prepare_file() as (dir_fd, name, fullname):
self.assertTrue(posix.access(name, os.R_OK, dir_fd=dir_fd))
@unittest.skipUnless(os.chmod in os.supports_dir_fd, "test needs dir_fd support in os.chmod()")
def test_chmod_dir_fd(self):
with self.prepare_file() as (dir_fd, name, fullname):
posix.chmod(fullname, stat.S_IRUSR)
posix.chmod(name, stat.S_IRUSR | stat.S_IWUSR, dir_fd=dir_fd)
s = posix.stat(fullname)
self.assertEqual(s.st_mode & stat.S_IRWXU,
stat.S_IRUSR | stat.S_IWUSR)
@unittest.skipUnless(hasattr(os, 'chown') and (os.chown in os.supports_dir_fd),
"test needs dir_fd support in os.chown()")
def test_chown_dir_fd(self):
with self.prepare_file() as (dir_fd, name, fullname):
posix.chown(name, os.getuid(), os.getgid(), dir_fd=dir_fd)
@unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()")
def test_stat_dir_fd(self):
with self.prepare() as (dir_fd, name, fullname):
with open(fullname, 'w') as outfile:
outfile.write("testline\n")
self.addCleanup(posix.unlink, fullname)
s1 = posix.stat(fullname)
s2 = posix.stat(name, dir_fd=dir_fd)
self.assertEqual(s1, s2)
s2 = posix.stat(fullname, dir_fd=None)
self.assertEqual(s1, s2)
self.assertRaisesRegex(TypeError, 'should be integer or None, not',
posix.stat, name, dir_fd=posix.getcwd())
self.assertRaisesRegex(TypeError, 'should be integer or None, not',
posix.stat, name, dir_fd=float(dir_fd))
self.assertRaises(OverflowError,
posix.stat, name, dir_fd=10**20)
@unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()")
def test_utime_dir_fd(self):
with self.prepare_file() as (dir_fd, name, fullname):
now = time.time()
posix.utime(name, None, dir_fd=dir_fd)
posix.utime(name, dir_fd=dir_fd)
self.assertRaises(TypeError, posix.utime, name,
now, dir_fd=dir_fd)
self.assertRaises(TypeError, posix.utime, name,
(None, None), dir_fd=dir_fd)
self.assertRaises(TypeError, posix.utime, name,
(now, None), dir_fd=dir_fd)
self.assertRaises(TypeError, posix.utime, name,
(None, now), dir_fd=dir_fd)
self.assertRaises(TypeError, posix.utime, name,
(now, "x"), dir_fd=dir_fd)
posix.utime(name, (int(now), int(now)), dir_fd=dir_fd)
posix.utime(name, (now, now), dir_fd=dir_fd)
posix.utime(name,
(int(now), int((now - int(now)) * 1e9)), dir_fd=dir_fd)
posix.utime(name, dir_fd=dir_fd,
times=(int(now), int((now - int(now)) * 1e9)))
# try dir_fd and follow_symlinks together
if os.utime in os.supports_follow_symlinks:
try:
posix.utime(name, follow_symlinks=False, dir_fd=dir_fd)
except ValueError:
# whoops! using both together not supported on this platform.
pass
@unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()")
def test_link_dir_fd(self):
with self.prepare_file() as (dir_fd, name, fullname), \
self.prepare() as (dir_fd2, linkname, fulllinkname):
try:
posix.link(name, linkname, src_dir_fd=dir_fd, dst_dir_fd=dir_fd2)
except PermissionError as e:
self.skipTest('posix.link(): %s' % e)
self.addCleanup(posix.unlink, fulllinkname)
# should have same inodes
self.assertEqual(posix.stat(fullname)[1],
posix.stat(fulllinkname)[1])
@unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()")
def test_mkdir_dir_fd(self):
with self.prepare() as (dir_fd, name, fullname):
posix.mkdir(name, dir_fd=dir_fd)
self.addCleanup(posix.rmdir, fullname)
posix.stat(fullname) # should not raise exception
@unittest.skipUnless(hasattr(os, 'mknod')
and (os.mknod in os.supports_dir_fd)
and hasattr(stat, 'S_IFIFO'),
"test requires both stat.S_IFIFO and dir_fd support for os.mknod()")
def test_mknod_dir_fd(self):
# Test using mknodat() to create a FIFO (the only use specified
# by POSIX).
with self.prepare() as (dir_fd, name, fullname):
mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
try:
posix.mknod(name, mode, 0, dir_fd=dir_fd)
except OSError as e:
# Some old systems don't allow unprivileged users to use
# mknod(), or only support creating device nodes.
self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
else:
self.addCleanup(posix.unlink, fullname)
self.assertTrue(stat.S_ISFIFO(posix.stat(fullname).st_mode))
@unittest.skipUnless(os.open in os.supports_dir_fd, "test needs dir_fd support in os.open()")
def test_open_dir_fd(self):
with self.prepare() as (dir_fd, name, fullname):
with open(fullname, 'wb') as outfile:
outfile.write(b"testline\n")
self.addCleanup(posix.unlink, fullname)
fd = posix.open(name, posix.O_RDONLY, dir_fd=dir_fd)
try:
res = posix.read(fd, 9)
self.assertEqual(b"testline\n", res)
finally:
posix.close(fd)
@unittest.skipUnless(hasattr(os, 'readlink') and (os.readlink in os.supports_dir_fd),
"test needs dir_fd support in os.readlink()")
def test_readlink_dir_fd(self):
with self.prepare() as (dir_fd, name, fullname):
os.symlink('symlink', fullname)
self.addCleanup(posix.unlink, fullname)
self.assertEqual(posix.readlink(name, dir_fd=dir_fd), 'symlink')
@unittest.skipUnless(os.rename in os.supports_dir_fd, "test needs dir_fd support in os.rename()")
def test_rename_dir_fd(self):
with self.prepare_file() as (dir_fd, name, fullname), \
self.prepare() as (dir_fd2, name2, fullname2):
posix.rename(name, name2,
src_dir_fd=dir_fd, dst_dir_fd=dir_fd2)
posix.stat(fullname2) # should not raise exception
posix.rename(fullname2, fullname)
@unittest.skipUnless(os.symlink in os.supports_dir_fd, "test needs dir_fd support in os.symlink()")
def test_symlink_dir_fd(self):
with self.prepare() as (dir_fd, name, fullname):
posix.symlink('symlink', name, dir_fd=dir_fd)
self.addCleanup(posix.unlink, fullname)
self.assertEqual(posix.readlink(fullname), 'symlink')
@unittest.skipUnless(os.unlink in os.supports_dir_fd, "test needs dir_fd support in os.unlink()")
def test_unlink_dir_fd(self):
with self.prepare() as (dir_fd, name, fullname):
os_helper.create_empty_file(fullname)
posix.stat(fullname) # should not raise exception
try:
posix.unlink(name, dir_fd=dir_fd)
self.assertRaises(OSError, posix.stat, fullname)
except:
self.addCleanup(posix.unlink, fullname)
raise
@unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()")
def test_mkfifo_dir_fd(self):
with self.prepare() as (dir_fd, name, fullname):
try:
posix.mkfifo(name, stat.S_IRUSR | stat.S_IWUSR, dir_fd=dir_fd)
except PermissionError as e:
self.skipTest('posix.mkfifo(): %s' % e)
self.addCleanup(posix.unlink, fullname)
self.assertTrue(stat.S_ISFIFO(posix.stat(fullname).st_mode))
class PosixGroupsTester(unittest.TestCase):
def setUp(self):
@@ -1548,7 +1560,7 @@ class _PosixSpawnMixin:
args = self.python_args('-c', script)
pid = self.spawn_func(args[0], args, os.environ)
support.wait_process(pid, exitcode=0)
with open(pidfile) as f:
with open(pidfile, encoding="utf-8") as f:
self.assertEqual(f.read(), str(pid))
def test_no_such_executable(self):
@@ -1573,14 +1585,14 @@ class _PosixSpawnMixin:
self.addCleanup(os_helper.unlink, envfile)
script = f"""if 1:
import os
with open({envfile!r}, "w") as envfile:
with open({envfile!r}, "w", encoding="utf-8") as envfile:
envfile.write(os.environ['foo'])
"""
args = self.python_args('-c', script)
pid = self.spawn_func(args[0], args,
{**os.environ, 'foo': 'bar'})
support.wait_process(pid, exitcode=0)
with open(envfile) as f:
with open(envfile, encoding="utf-8") as f:
self.assertEqual(f.read(), 'bar')
def test_none_file_actions(self):
@@ -1846,7 +1858,7 @@ class _PosixSpawnMixin:
file_actions=file_actions)
support.wait_process(pid, exitcode=0)
with open(outfile) as f:
with open(outfile, encoding="utf-8") as f:
self.assertEqual(f.read(), 'hello')
# TODO: RUSTPYTHON: FileNotFoundError: [Errno 2] No such file or directory (os error 2): '@test_55144_tmp' -> 'None'
@@ -1859,7 +1871,7 @@ class _PosixSpawnMixin:
try:
os.fstat(0)
except OSError as e:
with open({closefile!r}, 'w') as closefile:
with open({closefile!r}, 'w', encoding='utf-8') as closefile:
closefile.write('is closed %d' % e.errno)
"""
args = self.python_args('-c', script)
@@ -1867,7 +1879,7 @@ class _PosixSpawnMixin:
file_actions=[(os.POSIX_SPAWN_CLOSE, 0)])
support.wait_process(pid, exitcode=0)
with open(closefile) as f:
with open(closefile, encoding="utf-8") as f:
self.assertEqual(f.read(), 'is closed %d' % errno.EBADF)
def test_dup2(self):
@@ -1885,7 +1897,7 @@ class _PosixSpawnMixin:
pid = self.spawn_func(args[0], args, os.environ,
file_actions=file_actions)
support.wait_process(pid, exitcode=0)
with open(dupfile) as f:
with open(dupfile, encoding="utf-8") as f:
self.assertEqual(f.read(), 'hello')
@@ -1931,7 +1943,6 @@ class TestPosixSpawnP(unittest.TestCase, _PosixSpawnMixin):
assert_python_ok(*args, PATH=path)
@unittest.skip("TODO: RUSTPYTHON, NameError: name 'ParserCreate' is not defined")
@unittest.skipUnless(sys.platform == "darwin", "test weak linking on macOS")
class TestPosixWeaklinking(unittest.TestCase):
# These test cases verify that weak linking support on macOS works
@@ -2159,17 +2170,9 @@ class TestPosixWeaklinking(unittest.TestCase):
os.utime("path", dir_fd=0)
def test_main():
try:
support.run_unittest(
PosixTester,
PosixGroupsTester,
TestPosixSpawn,
TestPosixSpawnP,
TestPosixWeaklinking
)
finally:
support.reap_children()
def tearDownModule():
support.reap_children()
if __name__ == '__main__':
test_main()
unittest.main()

View File

@@ -1,9 +1,11 @@
import os
import posixpath
import sys
import unittest
from posixpath import realpath, abspath, dirname, basename
from test import support, test_genericpath
from test.support import os_helper, import_helper
from test import test_genericpath
from test.support import import_helper
from test.support import os_helper
from test.support.os_helper import FakePath
from unittest import mock
@@ -269,6 +271,8 @@ class PosixPathTest(unittest.TestCase):
self.assertEqual(posixpath.expanduser("~/"), "/")
self.assertEqual(posixpath.expanduser("~/foo"), "/foo")
@unittest.skipIf(sys.platform == "vxworks",
"no home directory on VxWorks")
def test_expanduser_pwd(self):
pwd = import_helper.import_module('pwd')
@@ -359,6 +363,19 @@ class PosixPathTest(unittest.TestCase):
finally:
os_helper.unlink(ABSTFN)
@unittest.skipUnless(hasattr(os, "symlink"),
"Missing symlink implementation")
@skip_if_ABSTFN_contains_backslash
def test_realpath_strict(self):
# Bug #43757: raise FileNotFoundError in strict mode if we encounter
# a path that does not exist.
try:
os.symlink(ABSTFN+"1", ABSTFN)
self.assertRaises(FileNotFoundError, realpath, ABSTFN, strict=True)
self.assertRaises(FileNotFoundError, realpath, ABSTFN + "2", strict=True)
finally:
os_helper.unlink(ABSTFN)
@unittest.skipUnless(hasattr(os, "symlink"),
"Missing symlink implementation")
@skip_if_ABSTFN_contains_backslash
@@ -374,7 +391,7 @@ class PosixPathTest(unittest.TestCase):
@skip_if_ABSTFN_contains_backslash
def test_realpath_symlink_loops(self):
# Bug #930024, return the path unchanged if we get into an infinite
# symlink loop.
# symlink loop in non-strict mode (default).
try:
os.symlink(ABSTFN, ABSTFN)
self.assertEqual(realpath(ABSTFN), ABSTFN)
@@ -411,6 +428,48 @@ class PosixPathTest(unittest.TestCase):
os_helper.unlink(ABSTFN+"c")
os_helper.unlink(ABSTFN+"a")
@unittest.skipUnless(hasattr(os, "symlink"),
"Missing symlink implementation")
@skip_if_ABSTFN_contains_backslash
def test_realpath_symlink_loops_strict(self):
# Bug #43757, raise OSError if we get into an infinite symlink loop in
# strict mode.
try:
os.symlink(ABSTFN, ABSTFN)
self.assertRaises(OSError, realpath, ABSTFN, strict=True)
os.symlink(ABSTFN+"1", ABSTFN+"2")
os.symlink(ABSTFN+"2", ABSTFN+"1")
self.assertRaises(OSError, realpath, ABSTFN+"1", strict=True)
self.assertRaises(OSError, realpath, ABSTFN+"2", strict=True)
self.assertRaises(OSError, realpath, ABSTFN+"1/x", strict=True)
self.assertRaises(OSError, realpath, ABSTFN+"1/..", strict=True)
self.assertRaises(OSError, realpath, ABSTFN+"1/../x", strict=True)
os.symlink(ABSTFN+"x", ABSTFN+"y")
self.assertRaises(OSError, realpath,
ABSTFN+"1/../" + basename(ABSTFN) + "y", strict=True)
self.assertRaises(OSError, realpath,
ABSTFN+"1/../" + basename(ABSTFN) + "1", strict=True)
os.symlink(basename(ABSTFN) + "a/b", ABSTFN+"a")
self.assertRaises(OSError, realpath, ABSTFN+"a", strict=True)
os.symlink("../" + basename(dirname(ABSTFN)) + "/" +
basename(ABSTFN) + "c", ABSTFN+"c")
self.assertRaises(OSError, realpath, ABSTFN+"c", strict=True)
# Test using relative path as well.
with os_helper.change_cwd(dirname(ABSTFN)):
self.assertRaises(OSError, realpath, basename(ABSTFN), strict=True)
finally:
os_helper.unlink(ABSTFN)
os_helper.unlink(ABSTFN+"1")
os_helper.unlink(ABSTFN+"2")
os_helper.unlink(ABSTFN+"y")
os_helper.unlink(ABSTFN+"c")
os_helper.unlink(ABSTFN+"a")
@unittest.skipUnless(hasattr(os, "symlink"),
"Missing symlink implementation")
@skip_if_ABSTFN_contains_backslash
@@ -680,7 +739,7 @@ class PathLikeTests(unittest.TestCase):
path = posixpath
def setUp(self):
self.file_name = os_helper.TESTFN.lower()
self.file_name = os_helper.TESTFN
self.file_path = FakePath(os_helper.TESTFN)
self.addCleanup(os_helper.unlink, self.file_name)
with open(self.file_name, 'xb', 0) as file: