Skip to content

Commit 6f8367d

Browse files
authored
gh-90473: wasmtime does not support absolute symlinks (GH-93490)
1 parent 713eb18 commit 6f8367d

5 files changed

+20
-23
lines changed

Lib/test/support/os_helper.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,13 @@ def can_symlink():
171171
global _can_symlink
172172
if _can_symlink is not None:
173173
return _can_symlink
174-
symlink_path = TESTFN + "can_symlink"
174+
# WASI / wasmtime prevents symlinks with absolute paths, see man
175+
# openat2(2) RESOLVE_BENEATH. Almost all symlink tests use absolute
176+
# paths. Skip symlink tests on WASI for now.
177+
src = os.path.abspath(TESTFN)
178+
symlink_path = src + "can_symlink"
175179
try:
176-
os.symlink(TESTFN, symlink_path)
180+
os.symlink(src, symlink_path)
177181
can = True
178182
except (OSError, NotImplementedError, AttributeError):
179183
can = False

Lib/test/test_posixpath.py

+10-20
Original file line numberDiff line numberDiff line change
@@ -387,8 +387,7 @@ def test_realpath_pardir(self):
387387
self.assertEqual(realpath(b'../..'), dirname(dirname(os.getcwdb())))
388388
self.assertEqual(realpath(b'/'.join([b'..'] * 100)), b'/')
389389

390-
@unittest.skipUnless(hasattr(os, "symlink"),
391-
"Missing symlink implementation")
390+
@os_helper.skip_unless_symlink
392391
@skip_if_ABSTFN_contains_backslash
393392
def test_realpath_basic(self):
394393
# Basic operation.
@@ -398,8 +397,7 @@ def test_realpath_basic(self):
398397
finally:
399398
os_helper.unlink(ABSTFN)
400399

401-
@unittest.skipUnless(hasattr(os, "symlink"),
402-
"Missing symlink implementation")
400+
@os_helper.skip_unless_symlink
403401
@skip_if_ABSTFN_contains_backslash
404402
def test_realpath_strict(self):
405403
# Bug #43757: raise FileNotFoundError in strict mode if we encounter
@@ -411,8 +409,7 @@ def test_realpath_strict(self):
411409
finally:
412410
os_helper.unlink(ABSTFN)
413411

414-
@unittest.skipUnless(hasattr(os, "symlink"),
415-
"Missing symlink implementation")
412+
@os_helper.skip_unless_symlink
416413
@skip_if_ABSTFN_contains_backslash
417414
def test_realpath_relative(self):
418415
try:
@@ -421,8 +418,7 @@ def test_realpath_relative(self):
421418
finally:
422419
os_helper.unlink(ABSTFN)
423420

424-
@unittest.skipUnless(hasattr(os, "symlink"),
425-
"Missing symlink implementation")
421+
@os_helper.skip_unless_symlink
426422
@skip_if_ABSTFN_contains_backslash
427423
def test_realpath_symlink_loops(self):
428424
# Bug #930024, return the path unchanged if we get into an infinite
@@ -463,8 +459,7 @@ def test_realpath_symlink_loops(self):
463459
os_helper.unlink(ABSTFN+"c")
464460
os_helper.unlink(ABSTFN+"a")
465461

466-
@unittest.skipUnless(hasattr(os, "symlink"),
467-
"Missing symlink implementation")
462+
@os_helper.skip_unless_symlink
468463
@skip_if_ABSTFN_contains_backslash
469464
def test_realpath_symlink_loops_strict(self):
470465
# Bug #43757, raise OSError if we get into an infinite symlink loop in
@@ -505,8 +500,7 @@ def test_realpath_symlink_loops_strict(self):
505500
os_helper.unlink(ABSTFN+"c")
506501
os_helper.unlink(ABSTFN+"a")
507502

508-
@unittest.skipUnless(hasattr(os, "symlink"),
509-
"Missing symlink implementation")
503+
@os_helper.skip_unless_symlink
510504
@skip_if_ABSTFN_contains_backslash
511505
def test_realpath_repeated_indirect_symlinks(self):
512506
# Issue #6975.
@@ -520,8 +514,7 @@ def test_realpath_repeated_indirect_symlinks(self):
520514
os_helper.unlink(ABSTFN + '/link')
521515
safe_rmdir(ABSTFN)
522516

523-
@unittest.skipUnless(hasattr(os, "symlink"),
524-
"Missing symlink implementation")
517+
@os_helper.skip_unless_symlink
525518
@skip_if_ABSTFN_contains_backslash
526519
def test_realpath_deep_recursion(self):
527520
depth = 10
@@ -540,8 +533,7 @@ def test_realpath_deep_recursion(self):
540533
os_helper.unlink(ABSTFN + '/%d' % i)
541534
safe_rmdir(ABSTFN)
542535

543-
@unittest.skipUnless(hasattr(os, "symlink"),
544-
"Missing symlink implementation")
536+
@os_helper.skip_unless_symlink
545537
@skip_if_ABSTFN_contains_backslash
546538
def test_realpath_resolve_parents(self):
547539
# We also need to resolve any symlinks in the parents of a relative
@@ -560,8 +552,7 @@ def test_realpath_resolve_parents(self):
560552
safe_rmdir(ABSTFN + "/y")
561553
safe_rmdir(ABSTFN)
562554

563-
@unittest.skipUnless(hasattr(os, "symlink"),
564-
"Missing symlink implementation")
555+
@os_helper.skip_unless_symlink
565556
@skip_if_ABSTFN_contains_backslash
566557
def test_realpath_resolve_before_normalizing(self):
567558
# Bug #990669: Symbolic links should be resolved before we
@@ -589,8 +580,7 @@ def test_realpath_resolve_before_normalizing(self):
589580
safe_rmdir(ABSTFN + "/k")
590581
safe_rmdir(ABSTFN)
591582

592-
@unittest.skipUnless(hasattr(os, "symlink"),
593-
"Missing symlink implementation")
583+
@os_helper.skip_unless_symlink
594584
@skip_if_ABSTFN_contains_backslash
595585
def test_realpath_resolve_first(self):
596586
# Bug #1213894: The first component of the path, if not absolute,

Lib/test/test_stat.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ def test_directory(self):
161161
else:
162162
self.assertEqual(modestr[0], 'd')
163163

164-
@unittest.skipUnless(hasattr(os, 'symlink'), 'os.symlink not available')
164+
@os_helper.skip_unless_symlink
165165
def test_link(self):
166166
try:
167167
os.symlink(os.getcwd(), TESTFN)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Skip symlink tests on WASI. wasmtime uses ``openat2(2)`` with
2+
``RESOLVE_BENEATH`` flag, which prevents symlinks with absolute paths.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Skip tests on WASI that require symlinks with absolute paths.

0 commit comments

Comments
 (0)