@@ -1573,6 +1573,7 @@ class PathTest(unittest.TestCase):
1573
1573
"""Tests for the FS-accessing functionalities of the Path classes."""
1574
1574
1575
1575
cls = pathlib .Path
1576
+ can_symlink = os_helper .can_symlink ()
1576
1577
1577
1578
# (BASE)
1578
1579
# |
@@ -1616,7 +1617,7 @@ def cleanup():
1616
1617
with open (join ('dirC' , 'dirD' , 'fileD' ), 'wb' ) as f :
1617
1618
f .write (b"this is file D\n " )
1618
1619
os .chmod (join ('dirE' ), 0 )
1619
- if os_helper .can_symlink () :
1620
+ if self .can_symlink :
1620
1621
# Relative symlinks.
1621
1622
os .symlink ('fileA' , join ('linkA' ))
1622
1623
os .symlink ('non-existing' , join ('brokenLink' ))
@@ -1672,7 +1673,7 @@ def test_exists(self):
1672
1673
self .assertIs (True , (p / 'dirA' ).exists ())
1673
1674
self .assertIs (True , (p / 'fileA' ).exists ())
1674
1675
self .assertIs (False , (p / 'fileA' / 'bah' ).exists ())
1675
- if os_helper .can_symlink () :
1676
+ if self .can_symlink :
1676
1677
self .assertIs (True , (p / 'linkA' ).exists ())
1677
1678
self .assertIs (True , (p / 'linkB' ).exists ())
1678
1679
self .assertIs (True , (p / 'linkB' / 'fileB' ).exists ())
@@ -1739,12 +1740,13 @@ def test_iterdir(self):
1739
1740
it = p .iterdir ()
1740
1741
paths = set (it )
1741
1742
expected = ['dirA' , 'dirB' , 'dirC' , 'dirE' , 'fileA' ]
1742
- if os_helper .can_symlink () :
1743
+ if self .can_symlink :
1743
1744
expected += ['linkA' , 'linkB' , 'brokenLink' , 'brokenLinkLoop' ]
1744
1745
self .assertEqual (paths , { P (BASE , q ) for q in expected })
1745
1746
1746
- @os_helper .skip_unless_symlink
1747
1747
def test_iterdir_symlink (self ):
1748
+ if not self .can_symlink :
1749
+ self .skipTest ("symlinks required" )
1748
1750
# __iter__ on a symlink to a directory.
1749
1751
P = self .cls
1750
1752
p = P (BASE , 'linkB' )
@@ -1772,23 +1774,23 @@ def _check(glob, expected):
1772
1774
_check (it , ["fileA" ])
1773
1775
_check (p .glob ("fileB" ), [])
1774
1776
_check (p .glob ("dir*/file*" ), ["dirB/fileB" , "dirC/fileC" ])
1775
- if not os_helper .can_symlink () :
1777
+ if not self .can_symlink :
1776
1778
_check (p .glob ("*A" ), ['dirA' , 'fileA' ])
1777
1779
else :
1778
1780
_check (p .glob ("*A" ), ['dirA' , 'fileA' , 'linkA' ])
1779
- if not os_helper .can_symlink () :
1781
+ if not self .can_symlink :
1780
1782
_check (p .glob ("*B/*" ), ['dirB/fileB' ])
1781
1783
else :
1782
1784
_check (p .glob ("*B/*" ), ['dirB/fileB' , 'dirB/linkD' ,
1783
1785
'linkB/fileB' , 'linkB/linkD' ])
1784
- if not os_helper .can_symlink () :
1786
+ if not self .can_symlink :
1785
1787
_check (p .glob ("*/fileB" ), ['dirB/fileB' ])
1786
1788
else :
1787
1789
_check (p .glob ("*/fileB" ), ['dirB/fileB' , 'linkB/fileB' ])
1788
- if os_helper .can_symlink () :
1790
+ if self .can_symlink :
1789
1791
_check (p .glob ("brokenLink" ), ['brokenLink' ])
1790
1792
1791
- if not os_helper .can_symlink () :
1793
+ if not self .can_symlink :
1792
1794
_check (p .glob ("*/" ), ["dirA" , "dirB" , "dirC" , "dirE" ])
1793
1795
else :
1794
1796
_check (p .glob ("*/" ), ["dirA" , "dirB" , "dirC" , "dirE" , "linkB" ])
@@ -1810,8 +1812,9 @@ def _check(path, pattern, case_sensitive, expected):
1810
1812
_check (path , "dirb/file*" , True , [])
1811
1813
_check (path , "dirb/file*" , False , ["dirB/fileB" ])
1812
1814
1813
- @os_helper .skip_unless_symlink
1814
1815
def test_glob_follow_symlinks_common (self ):
1816
+ if not self .can_symlink :
1817
+ self .skipTest ("symlinks required" )
1815
1818
def _check (path , glob , expected ):
1816
1819
actual = {path for path in path .glob (glob , follow_symlinks = True )
1817
1820
if "linkD" not in path .parent .parts } # exclude symlink loop.
@@ -1835,8 +1838,9 @@ def _check(path, glob, expected):
1835
1838
_check (p , "dir*/*/../dirD/**/" , ["dirC/dirD/../dirD" ])
1836
1839
_check (p , "*/dirD/**/" , ["dirC/dirD" ])
1837
1840
1838
- @os_helper .skip_unless_symlink
1839
1841
def test_glob_no_follow_symlinks_common (self ):
1842
+ if not self .can_symlink :
1843
+ self .skipTest ("symlinks required" )
1840
1844
def _check (path , glob , expected ):
1841
1845
actual = {path for path in path .glob (glob , follow_symlinks = False )}
1842
1846
self .assertEqual (actual , { P (BASE , q ) for q in expected })
@@ -1868,14 +1872,14 @@ def _check(glob, expected):
1868
1872
_check (p .rglob ("fileB" ), ["dirB/fileB" ])
1869
1873
_check (p .rglob ("**/fileB" ), ["dirB/fileB" ])
1870
1874
_check (p .rglob ("*/fileA" ), [])
1871
- if not os_helper .can_symlink () :
1875
+ if not self .can_symlink :
1872
1876
_check (p .rglob ("*/fileB" ), ["dirB/fileB" ])
1873
1877
else :
1874
1878
_check (p .rglob ("*/fileB" ), ["dirB/fileB" , "dirB/linkD/fileB" ,
1875
1879
"linkB/fileB" , "dirA/linkC/fileB" ])
1876
1880
_check (p .rglob ("file*" ), ["fileA" , "dirB/fileB" ,
1877
1881
"dirC/fileC" , "dirC/dirD/fileD" ])
1878
- if not os_helper .can_symlink () :
1882
+ if not self .can_symlink :
1879
1883
_check (p .rglob ("*/" ), [
1880
1884
"dirA" , "dirB" , "dirC" , "dirC/dirD" , "dirE" ,
1881
1885
])
@@ -1900,8 +1904,9 @@ def _check(glob, expected):
1900
1904
_check (p .rglob ("*.txt" ), ["dirC/novel.txt" ])
1901
1905
_check (p .rglob ("*.*" ), ["dirC/novel.txt" ])
1902
1906
1903
- @os_helper .skip_unless_symlink
1904
1907
def test_rglob_follow_symlinks_common (self ):
1908
+ if not self .can_symlink :
1909
+ self .skipTest ("symlinks required" )
1905
1910
def _check (path , glob , expected ):
1906
1911
actual = {path for path in path .rglob (glob , follow_symlinks = True )
1907
1912
if 'linkD' not in path .parent .parts } # exclude symlink loop.
@@ -1929,8 +1934,9 @@ def _check(path, glob, expected):
1929
1934
_check (p , "*.txt" , ["dirC/novel.txt" ])
1930
1935
_check (p , "*.*" , ["dirC/novel.txt" ])
1931
1936
1932
- @os_helper .skip_unless_symlink
1933
1937
def test_rglob_no_follow_symlinks_common (self ):
1938
+ if not self .can_symlink :
1939
+ self .skipTest ("symlinks required" )
1934
1940
def _check (path , glob , expected ):
1935
1941
actual = {path for path in path .rglob (glob , follow_symlinks = False )}
1936
1942
self .assertEqual (actual , { P (BASE , q ) for q in expected })
@@ -1954,9 +1960,10 @@ def _check(path, glob, expected):
1954
1960
_check (p , "*.txt" , ["dirC/novel.txt" ])
1955
1961
_check (p , "*.*" , ["dirC/novel.txt" ])
1956
1962
1957
- @os_helper .skip_unless_symlink
1958
1963
def test_rglob_symlink_loop (self ):
1959
1964
# Don't get fooled by symlink loops (Issue #26012).
1965
+ if not self .can_symlink :
1966
+ self .skipTest ("symlinks required" )
1960
1967
P = self .cls
1961
1968
p = P (BASE )
1962
1969
given = set (p .rglob ('*' ))
@@ -2003,9 +2010,10 @@ def test_glob_dotdot(self):
2003
2010
self .assertEqual (set (p .glob ("xyzzy/.." )), set ())
2004
2011
self .assertEqual (set (p .glob ("/" .join ([".." ] * 50 ))), { P (BASE , * [".." ] * 50 )})
2005
2012
2006
- @os_helper .skip_unless_symlink
2007
2013
def test_glob_permissions (self ):
2008
2014
# See bpo-38894
2015
+ if not self .can_symlink :
2016
+ self .skipTest ("symlinks required" )
2009
2017
P = self .cls
2010
2018
base = P (BASE ) / 'permissions'
2011
2019
base .mkdir ()
@@ -2023,9 +2031,10 @@ def test_glob_permissions(self):
2023
2031
self .assertEqual (len (set (base .glob ("*/fileC" ))), 50 )
2024
2032
self .assertEqual (len (set (base .glob ("*/file*" ))), 50 )
2025
2033
2026
- @os_helper .skip_unless_symlink
2027
2034
def test_glob_long_symlink (self ):
2028
2035
# See gh-87695
2036
+ if not self .can_symlink :
2037
+ self .skipTest ("symlinks required" )
2029
2038
base = self .cls (BASE ) / 'long_symlink'
2030
2039
base .mkdir ()
2031
2040
bad_link = base / 'bad_link'
@@ -2043,8 +2052,9 @@ def test_glob_above_recursion_limit(self):
2043
2052
with set_recursion_limit (recursion_limit ):
2044
2053
list (base .glob ('**' ))
2045
2054
2046
- @os_helper .skip_unless_symlink
2047
2055
def test_readlink (self ):
2056
+ if not self .can_symlink :
2057
+ self .skipTest ("symlinks required" )
2048
2058
P = self .cls (BASE )
2049
2059
self .assertEqual ((P / 'linkA' ).readlink (), self .cls ('fileA' ))
2050
2060
self .assertEqual ((P / 'brokenLink' ).readlink (),
@@ -2067,8 +2077,9 @@ def _check_resolve(self, p, expected, strict=True):
2067
2077
# This can be used to check both relative and absolute resolutions.
2068
2078
_check_resolve_relative = _check_resolve_absolute = _check_resolve
2069
2079
2070
- @os_helper .skip_unless_symlink
2071
2080
def test_resolve_common (self ):
2081
+ if not self .can_symlink :
2082
+ self .skipTest ("symlinks required" )
2072
2083
P = self .cls
2073
2084
p = P (BASE , 'foo' )
2074
2085
with self .assertRaises (OSError ) as cm :
@@ -2128,9 +2139,10 @@ def test_resolve_common(self):
2128
2139
# resolves to 'dirB/..' first before resolving to parent of dirB.
2129
2140
self ._check_resolve_relative (p , P (BASE , 'foo' , 'in' , 'spam' ), False )
2130
2141
2131
- @os_helper .skip_unless_symlink
2132
2142
def test_resolve_dot (self ):
2133
2143
# See http://web.archive.org/web/20200623062557/https://bitbucket.org/pitrou/pathlib/issues/9/
2144
+ if not self .can_symlink :
2145
+ self .skipTest ("symlinks required" )
2134
2146
p = self .cls (BASE )
2135
2147
p .joinpath ('0' ).symlink_to ('.' , target_is_directory = True )
2136
2148
p .joinpath ('1' ).symlink_to (os .path .join ('0' , '0' ), target_is_directory = True )
@@ -2152,8 +2164,9 @@ def test_stat(self):
2152
2164
self .addCleanup (p .chmod , st .st_mode )
2153
2165
self .assertNotEqual (p .stat (), st )
2154
2166
2155
- @os_helper .skip_unless_symlink
2156
2167
def test_stat_no_follow_symlinks (self ):
2168
+ if not self .can_symlink :
2169
+ self .skipTest ("symlinks required" )
2157
2170
p = self .cls (BASE ) / 'linkA'
2158
2171
st = p .stat ()
2159
2172
self .assertNotEqual (st , p .stat (follow_symlinks = False ))
@@ -2163,8 +2176,9 @@ def test_stat_no_follow_symlinks_nosymlink(self):
2163
2176
st = p .stat ()
2164
2177
self .assertEqual (st , p .stat (follow_symlinks = False ))
2165
2178
2166
- @os_helper .skip_unless_symlink
2167
2179
def test_lstat (self ):
2180
+ if not self .can_symlink :
2181
+ self .skipTest ("symlinks required" )
2168
2182
p = self .cls (BASE )/ 'linkA'
2169
2183
st = p .stat ()
2170
2184
self .assertNotEqual (st , p .lstat ())
@@ -2180,7 +2194,7 @@ def test_is_dir(self):
2180
2194
self .assertFalse ((P / 'fileA' ).is_dir ())
2181
2195
self .assertFalse ((P / 'non-existing' ).is_dir ())
2182
2196
self .assertFalse ((P / 'fileA' / 'bah' ).is_dir ())
2183
- if os_helper .can_symlink () :
2197
+ if self .can_symlink :
2184
2198
self .assertFalse ((P / 'linkA' ).is_dir ())
2185
2199
self .assertTrue ((P / 'linkB' ).is_dir ())
2186
2200
self .assertFalse ((P / 'brokenLink' ).is_dir ())
@@ -2193,7 +2207,7 @@ def test_is_dir_no_follow_symlinks(self):
2193
2207
self .assertFalse ((P / 'fileA' ).is_dir (follow_symlinks = False ))
2194
2208
self .assertFalse ((P / 'non-existing' ).is_dir (follow_symlinks = False ))
2195
2209
self .assertFalse ((P / 'fileA' / 'bah' ).is_dir (follow_symlinks = False ))
2196
- if os_helper .can_symlink () :
2210
+ if self .can_symlink :
2197
2211
self .assertFalse ((P / 'linkA' ).is_dir (follow_symlinks = False ))
2198
2212
self .assertFalse ((P / 'linkB' ).is_dir (follow_symlinks = False ))
2199
2213
self .assertFalse ((P / 'brokenLink' ).is_dir (follow_symlinks = False ))
@@ -2206,7 +2220,7 @@ def test_is_file(self):
2206
2220
self .assertFalse ((P / 'dirA' ).is_file ())
2207
2221
self .assertFalse ((P / 'non-existing' ).is_file ())
2208
2222
self .assertFalse ((P / 'fileA' / 'bah' ).is_file ())
2209
- if os_helper .can_symlink () :
2223
+ if self .can_symlink :
2210
2224
self .assertTrue ((P / 'linkA' ).is_file ())
2211
2225
self .assertFalse ((P / 'linkB' ).is_file ())
2212
2226
self .assertFalse ((P / 'brokenLink' ).is_file ())
@@ -2219,7 +2233,7 @@ def test_is_file_no_follow_symlinks(self):
2219
2233
self .assertFalse ((P / 'dirA' ).is_file (follow_symlinks = False ))
2220
2234
self .assertFalse ((P / 'non-existing' ).is_file (follow_symlinks = False ))
2221
2235
self .assertFalse ((P / 'fileA' / 'bah' ).is_file (follow_symlinks = False ))
2222
- if os_helper .can_symlink () :
2236
+ if self .can_symlink :
2223
2237
self .assertFalse ((P / 'linkA' ).is_file (follow_symlinks = False ))
2224
2238
self .assertFalse ((P / 'linkB' ).is_file (follow_symlinks = False ))
2225
2239
self .assertFalse ((P / 'brokenLink' ).is_file (follow_symlinks = False ))
@@ -2237,7 +2251,7 @@ def test_is_mount(self):
2237
2251
self .assertFalse ((P / 'non-existing' ).is_mount ())
2238
2252
self .assertFalse ((P / 'fileA' / 'bah' ).is_mount ())
2239
2253
self .assertTrue (R .is_mount ())
2240
- if os_helper .can_symlink () :
2254
+ if self .can_symlink :
2241
2255
self .assertFalse ((P / 'linkA' ).is_mount ())
2242
2256
self .assertIs ((R / '\udfff ' ).is_mount (), False )
2243
2257
@@ -2247,13 +2261,13 @@ def test_is_symlink(self):
2247
2261
self .assertFalse ((P / 'dirA' ).is_symlink ())
2248
2262
self .assertFalse ((P / 'non-existing' ).is_symlink ())
2249
2263
self .assertFalse ((P / 'fileA' / 'bah' ).is_symlink ())
2250
- if os_helper .can_symlink () :
2264
+ if self .can_symlink :
2251
2265
self .assertTrue ((P / 'linkA' ).is_symlink ())
2252
2266
self .assertTrue ((P / 'linkB' ).is_symlink ())
2253
2267
self .assertTrue ((P / 'brokenLink' ).is_symlink ())
2254
2268
self .assertIs ((P / 'fileA\udfff ' ).is_file (), False )
2255
2269
self .assertIs ((P / 'fileA\x00 ' ).is_file (), False )
2256
- if os_helper .can_symlink () :
2270
+ if self .can_symlink :
2257
2271
self .assertIs ((P / 'linkA\udfff ' ).is_file (), False )
2258
2272
self .assertIs ((P / 'linkA\x00 ' ).is_file (), False )
2259
2273
@@ -2310,6 +2324,9 @@ def test_parts_interning(self):
2310
2324
self .assertIs (p .parts [2 ], q .parts [3 ])
2311
2325
2312
2326
def _check_complex_symlinks (self , link0_target ):
2327
+ if not self .can_symlink :
2328
+ self .skipTest ("symlinks required" )
2329
+
2313
2330
# Test solving a non-looping chain of symlinks (issue #19887).
2314
2331
P = self .cls (BASE )
2315
2332
P .joinpath ('link1' ).symlink_to (os .path .join ('link0' , 'link0' ), target_is_directory = True )
@@ -2350,15 +2367,12 @@ def _check_complex_symlinks(self, link0_target):
2350
2367
finally :
2351
2368
os .chdir (old_path )
2352
2369
2353
- @os_helper .skip_unless_symlink
2354
2370
def test_complex_symlinks_absolute (self ):
2355
2371
self ._check_complex_symlinks (BASE )
2356
2372
2357
- @os_helper .skip_unless_symlink
2358
2373
def test_complex_symlinks_relative (self ):
2359
2374
self ._check_complex_symlinks ('.' )
2360
2375
2361
- @os_helper .skip_unless_symlink
2362
2376
def test_complex_symlinks_relative_dot_dot (self ):
2363
2377
self ._check_complex_symlinks (os .path .join ('dirA' , '..' ))
2364
2378
@@ -2462,7 +2476,7 @@ def with_segments(self, *pathsegments):
2462
2476
self .assertEqual (42 , p .with_segments ('~' ).expanduser ().session_id )
2463
2477
self .assertEqual (42 , (p / 'fileA' ).rename (p / 'fileB' ).session_id )
2464
2478
self .assertEqual (42 , (p / 'fileB' ).replace (p / 'fileA' ).session_id )
2465
- if os_helper .can_symlink () :
2479
+ if self .can_symlink :
2466
2480
self .assertEqual (42 , (p / 'linkA' ).readlink ().session_id )
2467
2481
for path in p .iterdir ():
2468
2482
self .assertEqual (42 , path .session_id )
@@ -2783,8 +2797,9 @@ def my_mkdir(path, mode=0o777):
2783
2797
self .assertNotIn (str (p12 ), concurrently_created )
2784
2798
self .assertTrue (p .exists ())
2785
2799
2786
- @os_helper .skip_unless_symlink
2787
2800
def test_symlink_to (self ):
2801
+ if not self .can_symlink :
2802
+ self .skipTest ("symlinks required" )
2788
2803
P = self .cls (BASE )
2789
2804
target = P / 'fileA'
2790
2805
# Symlinking a path target.
@@ -3167,8 +3182,9 @@ def test_touch_mode(self):
3167
3182
st = os .stat (join ('masked_new_file' ))
3168
3183
self .assertEqual (stat .S_IMODE (st .st_mode ), 0o750 )
3169
3184
3170
- @os_helper .skip_unless_symlink
3171
3185
def test_resolve_loop (self ):
3186
+ if not self .can_symlink :
3187
+ self .skipTest ("symlinks required" )
3172
3188
# Loops with relative symlinks.
3173
3189
os .symlink ('linkX/inside' , join ('linkX' ))
3174
3190
self ._check_symlink_loop (BASE , 'linkX' )
0 commit comments