Skip to content

Commit 22fed60

Browse files
authored
gh-90473: Make chmod a dummy on WASI, skip chmod tests (GH-93534)
WASI does not have the ``chmod(2)`` syscall yet.
1 parent 56b5daf commit 22fed60

20 files changed

+81
-5
lines changed

Lib/test/support/os_helper.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,42 @@ def skip_unless_xattr(test):
237237
return test if ok else unittest.skip(msg)(test)
238238

239239

240+
_can_chmod = None
241+
242+
def can_chmod():
243+
global _can_chmod
244+
if _can_chmod is not None:
245+
return _can_chmod
246+
if not hasattr(os, "chown"):
247+
_can_chmod = False
248+
return _can_chmod
249+
try:
250+
with open(TESTFN, "wb") as f:
251+
try:
252+
os.chmod(TESTFN, 0o777)
253+
mode1 = os.stat(TESTFN).st_mode
254+
os.chmod(TESTFN, 0o666)
255+
mode2 = os.stat(TESTFN).st_mode
256+
except OSError as e:
257+
can = False
258+
else:
259+
can = stat.S_IMODE(mode1) != stat.S_IMODE(mode2)
260+
finally:
261+
os.unlink(TESTFN)
262+
_can_chmod = can
263+
return can
264+
265+
266+
def skip_unless_working_chmod(test):
267+
"""Skip tests that require working os.chmod()
268+
269+
WASI SDK 15.0 cannot change file mode bits.
270+
"""
271+
ok = can_chmod()
272+
msg = "requires working os.chmod()"
273+
return test if ok else unittest.skip(msg)(test)
274+
275+
240276
def unlink(filename):
241277
try:
242278
_unlink(filename)

Lib/test/test_argparse.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def setUp(self):
4545
env['COLUMNS'] = '80'
4646

4747

48+
@os_helper.skip_unless_working_chmod
4849
class TempDirMixin(object):
4950

5051
def setUp(self):

Lib/test/test_dbm_dumb.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ def test_dumbdbm_creation(self):
4242
self.read_helper(f)
4343

4444
@unittest.skipUnless(hasattr(os, 'umask'), 'test needs os.umask()')
45+
@os_helper.skip_unless_working_chmod
4546
def test_dumbdbm_creation_mode(self):
4647
try:
4748
old_umask = os.umask(0o002)
@@ -265,6 +266,7 @@ def test_invalid_flag(self):
265266
"'r', 'w', 'c', or 'n'"):
266267
dumbdbm.open(_fname, flag)
267268

269+
@os_helper.skip_unless_working_chmod
268270
def test_readonly_files(self):
269271
with os_helper.temp_dir() as dir:
270272
fname = os.path.join(dir, 'db')

Lib/test/test_import/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ def test_creation_mode(self):
557557

558558
@unittest.skipUnless(os.name == 'posix',
559559
"test meaningful only on posix systems")
560+
@os_helper.skip_unless_working_chmod
560561
def test_cached_mode_issue_2051(self):
561562
# permissions of .pyc should match those of .py, regardless of mask
562563
mode = 0o600
@@ -573,6 +574,7 @@ def test_cached_mode_issue_2051(self):
573574

574575
@unittest.skipUnless(os.name == 'posix',
575576
"test meaningful only on posix systems")
577+
@os_helper.skip_unless_working_chmod
576578
def test_cached_readonly(self):
577579
mode = 0o400
578580
with temp_umask(0o022), _ready_to_import() as (name, path):
@@ -886,6 +888,7 @@ def test_import_pyc_path(self):
886888
@unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0,
887889
"due to varying filesystem permission semantics (issue #11956)")
888890
@skip_if_dont_write_bytecode
891+
@os_helper.skip_unless_working_chmod
889892
def test_unwritable_directory(self):
890893
# When the umask causes the new __pycache__ directory to be
891894
# unwritable, the import still succeeds but no .pyc file is written.

Lib/test/test_netrc.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ def test_comment_at_end_of_machine_line_pass_has_hash(self):
272272

