@@ -47,7 +47,17 @@ def _get_bothseps(path):
47
47
LCMapStringEx as _LCMapStringEx ,
48
48
LOCALE_NAME_INVARIANT as _LOCALE_NAME_INVARIANT ,
49
49
LCMAP_LOWERCASE as _LCMAP_LOWERCASE )
50
+ except ImportError :
51
+ def normcase (s ):
52
+ """Normalize case of pathname.
50
53
54
+ Makes all characters lowercase and all slashes into backslashes.
55
+ """
56
+ s = os .fspath (s )
57
+ if isinstance (s , bytes ):
58
+ return os .fsencode (os .fsdecode (s ).replace ('/' , '\\ ' ).lower ())
59
+ return s .replace ('/' , '\\ ' ).lower ()
60
+ else :
51
61
def normcase (s ):
52
62
"""Normalize case of pathname.
53
63
@@ -66,16 +76,6 @@ def normcase(s):
66
76
return _LCMapStringEx (_LOCALE_NAME_INVARIANT ,
67
77
_LCMAP_LOWERCASE ,
68
78
s .replace ('/' , '\\ ' ))
69
- except ImportError :
70
- def normcase (s ):
71
- """Normalize case of pathname.
72
-
73
- Makes all characters lowercase and all slashes into backslashes.
74
- """
75
- s = os .fspath (s )
76
- if isinstance (s , bytes ):
77
- return os .fsencode (os .fsdecode (s ).replace ('/' , '\\ ' ).lower ())
78
- return s .replace ('/' , '\\ ' ).lower ()
79
79
80
80
81
81
def isabs (s ):
@@ -279,9 +279,9 @@ def isjunction(path):
279
279
"""Test whether a path is a junction"""
280
280
try :
281
281
st = os .lstat (path )
282
+ return st .st_reparse_tag == stat .IO_REPARSE_TAG_MOUNT_POINT
282
283
except (OSError , ValueError , AttributeError ):
283
284
return False
284
- return bool (st .st_reparse_tag == stat .IO_REPARSE_TAG_MOUNT_POINT )
285
285
else :
286
286
# Use genericpath.isjunction as imported above
287
287
pass
@@ -301,6 +301,8 @@ def isjunction(path):
301
301
from nt import _getvolumepathname
302
302
except ImportError :
303
303
_getvolumepathname = None
304
+
305
+
304
306
def ismount (path ):
305
307
"""Test whether a path is a mount point (a drive root, the root of a
306
308
share, or a mounted volume)"""
@@ -312,24 +314,22 @@ def ismount(path):
312
314
return not tail
313
315
if root and not tail :
314
316
return True
315
-
316
- if _getvolumepathname :
317
- x = path .rstrip (seps )
318
- y = _getvolumepathname (path ).rstrip (seps )
319
- return x .casefold () == y .casefold ()
320
- else :
317
+ if not _getvolumepathname :
321
318
return False
319
+ x = path .rstrip (seps )
320
+ y = _getvolumepathname (path ).rstrip (seps )
321
+ return x .casefold () == y .casefold ()
322
322
323
323
324
324
_reserved_chars = frozenset (
325
- {chr (i ) for i in range (32 )} |
326
- {'"' , '*' , ':' , '<' , '>' , '?' , '|' , '/' , '\\ ' }
325
+ {chr (i ) for i in range (32 )}
326
+ | {'"' , '*' , ':' , '<' , '>' , '?' , '|' , '/' , '\\ ' }
327
327
)
328
328
329
329
_reserved_names = frozenset (
330
- {'CON' , 'PRN' , 'AUX' , 'NUL' , 'CONIN$' , 'CONOUT$' } |
331
- {f'COM{ c } ' for c in '123456789\xb9 \xb2 \xb3 ' } |
332
- {f'LPT{ c } ' for c in '123456789\xb9 \xb2 \xb3 ' }
330
+ {'CON' , 'PRN' , 'AUX' , 'NUL' , 'CONIN$' , 'CONOUT$' }
331
+ | {f'COM{ c } ' for c in '123456789\xb9 \xb2 \xb3 ' }
332
+ | {f'LPT{ c } ' for c in '123456789\xb9 \xb2 \xb3 ' }
333
333
)
334
334
335
335
def isreserved (path ):
@@ -352,9 +352,7 @@ def _isreservedname(name):
352
352
# DOS device names are reserved (e.g. "nul" or "nul .txt"). The rules
353
353
# are complex and vary across Windows versions. On the side of
354
354
# caution, return True for names that may not be reserved.
355
- if name .partition ('.' )[0 ].rstrip (' ' ).upper () in _reserved_names :
356
- return True
357
- return False
355
+ return name .partition ('.' )[0 ].rstrip (' ' ).upper () in _reserved_names
358
356
359
357
360
358
# Expand paths beginning with '~' or '~user'.
@@ -477,19 +475,17 @@ def expandvars(path):
477
475
pathlen = len (path )
478
476
try :
479
477
index = path .index (percent )
478
+ var = path [:index ]
479
+ if environ is None :
480
+ value = os .fsencode (os .environ [os .fsdecode (var )])
481
+ else :
482
+ value = environ [var ]
483
+ res += value
480
484
except ValueError :
481
485
res += percent + path
482
486
index = pathlen - 1
483
- else :
484
- var = path [:index ]
485
- try :
486
- if environ is None :
487
- value = os .fsencode (os .environ [os .fsdecode (var )])
488
- else :
489
- value = environ [var ]
490
- except KeyError :
491
- value = percent + var + percent
492
- res += value
487
+ except KeyError :
488
+ res += percent + var + percent
493
489
elif c == dollar : # variable or '$$'
494
490
if path [index + 1 :index + 2 ] == dollar :
495
491
res += c
@@ -499,19 +495,17 @@ def expandvars(path):
499
495
pathlen = len (path )
500
496
try :
501
497
index = path .index (rbrace )
498
+ var = path [:index ]
499
+ if environ is None :
500
+ value = os .fsencode (os .environ [os .fsdecode (var )])
501
+ else :
502
+ value = environ [var ]
503
+ res += value
502
504
except ValueError :
503
505
res += dollar + brace + path
504
506
index = pathlen - 1
505
- else :
506
- var = path [:index ]
507
- try :
508
- if environ is None :
509
- value = os .fsencode (os .environ [os .fsdecode (var )])
510
- else :
511
- value = environ [var ]
512
- except KeyError :
513
- value = dollar + brace + var + rbrace
514
- res += value
507
+ except KeyError :
508
+ res += dollar + brace + var + rbrace
515
509
else :
516
510
var = path [:0 ]
517
511
index += 1
@@ -525,9 +519,9 @@ def expandvars(path):
525
519
value = os .fsencode (os .environ [os .fsdecode (var )])
526
520
else :
527
521
value = environ [var ]
522
+ res += value
528
523
except KeyError :
529
- value = dollar + var
530
- res += value
524
+ res += dollar + var
531
525
if c :
532
526
index -= 1
533
527
else :
@@ -542,6 +536,12 @@ def expandvars(path):
542
536
try :
543
537
from nt import _path_normpath
544
538
539
+ def normpath (path ):
540
+ """Normalize path, eliminating double slashes, etc."""
541
+ path = os .fspath (path )
542
+ if isinstance (path , bytes ):
543
+ return os .fsencode (_path_normpath (os .fsdecode (path ))) or b"."
544
+ return _path_normpath (path ) or "."
545
545
except ImportError :
546
546
def normpath (path ):
547
547
"""Normalize path, eliminating double slashes, etc."""
@@ -564,29 +564,20 @@ def normpath(path):
564
564
while i < len (comps ):
565
565
if not comps [i ] or comps [i ] == curdir :
566
566
del comps [i ]
567
- elif comps [i ] == pardir :
568
- if i > 0 and comps [i - 1 ] != pardir :
569
- del comps [i - 1 :i + 1 ]
570
- i -= 1
571
- elif i == 0 and root :
572
- del comps [i ]
573
- else :
574
- i += 1
567
+ elif comps [i ] != pardir :
568
+ i += 1
569
+ elif i > 0 and comps [i - 1 ] != pardir :
570
+ del comps [i - 1 :i + 1 ]
571
+ i -= 1
572
+ elif i == 0 and root :
573
+ del comps [i ]
575
574
else :
576
575
i += 1
577
576
# If the path is now empty, substitute '.'
578
577
if not prefix and not comps :
579
578
comps .append (curdir )
580
579
return prefix + sep .join (comps )
581
580
582
- else :
583
- def normpath (path ):
584
- """Normalize path, eliminating double slashes, etc."""
585
- path = os .fspath (path )
586
- if isinstance (path , bytes ):
587
- return os .fsencode (_path_normpath (os .fsdecode (path ))) or b"."
588
- return _path_normpath (path ) or "."
589
-
590
581
591
582
def _abspath_fallback (path ):
592
583
"""Return the absolute version of a path as a fallback function in case
@@ -607,10 +598,8 @@ def _abspath_fallback(path):
607
598
# Return an absolute path.
608
599
try :
609
600
from nt import _getfullpathname
610
-
611
601
except ImportError : # not running on Windows - mock up something sensible
612
602
abspath = _abspath_fallback
613
-
614
603
else : # use native Windows method on Windows
615
604
def abspath (path ):
616
605
"""Return the absolute version of a path."""
@@ -697,28 +686,28 @@ def _getfinalpathname_nonstrict(path):
697
686
except OSError as ex :
698
687
if ex .winerror not in allowed_winerror :
699
688
raise
689
+ try :
690
+ # The OS could not resolve this path fully, so we attempt
691
+ # to follow the link ourselves. If we succeed, join the tail
692
+ # and return.
693
+ new_path = _readlink_deep (path )
694
+ if new_path != path :
695
+ return join (new_path , tail ) if tail else new_path
696
+ except OSError :
697
+ # If we fail to readlink(), let's keep traversing
698
+ pass
699
+ # If we get these errors, try to get the real name of the file without accessing it.
700
+ if ex .winerror in (1 , 5 , 32 , 50 , 87 , 1920 , 1921 ):
700
701
try :
701
- # The OS could not resolve this path fully, so we attempt
702
- # to follow the link ourselves. If we succeed, join the tail
703
- # and return.
704
- new_path = _readlink_deep (path )
705
- if new_path != path :
706
- return join (new_path , tail ) if tail else new_path
702
+ name = _findfirstfile (path )
703
+ path , _ = split (path )
707
704
except OSError :
708
- # If we fail to readlink(), let's keep traversing
709
- pass
710
- # If we get these errors, try to get the real name of the file without accessing it.
711
- if ex .winerror in (1 , 5 , 32 , 50 , 87 , 1920 , 1921 ):
712
- try :
713
- name = _findfirstfile (path )
714
- path , _ = split (path )
715
- except OSError :
716
- path , name = split (path )
717
- else :
718
705
path , name = split (path )
719
- if path and not name :
720
- return path + tail
721
- tail = join (name , tail ) if tail else name
706
+ else :
707
+ path , name = split (path )
708
+ if path and not name :
709
+ return path + tail
710
+ tail = join (name , tail ) if tail else name
722
711
return tail
723
712
724
713
def realpath (path , * , strict = False ):
@@ -904,12 +893,13 @@ def commonpath(paths):
904
893
905
894
try :
906
895
from nt import _path_isdevdrive
896
+ except ImportError :
897
+ # Use genericpath.isdevdrive as imported above
898
+ pass
899
+ else :
907
900
def isdevdrive (path ):
908
901
"""Determines whether the specified path is on a Windows Dev Drive."""
909
902
try :
910
903
return _path_isdevdrive (abspath (path ))
911
904
except OSError :
912
905
return False
913
- except ImportError :
914
- # Use genericpath.isdevdrive as imported above
915
- pass
0 commit comments