2020from  test .support  import  infinite_recursion 
2121from  test .support  import  os_helper 
2222from  test .support .os_helper  import  TESTFN , FakePath 
23- from  test .test_pathlib  import  test_pathlib_abc 
24- from  test .test_pathlib .test_pathlib_abc  import  needs_posix , needs_windows 
25- 
2623try :
2724    import  fcntl 
2825except  ImportError :
@@ -56,7 +53,20 @@ def new_test(self):
5653    return  new_test 
5754
5855
56+ _tests_needing_posix  =  set ()
57+ _tests_needing_windows  =  set ()
5958_tests_needing_symlinks  =  set ()
59+ 
60+ def  needs_posix (fn ):
61+     """Decorator that marks a test as requiring a POSIX-flavoured path class.""" 
62+     _tests_needing_posix .add (fn .__name__ )
63+     return  fn 
64+ 
65+ def  needs_windows (fn ):
66+     """Decorator that marks a test as requiring a Windows-flavoured path class.""" 
67+     _tests_needing_windows .add (fn .__name__ )
68+     return  fn 
69+ 
6070def  needs_symlinks (fn ):
6171    """Decorator that marks a test as requiring a path class that supports symlinks.""" 
6272    _tests_needing_symlinks .add (fn .__name__ )
@@ -74,7 +84,7 @@ def test_is_notimplemented(self):
7484# Tests for the pure classes. 
7585# 
7686
77- class  PurePathTest (test_pathlib_abc . JoinablePathTest ):
87+ class  PurePathTest (unittest . TestCase ):
7888    cls  =  pathlib .PurePath 
7989
8090    # Make sure any symbolic links in the base test path are resolved. 
@@ -96,6 +106,72 @@ class PurePathTest(test_pathlib_abc.JoinablePathTest):
96106            ],
97107    }
98108
109+     def  setUp (self ):
110+         name  =  self .id ().split ('.' )[- 1 ]
111+         if  name  in  _tests_needing_posix  and  self .cls .parser  is  not posixpath :
112+             self .skipTest ('requires POSIX-flavoured path class' )
113+         if  name  in  _tests_needing_windows  and  self .cls .parser  is  posixpath :
114+             self .skipTest ('requires Windows-flavoured path class' )
115+         p  =  self .cls ('a' )
116+         self .parser  =  p .parser 
117+         self .sep  =  self .parser .sep 
118+         self .altsep  =  self .parser .altsep 
119+ 
120+     def  _check_str_subclass (self , * args ):
121+         # Issue #21127: it should be possible to construct a PurePath object 
122+         # from a str subclass instance, and it then gets converted to 
123+         # a pure str object. 
124+         class  StrSubclass (str ):
125+             pass 
126+         P  =  self .cls 
127+         p  =  P (* (StrSubclass (x ) for  x  in  args ))
128+         self .assertEqual (p , P (* args ))
129+         for  part  in  p .parts :
130+             self .assertIs (type (part ), str )
131+ 
132+     def  test_str_subclass_common (self ):
133+         self ._check_str_subclass ('' )
134+         self ._check_str_subclass ('.' )
135+         self ._check_str_subclass ('a' )
136+         self ._check_str_subclass ('a/b.txt' )
137+         self ._check_str_subclass ('/a/b.txt' )
138+ 
139+     @needs_windows  
140+     def  test_str_subclass_windows (self ):
141+         self ._check_str_subclass ('.\\ a:b' )
142+         self ._check_str_subclass ('c:' )
143+         self ._check_str_subclass ('c:a' )
144+         self ._check_str_subclass ('c:a\\ b.txt' )
145+         self ._check_str_subclass ('c:\\ ' )
146+         self ._check_str_subclass ('c:\\ a' )
147+         self ._check_str_subclass ('c:\\ a\\ b.txt' )
148+         self ._check_str_subclass ('\\ \\ some\\ share' )
149+         self ._check_str_subclass ('\\ \\ some\\ share\\ a' )
150+         self ._check_str_subclass ('\\ \\ some\\ share\\ a\\ b.txt' )
151+ 
152+     def  _check_str (self , expected , args ):
153+         p  =  self .cls (* args )
154+         self .assertEqual (str (p ), expected .replace ('/' , self .sep ))
155+ 
156+     def  test_str_common (self ):
157+         # Canonicalized paths roundtrip. 
158+         for  pathstr  in  ('a' , 'a/b' , 'a/b/c' , '/' , '/a/b' , '/a/b/c' ):
159+             self ._check_str (pathstr , (pathstr ,))
160+         # Other tests for str() are in test_equivalences(). 
161+ 
162+     @needs_windows  
163+     def  test_str_windows (self ):
164+         p  =  self .cls ('a/b/c' )
165+         self .assertEqual (str (p ), 'a\\ b\\ c' )
166+         p  =  self .cls ('c:/a/b/c' )
167+         self .assertEqual (str (p ), 'c:\\ a\\ b\\ c' )
168+         p  =  self .cls ('//a/b' )
169+         self .assertEqual (str (p ), '\\ \\ a\\ b\\ ' )
170+         p  =  self .cls ('//a/b/c' )
171+         self .assertEqual (str (p ), '\\ \\ a\\ b\\ c' )
172+         p  =  self .cls ('//a/b/c/d' )
173+         self .assertEqual (str (p ), '\\ \\ a\\ b\\ c\\ d' )
174+ 
99175    def  test_concrete_class (self ):
100176        if  self .cls  is  pathlib .PurePath :
101177            expected  =  pathlib .PureWindowsPath  if  os .name  ==  'nt'  else  pathlib .PurePosixPath 
@@ -1032,7 +1108,7 @@ class cls(pathlib.PurePath):
10321108# Tests for the concrete classes. 
10331109# 
10341110
1035- class  PathTest (test_pathlib_abc . RWPathTest ,  PurePathTest ):
1111+ class  PathTest (PurePathTest ):
10361112    """Tests for the FS-accessing functionalities of the Path classes.""" 
10371113    cls  =  pathlib .Path 
10381114    can_symlink  =  os_helper .can_symlink ()
@@ -1042,8 +1118,6 @@ def setUp(self):
10421118        if  name  in  _tests_needing_symlinks  and  not  self .can_symlink :
10431119            self .skipTest ('requires symlinks' )
10441120        super ().setUp ()
1045- 
1046-     def  createTestHierarchy (self ):
10471121        os .mkdir (self .base )
10481122        os .mkdir (os .path .join (self .base , 'dirA' ))
10491123        os .mkdir (os .path .join (self .base , 'dirB' ))
@@ -1082,6 +1156,15 @@ def tearDown(self):
10821156        os .chmod (os .path .join (self .base , 'dirE' ), 0o777 )
10831157        os_helper .rmtree (self .base )
10841158
1159+     def  assertFileNotFound (self , func , * args , ** kwargs ):
1160+         with  self .assertRaises (FileNotFoundError ) as  cm :
1161+             func (* args , ** kwargs )
1162+         self .assertEqual (cm .exception .errno , errno .ENOENT )
1163+ 
1164+     def  assertEqualNormCase (self , path_a , path_b ):
1165+         normcase  =  self .parser .normcase 
1166+         self .assertEqual (normcase (path_a ), normcase (path_b ))
1167+ 
10851168    def  tempdir (self ):
10861169        d  =  os_helper ._longpath (tempfile .mkdtemp (suffix = '-dirD' ,
10871170                                                 dir = os .getcwd ()))
@@ -2747,6 +2830,24 @@ def test_iterdir_symlink(self):
27472830        expected  =  { P (self .base , 'linkB' , q ) for  q  in  ['fileB' , 'linkD' ] }
27482831        self .assertEqual (paths , expected )
27492832
2833+     @needs_posix  
2834+     def  test_glob_posix (self ):
2835+         P  =  self .cls 
2836+         p  =  P (self .base )
2837+         q  =  p  /  "FILEa" 
2838+         given  =  set (p .glob ("FILEa" ))
2839+         expect  =  {q } if  q .info .exists () else  set ()
2840+         self .assertEqual (given , expect )
2841+         self .assertEqual (set (p .glob ("FILEa*" )), set ())
2842+ 
2843+     @needs_windows  
2844+     def  test_glob_windows (self ):
2845+         P  =  self .cls 
2846+         p  =  P (self .base )
2847+         self .assertEqual (set (p .glob ("FILEa" )), { P (self .base , "fileA" ) })
2848+         self .assertEqual (set (p .glob ("*a\\ " )), { P (self .base , "dirA/" ) })
2849+         self .assertEqual (set (p .glob ("F*a" )), { P (self .base , "fileA" ) })
2850+ 
27502851    def  test_glob_empty_pattern (self ):
27512852        p  =  self .cls ('' )
27522853        with  self .assertRaisesRegex (ValueError , 'Unacceptable pattern' ):
@@ -3335,7 +3436,7 @@ def test_group_windows(self):
33353436            P ('c:/' ).group ()
33363437
33373438
3338- class  PathWalkTest (test_pathlib_abc . ReadablePathWalkTest ):
3439+ class  PathWalkTest (unittest . TestCase ):
33393440    cls  =  pathlib .Path 
33403441    base  =  PathTest .base 
33413442    can_symlink  =  PathTest .can_symlink 
@@ -3344,9 +3445,13 @@ def setUp(self):
33443445        name  =  self .id ().split ('.' )[- 1 ]
33453446        if  name  in  _tests_needing_symlinks  and  not  self .can_symlink :
33463447            self .skipTest ('requires symlinks' )
3347-         super ().setUp ()
3448+         self .walk_path  =  self .cls (self .base , "TEST1" )
3449+         self .sub1_path  =  self .walk_path  /  "SUB1" 
3450+         self .sub11_path  =  self .sub1_path  /  "SUB11" 
3451+         self .sub2_path  =  self .walk_path  /  "SUB2" 
3452+         self .link_path  =  self .sub2_path  /  "link" 
3453+         self .sub2_tree  =  (self .sub2_path , [], ["tmp3" ])
33483454
3349-     def  createTestHierarchy (self ):
33503455        # Build: 
33513456        #     TESTFN/ 
33523457        #       TEST1/              a file kid and two directory kids 
0 commit comments