273273
@unittest.skipUnless(os.name == 'posix', 'POSIX only test')
274274
@unittest.skipIf(pwd is None, 'security check requires pwd module')
275+
@os_helper.skip_unless_working_chmod
275276
def test_security(self):
276277
# This test is incomplete since we are normally not run as root and
277278
# therefore can't test the file ownership being wrong.

Lib/test/test_os.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,7 +1670,7 @@ def tearDown(self):
16701670
os.removedirs(path)
16711671

16721672

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

16761676
@classmethod
@@ -3784,7 +3784,6 @@ class Str(str):
37843784
def test_oserror_filename(self):
37853785
funcs = [
37863786
(self.filenames, os.chdir,),
3787-
(self.filenames, os.chmod, 0o777),
37883787
(self.filenames, os.lstat,),
37893788
(self.filenames, os.open, os.O_RDONLY),
37903789
(self.filenames, os.rmdir,),
@@ -3805,6 +3804,8 @@ def test_oserror_filename(self):
38053804
(self.filenames, os.rename, "dst"),
38063805
(self.filenames, os.replace, "dst"),
38073806
))
3807+
if os_helper.can_chmod():
3808+
funcs.append((self.filenames, os.chmod, 0o777))
38083809
if hasattr(os, "chown"):
38093810
funcs.append((self.filenames, os.chown, 0, 0))
38103811
if hasattr(os, "lchown"):

Lib/test/test_pathlib.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1902,6 +1902,7 @@ def test_with(self):
19021902
with p:
19031903
pass
19041904

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

19171918
# On Windows, os.chmod does not follow symlinks (issue #15411)
19181919
@only_posix
1920+
@os_helper.skip_unless_working_chmod
19191921
def test_chmod_follow_symlinks_true(self):
19201922
p = self.cls(BASE) / 'linkA'
19211923
q = p.resolve()
@@ -1931,6 +1933,7 @@ def test_chmod_follow_symlinks_true(self):
19311933

19321934
# XXX also need a test for lchmod.
19331935

1936+
@os_helper.skip_unless_working_chmod
19341937
def test_stat(self):
19351938
p = self.cls(BASE) / 'fileA'
19361939
st = p.stat()

Lib/test/test_posix.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,7 @@ def check_stat(uid, gid):
786786
self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
787787
check_stat(uid, gid)
788788

789-
@unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
789+
@os_helper.skip_unless_working_chmod
790790
def test_chown(self):
791791
# raise an OSError if the file does not exist
792792
os.unlink(os_helper.TESTFN)
@@ -796,6 +796,7 @@ def test_chown(self):
796796
os_helper.create_empty_file(os_helper.TESTFN)
797797
self._test_all_chown_common(posix.chown, os_helper.TESTFN, posix.stat)
798798

799+
@os_helper.skip_unless_working_chmod
799800
@unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
800801
def test_fchown(self):
801802
os.unlink(os_helper.TESTFN)
@@ -809,6 +810,7 @@ def test_fchown(self):
809810
finally:
810811
test_file.close()
811812

813+
@os_helper.skip_unless_working_chmod
812814
@unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
813815
def test_lchown(self):
814816
os.unlink(os_helper.TESTFN)

Lib/test/test_posixpath.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,7 @@ def test_ismount_non_existent(self):
193193
self.assertIs(posixpath.ismount('/\x00'), False)
194194
self.assertIs(posixpath.ismount(b'/\x00'), False)
195195

196-
@unittest.skipUnless(os_helper.can_symlink(),
197-
"Test requires symlink support")
196+
@os_helper.skip_unless_symlink
198197
def test_ismount_symlinks(self):
199198
# Symlinks are never mountpoints.
200199
try:

Lib/test/test_py_compile.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ def test_relative_path(self):
119119
'non-root user required')
120120
@unittest.skipIf(os.name == 'nt',
121121
'cannot control directory permissions on Windows')
122+
@os_helper.skip_unless_working_chmod
122123
def test_exceptions_propagate(self):
123124
# Make sure that exceptions raised thanks to issues with writing
124125
# bytecode.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy