WASI does not have the ``chmod(2)`` syscall yet.
return test if ok else unittest.skip(msg)(test)
+_can_chmod = None
+
+def can_chmod():
+ global _can_chmod
+ if _can_chmod is not None:
+ return _can_chmod
+ if not hasattr(os, "chown"):
+ _can_chmod = False
+ return _can_chmod
+ try:
+ with open(TESTFN, "wb") as f:
+ try:
+ os.chmod(TESTFN, 0o777)
+ mode1 = os.stat(TESTFN).st_mode
+ os.chmod(TESTFN, 0o666)
+ mode2 = os.stat(TESTFN).st_mode
+ except OSError as e:
+ can = False
+ else:
+ can = stat.S_IMODE(mode1) != stat.S_IMODE(mode2)
+ finally:
+ os.unlink(TESTFN)
+ _can_chmod = can
+ return can
+
+
+def skip_unless_working_chmod(test):
+ """Skip tests that require working os.chmod()
+
+ WASI SDK 15.0 cannot change file mode bits.
+ """
+ ok = can_chmod()
+ msg = "requires working os.chmod()"
+ return test if ok else unittest.skip(msg)(test)
+
+
def unlink(filename):
try:
_unlink(filename)
env['COLUMNS'] = '80'
+@os_helper.skip_unless_working_chmod
class TempDirMixin(object):
def setUp(self):
self.read_helper(f)
@unittest.skipUnless(hasattr(os, 'umask'), 'test needs os.umask()')
+ @os_helper.skip_unless_working_chmod
def test_dumbdbm_creation_mode(self):
try:
old_umask = os.umask(0o002)
"'r', 'w', 'c', or 'n'"):
dumbdbm.open(_fname, flag)
+ @os_helper.skip_unless_working_chmod
def test_readonly_files(self):
with os_helper.temp_dir() as dir:
fname = os.path.join(dir, 'db')
@unittest.skipUnless(os.name == 'posix',
"test meaningful only on posix systems")
+ @os_helper.skip_unless_working_chmod
def test_cached_mode_issue_2051(self):
# permissions of .pyc should match those of .py, regardless of mask
mode = 0o600
@unittest.skipUnless(os.name == 'posix',
"test meaningful only on posix systems")
+ @os_helper.skip_unless_working_chmod
def test_cached_readonly(self):
mode = 0o400
with temp_umask(0o022), _ready_to_import() as (name, path):
@unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0,
"due to varying filesystem permission semantics (issue #11956)")
@skip_if_dont_write_bytecode
+ @os_helper.skip_unless_working_chmod
def test_unwritable_directory(self):
# When the umask causes the new __pycache__ directory to be
# unwritable, the import still succeeds but no .pyc file is written.
@unittest.skipUnless(os.name == 'posix', 'POSIX only test')
@unittest.skipIf(pwd is None, 'security check requires pwd module')
+ @os_helper.skip_unless_working_chmod
def test_security(self):
# This test is incomplete since we are normally not run as root and
# therefore can't test the file ownership being wrong.
os.removedirs(path)
-@unittest.skipUnless(hasattr(os, 'chown'), "Test needs chown")
+@os_helper.skip_unless_working_chmod
class ChownFileTests(unittest.TestCase):
@classmethod
def test_oserror_filename(self):
funcs = [
(self.filenames, os.chdir,),
- (self.filenames, os.chmod, 0o777),
(self.filenames, os.lstat,),
(self.filenames, os.open, os.O_RDONLY),
(self.filenames, os.rmdir,),
(self.filenames, os.rename, "dst"),
(self.filenames, os.replace, "dst"),
))
+ if os_helper.can_chmod():
+ funcs.append((self.filenames, os.chmod, 0o777))
if hasattr(os, "chown"):
funcs.append((self.filenames, os.chown, 0, 0))
if hasattr(os, "lchown"):
with p:
pass
+ @os_helper.skip_unless_working_chmod
def test_chmod(self):
p = self.cls(BASE) / 'fileA'
mode = p.stat().st_mode
# On Windows, os.chmod does not follow symlinks (issue #15411)
@only_posix
+ @os_helper.skip_unless_working_chmod
def test_chmod_follow_symlinks_true(self):
p = self.cls(BASE) / 'linkA'
q = p.resolve()
# XXX also need a test for lchmod.
+ @os_helper.skip_unless_working_chmod
def test_stat(self):
p = self.cls(BASE) / 'fileA'
st = p.stat()
self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
check_stat(uid, gid)
- @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
+ @os_helper.skip_unless_working_chmod
def test_chown(self):
# raise an OSError if the file does not exist
os.unlink(os_helper.TESTFN)
os_helper.create_empty_file(os_helper.TESTFN)
self._test_all_chown_common(posix.chown, os_helper.TESTFN, posix.stat)
+ @os_helper.skip_unless_working_chmod
@unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
def test_fchown(self):
os.unlink(os_helper.TESTFN)
finally:
test_file.close()
+ @os_helper.skip_unless_working_chmod
@unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
def test_lchown(self):
os.unlink(os_helper.TESTFN)
self.assertIs(posixpath.ismount('/\x00'), False)
self.assertIs(posixpath.ismount(b'/\x00'), False)
- @unittest.skipUnless(os_helper.can_symlink(),
- "Test requires symlink support")
+ @os_helper.skip_unless_symlink
def test_ismount_symlinks(self):
# Symlinks are never mountpoints.
try:
'non-root user required')
@unittest.skipIf(os.name == 'nt',
'cannot control directory permissions on Windows')
+ @os_helper.skip_unless_working_chmod
def test_exceptions_propagate(self):
# Make sure that exceptions raised thanks to issues with writing
# bytecode.
self.assertEqual(out.getvalue(), '')
self.assertEqual(err.getvalue(), '')
+ @os_helper.skip_unless_working_chmod
def test_apropos_empty_doc(self):
pkgdir = os.path.join(TESTFN, 'walkpkg')
os.mkdir(pkgdir)
"This test can't be run on Cygwin (issue #1071513).")
@unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0,
"This test can't be run reliably as root (issue #1076467).")
+ @os_helper.skip_unless_working_chmod
def test_on_error(self):
self.errorState = 0
os.mkdir(TESTFN)
else:
self.assertFalse(func(mode))
+ @os_helper.skip_unless_working_chmod
def test_mode(self):
with open(TESTFN, 'w'):
pass
self.assertEqual(self.statmod.S_IFMT(st_mode),
self.statmod.S_IFREG)
+ @os_helper.skip_unless_working_chmod
def test_directory(self):
os.mkdir(TESTFN)
os.chmod(TESTFN, 0o700)
data = f.read()
self.assertEqual(sha256sum(data), sha256_regtype)
+ @os_helper.skip_unless_working_chmod
def test_extractall(self):
# Test if extractall() correctly restores directory permissions
# and times (see issue1735).
tar.close()
os_helper.rmtree(DIR)
+ @os_helper.skip_unless_working_chmod
def test_extract_directory(self):
dirtype = "ustar/dirtype"
DIR = os.path.join(TEMPDIR, "extractdir")
support.gc_collect() # For PyPy or other GCs.
os.rmdir(dir)
+ @os_helper.skip_unless_working_chmod
def test_file_mode(self):
# _mkstemp_inner creates files with the proper mode
finally:
os.rmdir(dir)
+ @os_helper.skip_unless_working_chmod
def test_mode(self):
# mkdtemp creates directories with the proper mode
with self.assertRaises(TypeError):
uu.encode(inp, out, "t1", 0o644, True)
+ @os_helper.skip_unless_working_chmod
def test_decode(self):
for backtick in True, False:
inp = io.BytesIO(encodedtextwrapped(0o666, "t1", backtick=backtick))
s = fout.read()
self.assertEqual(s, encodedtextwrapped(0o644, self.tmpin))
+ # decode() calls chmod()
+ @os_helper.skip_unless_working_chmod
def test_decode(self):
with open(self.tmpin, 'wb') as f:
f.write(encodedtextwrapped(0o644, self.tmpout))
self.assertEqual(s, plaintext)
# XXX is there an xp way to verify the mode?
+ @os_helper.skip_unless_working_chmod
def test_decode_filename(self):
with open(self.tmpin, 'wb') as f:
f.write(encodedtextwrapped(0o644, self.tmpout))
s = f.read()
self.assertEqual(s, plaintext)
+ @os_helper.skip_unless_working_chmod
def test_decodetwice(self):
# Verify that decode() will refuse to overwrite an existing file
with open(self.tmpin, 'wb') as f:
with open(self.tmpin, 'rb') as f:
self.assertRaises(uu.Error, uu.decode, f)
+ @os_helper.skip_unless_working_chmod
def test_decode_mode(self):
# Verify that decode() will set the given mode for the out_file
expected_mode = 0o444
import zipapp
import zipfile
from test.support import requires_zlib
+from test.support import os_helper
from unittest.mock import patch
# (Unix only) tests that archives with shebang lines are made executable
@unittest.skipIf(sys.platform == 'win32',
'Windows does not support an executable bit')
+ @os_helper.skip_unless_working_chmod
def test_shebang_is_executable(self):
# Test that an archive with a shebang line is made executable.
source = self.tmpdir / 'source'
--- /dev/null
+WASI does not have a ``chmod(2)`` syscall. :func:`os.chmod` is now a dummy
+function on WASI. Skip all tests that depend on working :func:`os.chmod`.
{
#ifdef HAVE_CHMOD
result = chmod(path->narrow, mode);
+#elif defined(__wasi__)
+ // WASI SDK 15.0 does not support chmod.
+ // Ignore missing syscall for now.
+ result = 0;
#else
result = -1;
errno = ENOSYS;
# WASIX stubs we don't want to use.
ac_cv_func_kill=no
+# WASI SDK 15.0 does not have chmod.
+# Ignore WASIX stubs for now.
+ac_cv_func_chmod=no
+ac_cv_func_fchmod=no
+
# WASI sockets are limited to operations on given socket fd and inet sockets.
# Disable AF_UNIX and AF_PACKET support, see socketmodule.h.
ac_cv_header_sys_un_h=no