@@ -122,6 +122,13 @@ def test_parse_parts(self):
122
122
# the second path is relative.
123
123
check (['c:/a/b' , 'c:x/y' ], ('c:' , '\\ ' , ['c:\\ ' , 'a' , 'b' , 'x' , 'y' ]))
124
124
check (['c:/a/b' , 'c:/x/y' ], ('c:' , '\\ ' , ['c:\\ ' , 'x' , 'y' ]))
125
+ # Paths to files with NTFS alternate data streams
126
+ check (['./c:s' ], ('' , '' , ['c:s' ]))
127
+ check (['cc:s' ], ('' , '' , ['cc:s' ]))
128
+ check (['C:c:s' ], ('C:' , '' , ['C:' , 'c:s' ]))
129
+ check (['C:/c:s' ], ('C:' , '\\ ' , ['C:\\ ' , 'c:s' ]))
130
+ check (['D:a' , './c:b' ], ('D:' , '' , ['D:' , 'a' , 'c:b' ]))
131
+ check (['D:/a' , './c:b' ], ('D:' , '\\ ' , ['D:\\ ' , 'a' , 'c:b' ]))
125
132
126
133
127
134
#
@@ -165,6 +172,7 @@ def test_constructor_common(self):
165
172
self .assertEqual (P (P ('a' ), 'b' ), P ('a/b' ))
166
173
self .assertEqual (P (P ('a' ), P ('b' )), P ('a/b' ))
167
174
self .assertEqual (P (P ('a' ), P ('b' ), P ('c' )), P (FakePath ("a/b/c" )))
175
+ self .assertEqual (P (P ('./a:b' )), P ('./a:b' ))
168
176
169
177
def test_bytes (self ):
170
178
P = self .cls
@@ -814,7 +822,8 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase):
814
822
815
823
equivalences = _BasePurePathTest .equivalences .copy ()
816
824
equivalences .update ({
817
- 'c:a' : [ ('c:' , 'a' ), ('c:' , 'a/' ), ('/' , 'c:' , 'a' ) ],
825
+ './a:b' : [ ('./a:b' ,) ],
826
+ 'c:a' : [ ('c:' , 'a' ), ('c:' , 'a/' ), ('.' , 'c:' , 'a' ) ],
818
827
'c:/a' : [
819
828
('c:/' , 'a' ), ('c:' , '/' , 'a' ), ('c:' , '/a' ),
820
829
('/z' , 'c:/' , 'a' ), ('//x/y' , 'c:/' , 'a' ),
@@ -838,6 +847,7 @@ def test_str(self):
838
847
self .assertEqual (str (p ), '\\ \\ a\\ b\\ c\\ d' )
839
848
840
849
def test_str_subclass (self ):
850
+ self ._check_str_subclass ('.\\ a:b' )
841
851
self ._check_str_subclass ('c:' )
842
852
self ._check_str_subclass ('c:a' )
843
853
self ._check_str_subclass ('c:a\\ b.txt' )
@@ -1005,6 +1015,7 @@ def test_drive(self):
1005
1015
self .assertEqual (P ('//a/b' ).drive , '\\ \\ a\\ b' )
1006
1016
self .assertEqual (P ('//a/b/' ).drive , '\\ \\ a\\ b' )
1007
1017
self .assertEqual (P ('//a/b/c/d' ).drive , '\\ \\ a\\ b' )
1018
+ self .assertEqual (P ('./c:a' ).drive , '' )
1008
1019
1009
1020
def test_root (self ):
1010
1021
P = self .cls
@@ -1341,6 +1352,14 @@ def test_join(self):
1341
1352
self .assertEqual (pp , P ('C:/a/b/x/y' ))
1342
1353
pp = p .joinpath ('c:/x/y' )
1343
1354
self .assertEqual (pp , P ('C:/x/y' ))
1355
+ # Joining with files with NTFS data streams => the filename should
1356
+ # not be parsed as a drive letter
1357
+ pp = p .joinpath (P ('./d:s' ))
1358
+ self .assertEqual (pp , P ('C:/a/b/d:s' ))
1359
+ pp = p .joinpath (P ('./dd:s' ))
1360
+ self .assertEqual (pp , P ('C:/a/b/dd:s' ))
1361
+ pp = p .joinpath (P ('E:d:s' ))
1362
+ self .assertEqual (pp , P ('E:d:s' ))
1344
1363
1345
1364
def test_div (self ):
1346
1365
# Basically the same as joinpath().
@@ -1361,6 +1380,11 @@ def test_div(self):
1361
1380
# the second path is relative.
1362
1381
self .assertEqual (p / 'c:x/y' , P ('C:/a/b/x/y' ))
1363
1382
self .assertEqual (p / 'c:/x/y' , P ('C:/x/y' ))
1383
+ # Joining with files with NTFS data streams => the filename should
1384
+ # not be parsed as a drive letter
1385
+ self .assertEqual (p / P ('./d:s' ), P ('C:/a/b/d:s' ))
1386
+ self .assertEqual (p / P ('./dd:s' ), P ('C:/a/b/dd:s' ))
1387
+ self .assertEqual (p / P ('E:d:s' ), P ('E:d:s' ))
1364
1388
1365
1389
def test_is_reserved (self ):
1366
1390
P = self .cls
@@ -1626,6 +1650,8 @@ def test_expanduser_common(self):
1626
1650
self .assertEqual (p .expanduser (), p )
1627
1651
p = P (P ('' ).absolute ().anchor ) / '~'
1628
1652
self .assertEqual (p .expanduser (), p )
1653
+ p = P ('~/a:b' )
1654
+ self .assertEqual (p .expanduser (), P (os .path .expanduser ('~' ), './a:b' ))
1629
1655
1630
1656
def test_exists (self ):
1631
1657
P = self .cls
0 commit comments