@@ -269,6 +269,21 @@ def test_realpath_basic(self):
269
269
self .assertPathEqual (ntpath .realpath (os .fsencode (ABSTFN + "1" )),
270
270
os .fsencode (ABSTFN ))
271
271
272
+ @os_helper .skip_unless_symlink
273
+ @unittest .skipUnless (HAVE_GETFINALPATHNAME , 'need _getfinalpathname' )
274
+ def test_realpath_strict (self ):
275
+ # Bug #43757: raise FileNotFoundError in strict mode if we encounter
276
+ # a path that does not exist.
277
+ ABSTFN = ntpath .abspath (os_helper .TESTFN )
278
+ os .symlink (ABSTFN + "1" , ABSTFN )
279
+ self .addCleanup (os_helper .unlink , ABSTFN )
280
+ self .assertRaises (FileNotFoundError , ntpath .realpath , ABSTFN , strict = True )
281
+ self .assertRaises (FileNotFoundError , ntpath .realpath , ABSTFN + "2" , strict = True )
282
+
283
+ # TODO: RUSTPYTHON, TypeError: got an unexpected keyword argument 'strict'
284
+ if sys .platform == "win32" :
285
+ test_realpath_strict = unittest .expectedFailure (test_realpath_strict )
286
+
272
287
@os_helper .skip_unless_symlink
273
288
@unittest .skipUnless (HAVE_GETFINALPATHNAME , 'need _getfinalpathname' )
274
289
def test_realpath_relative (self ):
@@ -343,8 +358,9 @@ def test_realpath_broken_symlinks(self):
343
358
@os_helper .skip_unless_symlink
344
359
@unittest .skipUnless (HAVE_GETFINALPATHNAME , 'need _getfinalpathname' )
345
360
def test_realpath_symlink_loops (self ):
346
- # Symlink loops are non-deterministic as to which path is returned, but
347
- # it will always be the fully resolved path of one member of the cycle
361
+ # Symlink loops in non-strict mode are non-deterministic as to which
362
+ # path is returned, but it will always be the fully resolved path of
363
+ # one member of the cycle
348
364
ABSTFN = ntpath .abspath (os_helper .TESTFN )
349
365
self .addCleanup (os_helper .unlink , ABSTFN )
350
366
self .addCleanup (os_helper .unlink , ABSTFN + "1" )
@@ -386,6 +402,54 @@ def test_realpath_symlink_loops(self):
386
402
# Test using relative path as well.
387
403
self .assertPathEqual (ntpath .realpath (ntpath .basename (ABSTFN )), ABSTFN )
388
404
405
+ @os_helper .skip_unless_symlink
406
+ @unittest .skipUnless (HAVE_GETFINALPATHNAME , 'need _getfinalpathname' )
407
+ def test_realpath_symlink_loops_strict (self ):
408
+ # Symlink loops raise OSError in strict mode
409
+ ABSTFN = ntpath .abspath (os_helper .TESTFN )
410
+ self .addCleanup (os_helper .unlink , ABSTFN )
411
+ self .addCleanup (os_helper .unlink , ABSTFN + "1" )
412
+ self .addCleanup (os_helper .unlink , ABSTFN + "2" )
413
+ self .addCleanup (os_helper .unlink , ABSTFN + "y" )
414
+ self .addCleanup (os_helper .unlink , ABSTFN + "c" )
415
+ self .addCleanup (os_helper .unlink , ABSTFN + "a" )
416
+
417
+ os .symlink (ABSTFN , ABSTFN )
418
+ self .assertRaises (OSError , ntpath .realpath , ABSTFN , strict = True )
419
+
420
+ os .symlink (ABSTFN + "1" , ABSTFN + "2" )
421
+ os .symlink (ABSTFN + "2" , ABSTFN + "1" )
422
+ self .assertRaises (OSError , ntpath .realpath , ABSTFN + "1" , strict = True )
423
+ self .assertRaises (OSError , ntpath .realpath , ABSTFN + "2" , strict = True )
424
+ self .assertRaises (OSError , ntpath .realpath , ABSTFN + "1\\ x" , strict = True )
425
+ # Windows eliminates '..' components before resolving links, so the
426
+ # following call is not expected to raise.
427
+ self .assertPathEqual (ntpath .realpath (ABSTFN + "1\\ .." , strict = True ),
428
+ ntpath .dirname (ABSTFN ))
429
+ self .assertRaises (OSError , ntpath .realpath , ABSTFN + "1\\ ..\\ x" , strict = True )
430
+ os .symlink (ABSTFN + "x" , ABSTFN + "y" )
431
+ self .assertRaises (OSError , ntpath .realpath , ABSTFN + "1\\ ..\\ "
432
+ + ntpath .basename (ABSTFN ) + "y" ,
433
+ strict = True )
434
+ self .assertRaises (OSError , ntpath .realpath ,
435
+ ABSTFN + "1\\ ..\\ " + ntpath .basename (ABSTFN ) + "1" ,
436
+ strict = True )
437
+
438
+ os .symlink (ntpath .basename (ABSTFN ) + "a\\ b" , ABSTFN + "a" )
439
+ self .assertRaises (OSError , ntpath .realpath , ABSTFN + "a" , strict = True )
440
+
441
+ os .symlink ("..\\ " + ntpath .basename (ntpath .dirname (ABSTFN ))
442
+ + "\\ " + ntpath .basename (ABSTFN ) + "c" , ABSTFN + "c" )
443
+ self .assertRaises (OSError , ntpath .realpath , ABSTFN + "c" , strict = True )
444
+
445
+ # Test using relative path as well.
446
+ self .assertRaises (OSError , ntpath .realpath , ntpath .basename (ABSTFN ),
447
+ strict = True )
448
+
449
+ # TODO: RUSTPYTHON, FileExistsError: [Errno 183] Cannot create a file when that file already exists. (os error 183): 'None' -> 'None'
450
+ if sys .platform == "win32" :
451
+ test_realpath_symlink_loops_strict = unittest .expectedFailure (test_realpath_symlink_loops_strict )
452
+
389
453
@os_helper .skip_unless_symlink
390
454
@unittest .skipUnless (HAVE_GETFINALPATHNAME , 'need _getfinalpathname' )
391
455
def test_realpath_symlink_prefix (self ):
@@ -453,6 +517,7 @@ def test_realpath_cwd(self):
453
517
with os_helper .change_cwd (test_dir_short ):
454
518
self .assertPathEqual (test_file_long , ntpath .realpath ("file.txt" ))
455
519
520
+ @unittest .skipIf (sys .platform == "win32" , "TODO: RUSTPYTHON, ValueError: illegal environment variable name" )
456
521
def test_expandvars (self ):
457
522
with os_helper .EnvironmentVarGuard () as env :
458
523
env .clear ()
@@ -479,6 +544,7 @@ def test_expandvars(self):
479
544
tester ('ntpath.expandvars("\' %foo%\' %bar")' , "\' %foo%\' %bar" )
480
545
tester ('ntpath.expandvars("bar\' %foo%")' , "bar\' %foo%" )
481
546
547
+ @unittest .skipIf (sys .platform == "win32" , "TODO: RUSTPYTHON, ValueError: illegal environment variable name" )
482
548
@unittest .skipUnless (os_helper .FS_NONASCII , 'need os_helper.FS_NONASCII' )
483
549
def test_expandvars_nonascii (self ):
484
550
def check (value , expected ):
@@ -499,41 +565,56 @@ def check(value, expected):
499
565
check ('%spam%bar' , '%sbar' % nonascii )
500
566
check ('%{}%bar' .format (nonascii ), 'ham%sbar' % nonascii )
501
567
568
+ # TODO: RUSTPYTHON
569
+ @unittest .expectedFailure
502
570
def test_expanduser (self ):
503
571
tester ('ntpath.expanduser("test")' , 'test' )
504
572
505
573
with os_helper .EnvironmentVarGuard () as env :
506
574
env .clear ()
507
575
tester ('ntpath.expanduser("~test")' , '~test' )
508
576
509
- env ['HOMEPATH' ] = 'eric\\ idle'
510
577
env ['HOMEDRIVE' ] = 'C:\\ '
511
- tester ('ntpath.expanduser("~test")' , 'C:\\ eric\\ test' )
512
- tester ('ntpath.expanduser("~")' , 'C:\\ eric\\ idle' )
578
+ env ['HOMEPATH' ] = 'Users\\ eric'
579
+ env ['USERNAME' ] = 'eric'
580
+ tester ('ntpath.expanduser("~test")' , 'C:\\ Users\\ test' )
581
+ tester ('ntpath.expanduser("~")' , 'C:\\ Users\\ eric' )
513
582
514
583
del env ['HOMEDRIVE' ]
515
- tester ('ntpath.expanduser("~test")' , 'eric \\ test' )
516
- tester ('ntpath.expanduser("~")' , 'eric \\ idle ' )
584
+ tester ('ntpath.expanduser("~test")' , 'Users \\ test' )
585
+ tester ('ntpath.expanduser("~")' , 'Users \\ eric ' )
517
586
518
587
env .clear ()
519
- env ['USERPROFILE' ] = 'C:\\ eric\\ idle'
520
- tester ('ntpath.expanduser("~test")' , 'C:\\ eric\\ test' )
521
- tester ('ntpath.expanduser("~")' , 'C:\\ eric\\ idle' )
588
+ env ['USERPROFILE' ] = 'C:\\ Users\\ eric'
589
+ env ['USERNAME' ] = 'eric'
590
+ tester ('ntpath.expanduser("~test")' , 'C:\\ Users\\ test' )
591
+ tester ('ntpath.expanduser("~")' , 'C:\\ Users\\ eric' )
522
592
tester ('ntpath.expanduser("~test\\ foo\\ bar")' ,
523
- 'C:\\ eric \\ test\\ foo\\ bar' )
593
+ 'C:\\ Users \\ test\\ foo\\ bar' )
524
594
tester ('ntpath.expanduser("~test/foo/bar")' ,
525
- 'C:\\ eric \\ test/foo/bar' )
595
+ 'C:\\ Users \\ test/foo/bar' )
526
596
tester ('ntpath.expanduser("~\\ foo\\ bar")' ,
527
- 'C:\\ eric \\ idle \\ foo\\ bar' )
597
+ 'C:\\ Users \\ eric \\ foo\\ bar' )
528
598
tester ('ntpath.expanduser("~/foo/bar")' ,
529
- 'C:\\ eric \\ idle /foo/bar' )
599
+ 'C:\\ Users \\ eric /foo/bar' )
530
600
531
601
# bpo-36264: ignore `HOME` when set on windows
532
602
env .clear ()
533
603
env ['HOME' ] = 'F:\\ '
534
- env ['USERPROFILE' ] = 'C:\\ eric\\ idle'
535
- tester ('ntpath.expanduser("~test")' , 'C:\\ eric\\ test' )
536
- tester ('ntpath.expanduser("~")' , 'C:\\ eric\\ idle' )
604
+ env ['USERPROFILE' ] = 'C:\\ Users\\ eric'
605
+ env ['USERNAME' ] = 'eric'
606
+ tester ('ntpath.expanduser("~test")' , 'C:\\ Users\\ test' )
607
+ tester ('ntpath.expanduser("~")' , 'C:\\ Users\\ eric' )
608
+
609
+ # bpo-39899: don't guess another user's home directory if
610
+ # `%USERNAME% != basename(%USERPROFILE%)`
611
+ env .clear ()
612
+ env ['USERPROFILE' ] = 'C:\\ Users\\ eric'
613
+ env ['USERNAME' ] = 'idle'
614
+ tester ('ntpath.expanduser("~test")' , '~test' )
615
+ tester ('ntpath.expanduser("~")' , 'C:\\ Users\\ eric' )
616
+
617
+
537
618
538
619
@unittest .skipUnless (nt , "abspath requires 'nt' module" )
539
620
def test_abspath (self ):
@@ -569,6 +650,10 @@ def test_relpath(self):
569
650
tester ('ntpath.relpath("/a/b", "/a/b")' , '.' )
570
651
tester ('ntpath.relpath("c:/foo", "C:/FOO")' , '.' )
571
652
653
+ # TODO: RUSTPYTHON, FileExistsError: [Errno 183] Cannot create a file when that file already exists. (os error 183): 'None' -> 'None'
654
+ if sys .platform == "win32" :
655
+ test_relpath = unittest .expectedFailure (test_relpath )
656
+
572
657
def test_commonpath (self ):
573
658
def check (paths , expected ):
574
659
tester (('ntpath.commonpath(%r)' % paths ).replace ('\\ \\ ' , '\\ ' ),
@@ -728,8 +813,13 @@ class NtCommonTest(test_genericpath.CommonTest, unittest.TestCase):
728
813
pathmodule = ntpath
729
814
attributes = ['relpath' ]
730
815
731
- def test_expandvars_nonascii (self ):
732
- super ().test_expandvars_nonascii ()
816
+ @unittest .skipIf (sys .platform == "win32" , "TODO: RUSTPYTHON, ValueError: illegal environment variable name" )
817
+ def test_expandvars (self ): # TODO: RUSTPYTHON, remove when this passes
818
+ super ().test_expandvars () # TODO: RUSTPYTHON, remove when this passes
819
+
820
+ @unittest .skipIf (sys .platform == "win32" , "TODO: RUSTPYTHON, ValueError: illegal environment variable name" )
821
+ def test_expandvars_nonascii (self ): # TODO: RUSTPYTHON, remove when this passes
822
+ super ().test_expandvars_nonascii () # TODO: RUSTPYTHON, remove when this passes
733
823
734
824
# TODO: RUSTPYTHON
735
825
if sys .platform == "linux" :
@@ -767,7 +857,7 @@ class PathLikeTests(NtpathTestCase):
767
857
path = ntpath
768
858
769
859
def setUp (self ):
770
- self .file_name = os_helper .TESTFN . lower ()
860
+ self .file_name = os_helper .TESTFN
771
861
self .file_path = FakePath (os_helper .TESTFN )
772
862
self .addCleanup (os_helper .unlink , self .file_name )
773
863
with open (self .file_name , 'xb' , 0 ) as file :
@@ -778,6 +868,12 @@ def _check_function(self, func):
778
868
779
869
def test_path_normcase (self ):
780
870
self ._check_function (self .path .normcase )
871
+ if sys .platform == 'win32' :
872
+ self .assertEqual (ntpath .normcase ('\u03a9 \u2126 ' ), 'ωΩ' )
873
+
874
+ # TODO: RUSTPYTHON, AssertionError: 'ωω' != 'ωΩ'
875
+ if sys .platform == "win32" :
876
+ test_path_normcase = unittest .expectedFailure (test_path_normcase )
781
877
782
878
def test_path_isabs (self ):
783
879
self ._check_function (self .path .isabs )
0 commit comments