X Tutup
The Wayback Machine - https://web.archive.org/web/20221223204053/https://github.com/python/cpython/pull/93534/files
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-90473: Make chmod a dummy on WASI, skip chmod tests #93534

Merged
merged 1 commit into from Jun 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -237,6 +237,42 @@ def skip_unless_xattr(test):
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)
@@ -45,6 +45,7 @@ def setUp(self):
env['COLUMNS'] = '80'


@os_helper.skip_unless_working_chmod
ambv marked this conversation as resolved.
Show resolved Hide resolved
class TempDirMixin(object):

def setUp(self):
@@ -42,6 +42,7 @@ def test_dumbdbm_creation(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)
@@ -265,6 +266,7 @@ def test_invalid_flag(self):
"'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')
@@ -557,6 +557,7 @@ def test_creation_mode(self):

@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
@@ -573,6 +574,7 @@ def test_cached_mode_issue_2051(self):

@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):
@@ -886,6 +888,7 @@ def test_import_pyc_path(self):
@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.
@@ -272,6 +272,7 @@ def test_comment_at_end_of_machine_line_pass_has_hash(self):

@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.
@@ -1670,7 +1670,7 @@ def tearDown(self):
os.removedirs(path)


@unittest.skipUnless(hasattr(os, 'chown'), "Test needs chown")
@os_helper.skip_unless_working_chmod
class ChownFileTests(unittest.TestCase):

@classmethod
@@ -3784,7 +3784,6 @@ class Str(str):
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,),
@@ -3805,6 +3804,8 @@ def test_oserror_filename(self):
(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"):
@@ -1902,6 +1902,7 @@ def test_with(self):
with p:
pass

@os_helper.skip_unless_working_chmod
def test_chmod(self):
p = self.cls(BASE) / 'fileA'
mode = p.stat().st_mode
@@ -1916,6 +1917,7 @@ def test_chmod(self):

# 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()
@@ -1931,6 +1933,7 @@ def test_chmod_follow_symlinks_true(self):

# 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()
@@ -784,7 +784,7 @@ def check_stat(uid, gid):
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)
@@ -794,6 +794,7 @@ def test_chown(self):
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)
@@ -807,6 +808,7 @@ def test_fchown(self):
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)
@@ -193,8 +193,7 @@ def test_ismount_non_existent(self):
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:
@@ -119,6 +119,7 @@ def test_relative_path(self):
'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.
@@ -933,6 +933,7 @@ def test_apropos_with_unreadable_dir(self):
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)
@@ -311,6 +311,7 @@ def onerror(*args):
"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)
@@ -113,6 +113,7 @@ def assertS_IS(self, name, mode):
else:
self.assertFalse(func(mode))

@os_helper.skip_unless_working_chmod
def test_mode(self):
with open(TESTFN, 'w'):
pass
@@ -151,6 +152,7 @@ def test_mode(self):
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)
@@ -630,6 +630,7 @@ def test_extract_hardlink(self):
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).
@@ -660,6 +661,7 @@ def format_mtime(mtime):
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")
@@ -450,6 +450,7 @@ def test_choose_directory(self):
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

@@ -787,6 +788,7 @@ def test_choose_directory(self):
finally:
os.rmdir(dir)

@os_helper.skip_unless_working_chmod
def test_mode(self):
# mkdtemp creates directories with the proper mode

@@ -74,6 +74,7 @@ def test_encode(self):
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))
@@ -199,6 +200,8 @@ def test_encode(self):
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))
@@ -211,6 +214,7 @@ def test_decode(self):
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))
@@ -221,6 +225,7 @@ def test_decode_filename(self):
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:
@@ -231,6 +236,7 @@ def test_decodetwice(self):
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
@@ -9,6 +9,7 @@
import zipapp
import zipfile
from test.support import requires_zlib
from test.support import os_helper

from unittest.mock import patch

@@ -317,6 +318,7 @@ def test_content_of_copied_archive(self):
# (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'
@@ -0,0 +1,2 @@
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`.
@@ -3282,6 +3282,10 @@ os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
{
#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;
@@ -35,6 +35,11 @@ ac_cv_func_fdopendir=no
# 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
X Tutup