@@ -233,14 +233,10 @@ def __repr__(self):
233
233
return "<{}.parents>" .format (type (self ._path ).__name__ )
234
234
235
235
236
- class PurePath (object ):
237
- """Base class for manipulating paths without I/O .
236
+ class _LexicalPath (object ):
237
+ """Base class for manipulating paths using only lexical operations .
238
238
239
- PurePath represents a filesystem path and offers operations which
240
- don't imply any actual filesystem I/O. Depending on your system,
241
- instantiating a PurePath will return either a PurePosixPath or a
242
- PureWindowsPath object. You can also instantiate either of these classes
243
- directly, regardless of your system.
239
+ This class does not provide __fspath__(), __bytes__() or as_uri().
244
240
"""
245
241
246
242
__slots__ = (
@@ -280,16 +276,6 @@ class PurePath(object):
280
276
)
281
277
_flavour = os .path
282
278
283
- def __new__ (cls , * args , ** kwargs ):
284
- """Construct a PurePath from one or several strings and or existing
285
- PurePath objects. The strings and path objects are combined so as
286
- to yield a canonicalized path, which is incorporated into the
287
- new PurePath object.
288
- """
289
- if cls is PurePath :
290
- cls = PureWindowsPath if os .name == 'nt' else PurePosixPath
291
- return object .__new__ (cls )
292
-
293
279
def __reduce__ (self ):
294
280
# Using the parts tuple helps share interned path parts
295
281
# when pickling related paths.
@@ -298,7 +284,7 @@ def __reduce__(self):
298
284
def __init__ (self , * args ):
299
285
paths = []
300
286
for arg in args :
301
- if isinstance (arg , PurePath ):
287
+ if isinstance (arg , _LexicalPath ):
302
288
path = arg ._raw_path
303
289
else :
304
290
try :
@@ -378,43 +364,15 @@ def __str__(self):
378
364
self ._tail ) or '.'
379
365
return self ._str
380
366
381
- def __fspath__ (self ):
382
- return str (self )
383
-
384
367
def as_posix (self ):
385
368
"""Return the string representation of the path with forward (/)
386
369
slashes."""
387
370
f = self ._flavour
388
371
return str (self ).replace (f .sep , '/' )
389
372
390
- def __bytes__ (self ):
391
- """Return the bytes representation of the path. This is only
392
- recommended to use under Unix."""
393
- return os .fsencode (self )
394
-
395
373
def __repr__ (self ):
396
374
return "{}({!r})" .format (self .__class__ .__name__ , self .as_posix ())
397
375
398
- def as_uri (self ):
399
- """Return the path as a 'file' URI."""
400
- if not self .is_absolute ():
401
- raise ValueError ("relative path can't be expressed as a file URI" )
402
-
403
- drive = self .drive
404
- if len (drive ) == 2 and drive [1 ] == ':' :
405
- # It's a path on a local drive => 'file:///c:/a/b'
406
- prefix = 'file:///' + drive
407
- path = self .as_posix ()[2 :]
408
- elif drive :
409
- # It's a path on a network drive => 'file://host/share/a/b'
410
- prefix = 'file:'
411
- path = self .as_posix ()
412
- else :
413
- # It's a posix path => 'file:///etc/hosts'
414
- prefix = 'file://'
415
- path = str (self )
416
- return prefix + urlquote_from_bytes (os .fsencode (path ))
417
-
418
376
@property
419
377
def _str_normcase (self ):
420
378
# String with normalized case, for hashing and equality checks
@@ -434,7 +392,7 @@ def _parts_normcase(self):
434
392
return self ._parts_normcase_cached
435
393
436
394
def __eq__ (self , other ):
437
- if not isinstance (other , PurePath ):
395
+ if not isinstance (other , _LexicalPath ):
438
396
return NotImplemented
439
397
return self ._str_normcase == other ._str_normcase and self ._flavour is other ._flavour
440
398
@@ -446,22 +404,22 @@ def __hash__(self):
446
404
return self ._hash
447
405
448
406
def __lt__ (self , other ):
449
- if not isinstance (other , PurePath ) or self ._flavour is not other ._flavour :
407
+ if not isinstance (other , _LexicalPath ) or self ._flavour is not other ._flavour :
450
408
return NotImplemented
451
409
return self ._parts_normcase < other ._parts_normcase
452
410
453
411
def __le__ (self , other ):
454
- if not isinstance (other , PurePath ) or self ._flavour is not other ._flavour :
412
+ if not isinstance (other , _LexicalPath ) or self ._flavour is not other ._flavour :
455
413
return NotImplemented
456
414
return self ._parts_normcase <= other ._parts_normcase
457
415
458
416
def __gt__ (self , other ):
459
- if not isinstance (other , PurePath ) or self ._flavour is not other ._flavour :
417
+ if not isinstance (other , _LexicalPath ) or self ._flavour is not other ._flavour :
460
418
return NotImplemented
461
419
return self ._parts_normcase > other ._parts_normcase
462
420
463
421
def __ge__ (self , other ):
464
- if not isinstance (other , PurePath ) or self ._flavour is not other ._flavour :
422
+ if not isinstance (other , _LexicalPath ) or self ._flavour is not other ._flavour :
465
423
return NotImplemented
466
424
return self ._parts_normcase >= other ._parts_normcase
467
425
@@ -707,6 +665,57 @@ def match(self, path_pattern, *, case_sensitive=None):
707
665
return False
708
666
return True
709
667
668
+
669
+ class PurePath (_LexicalPath ):
670
+ """Base class for manipulating paths without I/O.
671
+
672
+ PurePath represents a filesystem path and offers operations which
673
+ don't imply any actual filesystem I/O. Depending on your system,
674
+ instantiating a PurePath will return either a PurePosixPath or a
675
+ PureWindowsPath object. You can also instantiate either of these classes
676
+ directly, regardless of your system.
677
+ """
678
+ __slots__ = ()
679
+
680
+ def __new__ (cls , * args , ** kwargs ):
681
+ """Construct a PurePath from one or several strings and or existing
682
+ PurePath objects. The strings and path objects are combined so as
683
+ to yield a canonicalized path, which is incorporated into the
684
+ new PurePath object.
685
+ """
686
+ if cls is PurePath :
687
+ cls = PureWindowsPath if os .name == 'nt' else PurePosixPath
688
+ return object .__new__ (cls )
689
+
690
+ def __fspath__ (self ):
691
+ return str (self )
692
+
693
+ def __bytes__ (self ):
694
+ """Return the bytes representation of the path. This is only
695
+ recommended to use under Unix."""
696
+ return os .fsencode (self )
697
+
698
+ def as_uri (self ):
699
+ """Return the path as a 'file' URI."""
700
+ if not self .is_absolute ():
701
+ raise ValueError ("relative path can't be expressed as a file URI" )
702
+
703
+ drive = self .drive
704
+ if len (drive ) == 2 and drive [1 ] == ':' :
705
+ # It's a path on a local drive => 'file:///c:/a/b'
706
+ prefix = 'file:///' + drive
707
+ path = self .as_posix ()[2 :]
708
+ elif drive :
709
+ # It's a path on a network drive => 'file://host/share/a/b'
710
+ prefix = 'file:'
711
+ path = self .as_posix ()
712
+ else :
713
+ # It's a posix path => 'file:///etc/hosts'
714
+ prefix = 'file://'
715
+ path = str (self )
716
+ return prefix + urlquote_from_bytes (os .fsencode (path ))
717
+
718
+
710
719
# Can't subclass os.PathLike from PurePath and keep the constructor
711
720
# optimizations in PurePath.__slots__.
712
721
os .PathLike .register (PurePath )
0 commit comments