@@ -1731,17 +1731,21 @@ def iterdir(self):
1731
1731
raise FileNotFoundError (errno .ENOENT , "File not found" , path )
1732
1732
1733
1733
def mkdir (self , mode = 0o777 , parents = False , exist_ok = False ):
1734
+ path = str (self .resolve ())
1735
+ if path in self ._directories :
1736
+ if exist_ok :
1737
+ return
1738
+ else :
1739
+ raise FileExistsError (errno .EEXIST , "File exists" , path )
1734
1740
try :
1735
- self ._directories [str (self .parent )].add (self .name )
1736
- self ._directories [str (self )] = set ()
1741
+ if self .name :
1742
+ self ._directories [str (self .parent )].add (self .name )
1743
+ self ._directories [path ] = set ()
1737
1744
except KeyError :
1738
- if not parents or self . parent == self :
1745
+ if not parents :
1739
1746
raise FileNotFoundError (errno .ENOENT , "File not found" , str (self .parent )) from None
1740
1747
self .parent .mkdir (parents = True , exist_ok = True )
1741
1748
self .mkdir (mode , parents = False , exist_ok = exist_ok )
1742
- except FileExistsError :
1743
- if not exist_ok :
1744
- raise
1745
1749
1746
1750
1747
1751
class DummyPathTest (unittest .TestCase ):
@@ -1771,33 +1775,37 @@ class DummyPathTest(unittest.TestCase):
1771
1775
#
1772
1776
1773
1777
def setUp (self ):
1774
- # note: this must be kept in sync with `PathTest.setUp()`
1778
+ pathmod = self .cls .pathmod
1779
+ p = self .cls (BASE )
1780
+ p .mkdir (parents = True )
1781
+ p .joinpath ('dirA' ).mkdir ()
1782
+ p .joinpath ('dirB' ).mkdir ()
1783
+ p .joinpath ('dirC' ).mkdir ()
1784
+ p .joinpath ('dirC' , 'dirD' ).mkdir ()
1785
+ p .joinpath ('dirE' ).mkdir ()
1786
+ with p .joinpath ('fileA' ).open ('wb' ) as f :
1787
+ f .write (b"this is file A\n " )
1788
+ with p .joinpath ('dirB' , 'fileB' ).open ('wb' ) as f :
1789
+ f .write (b"this is file B\n " )
1790
+ with p .joinpath ('dirC' , 'fileC' ).open ('wb' ) as f :
1791
+ f .write (b"this is file C\n " )
1792
+ with p .joinpath ('dirC' , 'novel.txt' ).open ('wb' ) as f :
1793
+ f .write (b"this is a novel\n " )
1794
+ with p .joinpath ('dirC' , 'dirD' , 'fileD' ).open ('wb' ) as f :
1795
+ f .write (b"this is file D\n " )
1796
+ if self .can_symlink :
1797
+ p .joinpath ('linkA' ).symlink_to ('fileA' )
1798
+ p .joinpath ('brokenLink' ).symlink_to ('non-existing' )
1799
+ p .joinpath ('linkB' ).symlink_to ('dirB' )
1800
+ p .joinpath ('dirA' , 'linkC' ).symlink_to (pathmod .join ('..' , 'dirB' ))
1801
+ p .joinpath ('dirB' , 'linkD' ).symlink_to (pathmod .join ('..' , 'dirB' ))
1802
+ p .joinpath ('brokenLinkLoop' ).symlink_to ('brokenLinkLoop' )
1803
+
1804
+ def tearDown (self ):
1775
1805
cls = self .cls
1776
1806
cls ._files .clear ()
1777
1807
cls ._directories .clear ()
1778
1808
cls ._symlinks .clear ()
1779
- join = cls .pathmod .join
1780
- cls ._files .update ({
1781
- join (BASE , 'fileA' ): b'this is file A\n ' ,
1782
- join (BASE , 'dirB' , 'fileB' ): b'this is file B\n ' ,
1783
- join (BASE , 'dirC' , 'fileC' ): b'this is file C\n ' ,
1784
- join (BASE , 'dirC' , 'dirD' , 'fileD' ): b'this is file D\n ' ,
1785
- join (BASE , 'dirC' , 'novel.txt' ): b'this is a novel\n ' ,
1786
- })
1787
- cls ._directories .update ({
1788
- BASE : {'dirA' , 'dirB' , 'dirC' , 'dirE' , 'fileA' },
1789
- join (BASE , 'dirA' ): set (),
1790
- join (BASE , 'dirB' ): {'fileB' },
1791
- join (BASE , 'dirC' ): {'dirD' , 'fileC' , 'novel.txt' },
1792
- join (BASE , 'dirC' , 'dirD' ): {'fileD' },
1793
- join (BASE , 'dirE' ): {},
1794
- })
1795
- dirname = BASE
1796
- while True :
1797
- dirname , basename = cls .pathmod .split (dirname )
1798
- if not basename :
1799
- break
1800
- cls ._directories [dirname ] = {basename }
1801
1809
1802
1810
def tempdir (self ):
1803
1811
path = self .cls (BASE ).with_name ('tmp-dirD' )
@@ -2626,22 +2634,6 @@ class DummyPathWithSymlinksTest(DummyPathTest):
2626
2634
cls = DummyPathWithSymlinks
2627
2635
can_symlink = True
2628
2636
2629
- def setUp (self ):
2630
- super ().setUp ()
2631
- cls = self .cls
2632
- join = cls .pathmod .join
2633
- cls ._symlinks .update ({
2634
- join (BASE , 'linkA' ): 'fileA' ,
2635
- join (BASE , 'linkB' ): 'dirB' ,
2636
- join (BASE , 'dirA' , 'linkC' ): join ('..' , 'dirB' ),
2637
- join (BASE , 'dirB' , 'linkD' ): join ('..' , 'dirB' ),
2638
- join (BASE , 'brokenLink' ): 'non-existing' ,
2639
- join (BASE , 'brokenLinkLoop' ): 'brokenLinkLoop' ,
2640
- })
2641
- cls ._directories [BASE ].update ({'linkA' , 'linkB' , 'brokenLink' , 'brokenLinkLoop' })
2642
- cls ._directories [join (BASE , 'dirA' )].add ('linkC' )
2643
- cls ._directories [join (BASE , 'dirB' )].add ('linkD' )
2644
-
2645
2637
2646
2638
#
2647
2639
# Tests for the concrete classes.
@@ -2653,38 +2645,12 @@ class PathTest(DummyPathTest):
2653
2645
can_symlink = os_helper .can_symlink ()
2654
2646
2655
2647
def setUp (self ):
2656
- # note: this must be kept in sync with `DummyPathTest.setUp()`
2657
- def cleanup ():
2658
- os .chmod (join ('dirE' ), 0o777 )
2659
- os_helper .rmtree (BASE )
2660
- self .addCleanup (cleanup )
2661
- os .mkdir (BASE )
2662
- os .mkdir (join ('dirA' ))
2663
- os .mkdir (join ('dirB' ))
2664
- os .mkdir (join ('dirC' ))
2665
- os .mkdir (join ('dirC' , 'dirD' ))
2666
- os .mkdir (join ('dirE' ))
2667
- with open (join ('fileA' ), 'wb' ) as f :
2668
- f .write (b"this is file A\n " )
2669
- with open (join ('dirB' , 'fileB' ), 'wb' ) as f :
2670
- f .write (b"this is file B\n " )
2671
- with open (join ('dirC' , 'fileC' ), 'wb' ) as f :
2672
- f .write (b"this is file C\n " )
2673
- with open (join ('dirC' , 'novel.txt' ), 'wb' ) as f :
2674
- f .write (b"this is a novel\n " )
2675
- with open (join ('dirC' , 'dirD' , 'fileD' ), 'wb' ) as f :
2676
- f .write (b"this is file D\n " )
2648
+ super ().setUp ()
2677
2649
os .chmod (join ('dirE' ), 0 )
2678
- if self .can_symlink :
2679
- # Relative symlinks.
2680
- os .symlink ('fileA' , join ('linkA' ))
2681
- os .symlink ('non-existing' , join ('brokenLink' ))
2682
- os .symlink ('dirB' , join ('linkB' ), target_is_directory = True )
2683
- os .symlink (os .path .join ('..' , 'dirB' ), join ('dirA' , 'linkC' ), target_is_directory = True )
2684
- # This one goes upwards, creating a loop.
2685
- os .symlink (os .path .join ('..' , 'dirB' ), join ('dirB' , 'linkD' ), target_is_directory = True )
2686
- # Broken symlink (pointing to itself).
2687
- os .symlink ('brokenLinkLoop' , join ('brokenLinkLoop' ))
2650
+
2651
+ def tearDown (self ):
2652
+ os .chmod (join ('dirE' ), 0o777 )
2653
+ os_helper .rmtree (BASE )
2688
2654
2689
2655
def tempdir (self ):
2690
2656
d = os_helper ._longpath (tempfile .mkdtemp (suffix = '-dirD' ,
0 commit comments