17
17
18
18
19
19
supports_symlinks = True
20
- if os .name == 'nt' :
21
- import nt
22
- if sys .getwindowsversion ()[:2 ] >= (6 , 0 ):
23
- from nt import _getfinalpathname
24
- else :
25
- supports_symlinks = False
26
- _getfinalpathname = None
27
- else :
28
- nt = None
29
20
30
21
31
22
__all__ = [
32
- "PurePath" , "PurePosixPath" , "PureWindowsPath" ,
33
- "Path" , "PosixPath" , "WindowsPath" ,
23
+ "PurePath" , "PurePosixPath" ,
24
+ "Path" , "PosixPath" ,
34
25
]
35
26
36
27
#
@@ -119,178 +110,13 @@ def join_parsed_parts(self, drv, root, parts, drv2, root2, parts2):
119
110
return drv2 , root2 , parts2
120
111
121
112
122
- class _WindowsFlavour (_Flavour ):
123
- # Reference for Windows paths can be found at
124
- # http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx
125
-
126
- sep = '\\ '
127
- altsep = '/'
128
- has_drv = True
129
- pathmod = ntpath
130
-
131
- is_supported = (os .name == 'nt' )
132
-
133
- drive_letters = set ('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' )
134
- ext_namespace_prefix = '\\ \\ ?\\ '
135
-
136
- reserved_names = (
137
- {'CON' , 'PRN' , 'AUX' , 'NUL' } |
138
- {'COM%d' % i for i in range (1 , 10 )} |
139
- {'LPT%d' % i for i in range (1 , 10 )}
140
- )
141
-
142
- # Interesting findings about extended paths:
143
- # - '\\?\c:\a', '//?/c:\a' and '//?/c:/a' are all supported
144
- # but '\\?\c:/a' is not
145
- # - extended paths are always absolute; "relative" extended paths will
146
- # fail.
147
-
148
- def splitroot (self , part , sep = sep ):
149
- first = part [0 :1 ]
150
- second = part [1 :2 ]
151
- if (second == sep and first == sep ):
152
- # XXX extended paths should also disable the collapsing of "."
153
- # components (according to MSDN docs).
154
- prefix , part = self ._split_extended_path (part )
155
- first = part [0 :1 ]
156
- second = part [1 :2 ]
157
- else :
158
- prefix = ''
159
- third = part [2 :3 ]
160
- if (second == sep and first == sep and third != sep ):
161
- # is a UNC path:
162
- # vvvvvvvvvvvvvvvvvvvvv root
163
- # \\machine\mountpoint\directory\etc\...
164
- # directory ^^^^^^^^^^^^^^
165
- index = part .find (sep , 2 )
166
- if index != - 1 :
167
- index2 = part .find (sep , index + 1 )
168
- # a UNC path can't have two slashes in a row
169
- # (after the initial two)
170
- if index2 != index + 1 :
171
- if index2 == - 1 :
172
- index2 = len (part )
173
- if prefix :
174
- return prefix + part [1 :index2 ], sep , part [index2 + 1 :]
175
- else :
176
- return part [:index2 ], sep , part [index2 + 1 :]
177
- drv = root = ''
178
- if second == ':' and first in self .drive_letters :
179
- drv = part [:2 ]
180
- part = part [2 :]
181
- first = third
182
- if first == sep :
183
- root = first
184
- part = part .lstrip (sep )
185
- return prefix + drv , root , part
186
-
187
- def casefold (self , s ):
188
- return s .lower ()
189
-
190
- def casefold_parts (self , parts ):
191
- return [p .lower () for p in parts ]
192
-
193
- def compile_pattern (self , pattern ):
194
- return re .compile (fnmatch .translate (pattern ), re .IGNORECASE ).fullmatch
195
-
196
- def resolve (self , path , strict = False ):
197
- s = str (path )
198
- if not s :
199
- return os .getcwd ()
200
- previous_s = None
201
- if _getfinalpathname is not None :
202
- if strict :
203
- return self ._ext_to_normal (_getfinalpathname (s ))
204
- else :
205
- tail_parts = [] # End of the path after the first one not found
206
- while True :
207
- try :
208
- s = self ._ext_to_normal (_getfinalpathname (s ))
209
- except FileNotFoundError :
210
- previous_s = s
211
- s , tail = os .path .split (s )
212
- tail_parts .append (tail )
213
- if previous_s == s :
214
- return path
215
- else :
216
- return os .path .join (s , * reversed (tail_parts ))
217
- # Means fallback on absolute
218
- return None
219
-
220
- def _split_extended_path (self , s , ext_prefix = ext_namespace_prefix ):
221
- prefix = ''
222
- if s .startswith (ext_prefix ):
223
- prefix = s [:4 ]
224
- s = s [4 :]
225
- if s .startswith ('UNC\\ ' ):
226
- prefix += s [:3 ]
227
- s = '\\ ' + s [3 :]
228
- return prefix , s
229
-
230
- def _ext_to_normal (self , s ):
231
- # Turn back an extended path into a normal DOS-like path
232
- return self ._split_extended_path (s )[1 ]
233
-
234
- def is_reserved (self , parts ):
235
- # NOTE: the rules for reserved names seem somewhat complicated
236
- # (e.g. r"..\NUL" is reserved but not r"foo\NUL").
237
- # We err on the side of caution and return True for paths which are
238
- # not considered reserved by Windows.
239
- if not parts :
240
- return False
241
- if parts [0 ].startswith ('\\ \\ ' ):
242
- # UNC paths are never reserved
243
- return False
244
- return parts [- 1 ].partition ('.' )[0 ].upper () in self .reserved_names
245
-
246
- def make_uri (self , path ):
247
- # Under Windows, file URIs use the UTF-8 encoding.
248
- drive = path .drive
249
- if len (drive ) == 2 and drive [1 ] == ':' :
250
- # It's a path on a local drive => 'file:///c:/a/b'
251
- rest = path .as_posix ()[2 :].lstrip ('/' )
252
- return 'file:///%s/%s' % (
253
- drive , urlquote_from_bytes (rest .encode ('utf-8' )))
254
- else :
255
- # It's a path on a network drive => 'file://host/share/a/b'
256
- return 'file:' + urlquote_from_bytes (path .as_posix ().encode ('utf-8' ))
257
-
258
- def gethomedir (self , username ):
259
- if 'USERPROFILE' in os .environ :
260
- userhome = os .environ ['USERPROFILE' ]
261
- elif 'HOMEPATH' in os .environ :
262
- try :
263
- drv = os .environ ['HOMEDRIVE' ]
264
- except KeyError :
265
- drv = ''
266
- userhome = drv + os .environ ['HOMEPATH' ]
267
- else :
268
- raise RuntimeError ("Can't determine home directory" )
269
-
270
- if username :
271
- # Try to guess user home directory. By default all users
272
- # directories are located in the same place and are named by
273
- # corresponding usernames. If current user home directory points
274
- # to nonstandard place, this guess is likely wrong.
275
- if os .environ ['USERNAME' ] != username :
276
- drv , root , parts = self .parse_parts ((userhome ,))
277
- if parts [- 1 ] != os .environ ['USERNAME' ]:
278
- raise RuntimeError ("Can't determine home directory "
279
- "for %r" % username )
280
- parts [- 1 ] = username
281
- if drv or root :
282
- userhome = drv + root + self .join (parts [1 :])
283
- else :
284
- userhome = self .join (parts )
285
- return userhome
286
-
287
113
class _PosixFlavour (_Flavour ):
288
114
sep = '/'
289
115
altsep = ''
290
116
has_drv = False
291
117
pathmod = posixpath
292
118
293
- is_supported = ( os . name != 'nt' )
119
+ is_supported = True
294
120
295
121
def splitroot (self , part , sep = sep ):
296
122
if part and part [0 ] == sep :
@@ -449,17 +275,10 @@ def replace(self, src, dst):
449
275
450
276
mkdir = os .mkdir
451
277
452
- if nt :
453
- if supports_symlinks :
454
- symlink = os .symlink
455
- else :
456
- def symlink (a , b , target_is_directory ):
457
- raise NotImplementedError ("symlink() not available on this system" )
458
- else :
459
- # Under POSIX, os.symlink() takes two args
460
- @staticmethod
461
- def symlink (a , b , target_is_directory ):
462
- return os .symlink (a , b )
278
+ # Under POSIX, os.symlink() takes two args
279
+ @staticmethod
280
+ def symlink (a , b , target_is_directory ):
281
+ return os .symlink (a , b )
463
282
464
283
utime = os .utime
465
284
@@ -660,10 +479,9 @@ class PurePath(object):
660
479
"""Base class for manipulating paths without I/O.
661
480
662
481
PurePath represents a filesystem path and offers operations which
663
- don't imply any actual filesystem I/O. Depending on your system,
664
- instantiating a PurePath will return either a PurePosixPath or a
665
- PureWindowsPath object. You can also instantiate either of these classes
666
- directly, regardless of your system.
482
+ don't imply any actual filesystem I/O. Instantiating a PurePath will
483
+ return a PurePosixPath object. You can also instantiate either of
484
+ these classes directly, regardless of your system.
667
485
"""
668
486
__slots__ = (
669
487
'_drv' , '_root' , '_parts' ,
@@ -677,7 +495,7 @@ def __new__(cls, *args):
677
495
new PurePath object.
678
496
"""
679
497
if cls is PurePath :
680
- cls = PureWindowsPath if os . name == 'nt' else PurePosixPath
498
+ cls = PurePosixPath
681
499
return cls ._from_parts (args )
682
500
683
501
def __reduce__ (self ):
@@ -1059,35 +877,24 @@ class PurePosixPath(PurePath):
1059
877
__slots__ = ()
1060
878
1061
879
1062
- class PureWindowsPath (PurePath ):
1063
- """PurePath subclass for Windows systems.
1064
-
1065
- On a Windows system, instantiating a PurePath should return this object.
1066
- However, you can also instantiate it directly on any system.
1067
- """
1068
- _flavour = _windows_flavour
1069
- __slots__ = ()
1070
-
1071
-
1072
880
# Filesystem-accessing classes
1073
881
1074
882
1075
883
class Path (PurePath ):
1076
884
"""PurePath subclass that can make system calls.
1077
885
1078
886
Path represents a filesystem path but unlike PurePath, also offers
1079
- methods to do system calls on path objects. Depending on your system,
1080
- instantiating a Path will return either a PosixPath or a WindowsPath
1081
- object. You can also instantiate a PosixPath or WindowsPath directly,
1082
- but cannot instantiate a WindowsPath on a POSIX system or vice versa.
887
+ methods to do system calls on path objects. Instantiating a Path will
888
+ return a PosixPath object. You can also instantiate a PosixPath
889
+ directly.
1083
890
"""
1084
891
__slots__ = (
1085
892
'_accessor' ,
1086
893
)
1087
894
1088
895
def __new__ (cls , * args , ** kwargs ):
1089
896
if cls is Path :
1090
- cls = WindowsPath if os . name == 'nt' else PosixPath
897
+ cls = PosixPath
1091
898
self = cls ._from_parts (args , init = False )
1092
899
if not self ._flavour .is_supported :
1093
900
raise NotImplementedError ("cannot instantiate %r on your system"
@@ -1209,8 +1016,6 @@ def absolute(self):
1209
1016
# XXX untested yet!
1210
1017
if self .is_absolute ():
1211
1018
return self
1212
- # FIXME this must defer to the specific flavour (and, under Windows,
1213
- # use nt._getfullpathname())
1214
1019
obj = self ._from_parts ([os .getcwd ()] + self ._parts , init = False )
1215
1020
obj ._init (template = self )
1216
1021
return obj
@@ -1585,12 +1390,3 @@ class PosixPath(Path, PurePosixPath):
1585
1390
"""
1586
1391
__slots__ = ()
1587
1392
1588
- class WindowsPath (Path , PureWindowsPath ):
1589
- """Path subclass for Windows systems.
1590
-
1591
- On a Windows system, instantiating a Path should return this object.
1592
- """
1593
- __slots__ = ()
1594
-
1595
- def is_mount (self ):
1596
- raise NotImplementedError ("Path.is_mount() is unsupported on this system" )
0 commit comments