@@ -583,7 +583,7 @@ def test_confstr(self):
583583 self .assertGreater (len (path ), 0 )
584584 self .assertEqual (posix .confstr (posix .confstr_names ["CS_PATH" ]), path )
585585
586- @unittest .expectedFailureIf (sys .platform in (' darwin' , ' linux' ), ''' TODO: RUSTPYTHON; AssertionError: "configuration names must be strings or integers" does not match "Expected type 'str' but 'float' found."''' )
586+ @unittest .expectedFailureIf (sys .platform in (" darwin" , " linux" ), " TODO: RUSTPYTHON; AssertionError: \ " configuration names must be strings or integers\ " does not match \ " Expected type 'str' but 'float' found.\" " )
587587 @unittest .skipUnless (hasattr (posix , 'sysconf' ),
588588 'test needs posix.sysconf()' )
589589 def test_sysconf (self ):
@@ -1018,7 +1018,7 @@ def test_chmod_dir(self):
10181018 target = self .tempdir ()
10191019 self .check_chmod (posix .chmod , target )
10201020
1021- @unittest .skipIf (sys .platform in (' darwin' , ' linux' ), ' TODO: RUSTPYTHON; crash' )
1021+ @unittest .skipIf (sys .platform in (" darwin" , " linux" ), " TODO: RUSTPYTHON; crash" )
10221022 @os_helper .skip_unless_working_chmod
10231023 def test_fchmod_file (self ):
10241024 with open (os_helper .TESTFN , 'wb+' ) as f :
@@ -1075,7 +1075,7 @@ def test_chmod_file_symlink(self):
10751075 self .check_chmod_link (posix .chmod , target , link )
10761076 self .check_chmod_link (posix .chmod , target , link , follow_symlinks = True )
10771077
1078- @unittest .skipIf (sys .platform == ' win32' , ' TODO: RUSTPYTHON; flaky' )
1078+ @unittest .skipIf (sys .platform == " win32" , " TODO: RUSTPYTHON; flaky" )
10791079 @os_helper .skip_unless_symlink
10801080 def test_chmod_dir_symlink (self ):
10811081 target = self .tempdir ()
@@ -1110,7 +1110,7 @@ def test_lchmod_dir_symlink(self):
11101110
11111111 def _test_chflags_regular_file (self , chflags_func , target_file , ** kwargs ):
11121112 st = os .stat (target_file )
1113- self .assertTrue ( hasattr ( st , 'st_flags' ) )
1113+ self .assertHasAttr ( st , 'st_flags' )
11141114
11151115 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
11161116 flags = st .st_flags | stat .UF_IMMUTABLE
@@ -1146,7 +1146,7 @@ def test_lchflags_regular_file(self):
11461146 def test_lchflags_symlink (self ):
11471147 testfn_st = os .stat (os_helper .TESTFN )
11481148
1149- self .assertTrue ( hasattr ( testfn_st , 'st_flags' ) )
1149+ self .assertHasAttr ( testfn_st , 'st_flags' )
11501150
11511151 self .addCleanup (os_helper .unlink , _DUMMY_SYMLINK )
11521152 os .symlink (os_helper .TESTFN , _DUMMY_SYMLINK )
@@ -1370,6 +1370,14 @@ def test_sched_param(self):
13701370 self .assertNotEqual (newparam , param )
13711371 self .assertEqual (newparam .sched_priority , 0 )
13721372
1373+ @requires_sched
1374+ def test_bug_140634 (self ):
1375+ sched_priority = float ('inf' ) # any new reference
1376+ param = posix .sched_param (sched_priority )
1377+ param .__reduce__ ()
1378+ del sched_priority , param # should not crash
1379+ support .gc_collect () # just to be sure
1380+
13731381 @unittest .skipUnless (hasattr (posix , "sched_rr_get_interval" ), "no function" )
13741382 def test_sched_rr_get_interval (self ):
13751383 try :
@@ -1525,6 +1533,51 @@ def test_pidfd_open(self):
15251533 self .assertEqual (cm .exception .errno , errno .EINVAL )
15261534 os .close (os .pidfd_open (os .getpid (), 0 ))
15271535
1536+ @os_helper .skip_unless_hardlink
1537+ @os_helper .skip_unless_symlink
1538+ def test_link_follow_symlinks (self ):
1539+ default_follow = sys .platform .startswith (
1540+ ('darwin' , 'freebsd' , 'netbsd' , 'openbsd' , 'dragonfly' , 'sunos5' ))
1541+ default_no_follow = sys .platform .startswith (('win32' , 'linux' ))
1542+ orig = os_helper .TESTFN
1543+ symlink = orig + 'symlink'
1544+ posix .symlink (orig , symlink )
1545+ self .addCleanup (os_helper .unlink , symlink )
1546+
1547+ with self .subTest ('no follow_symlinks' ):
1548+ # no follow_symlinks -> platform depending
1549+ link = orig + 'link'
1550+ posix .link (symlink , link )
1551+ self .addCleanup (os_helper .unlink , link )
1552+ if os .link in os .supports_follow_symlinks or default_follow :
1553+ self .assertEqual (posix .lstat (link ), posix .lstat (orig ))
1554+ elif default_no_follow :
1555+ self .assertEqual (posix .lstat (link ), posix .lstat (symlink ))
1556+
1557+ with self .subTest ('follow_symlinks=False' ):
1558+ # follow_symlinks=False -> duplicate the symlink itself
1559+ link = orig + 'link_nofollow'
1560+ try :
1561+ posix .link (symlink , link , follow_symlinks = False )
1562+ except NotImplementedError :
1563+ if os .link in os .supports_follow_symlinks or default_no_follow :
1564+ raise
1565+ else :
1566+ self .addCleanup (os_helper .unlink , link )
1567+ self .assertEqual (posix .lstat (link ), posix .lstat (symlink ))
1568+
1569+ with self .subTest ('follow_symlinks=True' ):
1570+ # follow_symlinks=True -> duplicate the target file
1571+ link = orig + 'link_following'
1572+ try :
1573+ posix .link (symlink , link , follow_symlinks = True )
1574+ except NotImplementedError :
1575+ if os .link in os .supports_follow_symlinks or default_follow :
1576+ raise
1577+ else :
1578+ self .addCleanup (os_helper .unlink , link )
1579+ self .assertEqual (posix .lstat (link ), posix .lstat (orig ))
1580+
15281581
15291582# tests for the posix *at functions follow
15301583class TestPosixDirFd (unittest .TestCase ):
@@ -1570,7 +1623,7 @@ def test_chown_dir_fd(self):
15701623 with self .prepare_file () as (dir_fd , name , fullname ):
15711624 posix .chown (name , os .getuid (), os .getgid (), dir_fd = dir_fd )
15721625
1573- @unittest .expectedFailureIf (sys .platform in (' darwin' , ' linux' ), ' TODO: RUSTPYTHON; AssertionError: RuntimeWarning not triggered' )
1626+ @unittest .expectedFailureIf (sys .platform in (" darwin" , " linux" ), " TODO: RUSTPYTHON; AssertionError: RuntimeWarning not triggered" )
15741627 @unittest .skipUnless (os .stat in os .supports_dir_fd , "test needs dir_fd support in os.stat()" )
15751628 def test_stat_dir_fd (self ):
15761629 with self .prepare () as (dir_fd , name , fullname ):
@@ -1973,7 +2026,7 @@ def test_setsigdef_wrong_type(self):
19732026 [sys .executable , "-c" , "pass" ],
19742027 os .environ , setsigdef = [signal .NSIG , signal .NSIG + 1 ])
19752028
1976- @unittest .expectedFailureIf (sys .platform in (' darwin' , ' linux' ), ' TODO: RUSTPYTHON; NotImplementedError: scheduler parameter is not yet implemented' )
2029+ @unittest .expectedFailureIf (sys .platform in (" darwin" , " linux" ), " TODO: RUSTPYTHON; NotImplementedError: scheduler parameter is not yet implemented" )
19772030 @requires_sched
19782031 @unittest .skipIf (sys .platform .startswith (('freebsd' , 'netbsd' )),
19792032 "bpo-34685: test can fail on BSD" )
@@ -1994,14 +2047,15 @@ def test_setscheduler_only_param(self):
19942047 )
19952048 support .wait_process (pid , exitcode = 0 )
19962049
1997- @unittest .expectedFailureIf (sys .platform in (' darwin' , ' linux' ), ' TODO: RUSTPYTHON; NotImplementedError: scheduler parameter is not yet implemented' )
2050+ @unittest .expectedFailureIf (sys .platform in (" darwin" , " linux" ), " TODO: RUSTPYTHON; NotImplementedError: scheduler parameter is not yet implemented" )
19982051 @requires_sched
19992052 @unittest .skipIf (sys .platform .startswith (('freebsd' , 'netbsd' )),
20002053 "bpo-34685: test can fail on BSD" )
20012054 @unittest .skipIf (platform .libc_ver ()[0 ] == 'glibc' and
20022055 os .sched_getscheduler (0 ) in [
20032056 os .SCHED_BATCH ,
2004- os .SCHED_IDLE ],
2057+ os .SCHED_IDLE ,
2058+ os .SCHED_DEADLINE ],
20052059 "Skip test due to glibc posix_spawn policy" )
20062060 def test_setscheduler_with_policy (self ):
20072061 policy = os .sched_getscheduler (0 )
@@ -2081,7 +2135,7 @@ def test_open_file(self):
20812135 with open (outfile , encoding = "utf-8" ) as f :
20822136 self .assertEqual (f .read (), 'hello' )
20832137
2084- @unittest .expectedFailure # TODO: RUSTPYTHON; the rust runtime reopens closed stdio fds at startup, so this test fails, even though POSIX_SPAWN_CLOSE does actually have an effect
2138+ @unittest .expectedFailure # TODO: RUSTPYTHON; the rust runtime reopens closed stdio fds at startup, so this test fails, even though POSIX_SPAWN_CLOSE does actually have an effect
20852139 def test_close_file (self ):
20862140 closefile = os_helper .TESTFN
20872141 self .addCleanup (os_helper .unlink , closefile )
@@ -2186,12 +2240,12 @@ def _verify_available(self, name):
21862240 def test_pwritev (self ):
21872241 self ._verify_available ("HAVE_PWRITEV" )
21882242 if self .mac_ver >= (10 , 16 ):
2189- self .assertTrue ( hasattr ( os , "pwritev" ), "os.pwritev is not available " )
2190- self .assertTrue ( hasattr ( os , "preadv" ), "os.readv is not available " )
2243+ self .assertHasAttr ( os , "pwritev" )
2244+ self .assertHasAttr ( os , "preadv" )
21912245
21922246 else :
2193- self .assertFalse ( hasattr ( os , "pwritev" ), "os.pwritev is available " )
2194- self .assertFalse ( hasattr ( os , "preadv" ), "os.readv is available " )
2247+ self .assertNotHasAttr ( os , "pwritev" )
2248+ self .assertNotHasAttr ( os , "preadv" )
21952249
21962250 def test_stat (self ):
21972251 self ._verify_available ("HAVE_FSTATAT" )
0 commit comments