@@ -433,7 +433,7 @@ def exists(path: str) -> bool:
433
433
return True
434
434
435
435
436
- def is_file_hidden_win (abs_path : str , stat_res : Optional [Any ] = None ) -> bool :
436
+ def is_file_hidden_win (abs_path : str | Path , stat_res : Optional [Any ] = None ) -> bool :
437
437
"""Is a file hidden?
438
438
439
439
This only checks the file itself; it should be called in combination with
@@ -449,7 +449,8 @@ def is_file_hidden_win(abs_path: str, stat_res: Optional[Any] = None) -> bool:
449
449
The result of calling stat() on abs_path. If not passed, this function
450
450
will call stat() internally.
451
451
"""
452
- if Path (abs_path ).name .startswith ("." ):
452
+ abs_path = Path (abs_path )
453
+ if abs_path .name .startswith ("." ):
453
454
return True
454
455
455
456
if stat_res is None :
@@ -494,12 +495,13 @@ def is_file_hidden_posix(abs_path: str, stat_res: Optional[Any] = None) -> bool:
494
495
The result of calling stat() on abs_path. If not passed, this function
495
496
will call stat() internally.
496
497
"""
497
- if Path (abs_path ).name .startswith ("." ):
498
+ abs_path = Path (abs_path )
499
+ if abs_path .name .startswith ("." ):
498
500
return True
499
501
500
502
if stat_res is None or stat .S_ISLNK (stat_res .st_mode ):
501
503
try :
502
- stat_res = Path ( abs_path ) .stat ()
504
+ stat_res = abs_path .stat ()
503
505
except OSError as e :
504
506
if e .errno == errno .ENOENT :
505
507
return False
@@ -524,7 +526,7 @@ def is_file_hidden_posix(abs_path: str, stat_res: Optional[Any] = None) -> bool:
524
526
is_file_hidden = is_file_hidden_posix
525
527
526
528
527
- def is_hidden (abs_path : str , abs_root : str = "" ) -> bool :
529
+ def is_hidden (abs_path : str | Path , abs_root : str | Path = "" ) -> bool :
528
530
"""Is a file hidden or contained in a hidden directory?
529
531
530
532
This will start with the rightmost path element and work backwards to the
@@ -538,42 +540,56 @@ def is_hidden(abs_path: str, abs_root: str = "") -> bool:
538
540
539
541
Parameters
540
542
----------
541
- abs_path : unicode
543
+ abs_path : str or Path
542
544
The absolute path to check for hidden directories.
543
- abs_root : unicode
545
+ abs_root : str or Path
544
546
The absolute path of the root directory in which hidden directories
545
547
should be checked for.
546
548
"""
547
- abs_path = os .path .normpath (abs_path )
548
- abs_root = os .path .normpath (abs_root )
549
+ abs_path = Path (os .path .normpath (abs_path ))
550
+ if abs_root :
551
+ abs_root = Path (os .path .normpath (abs_root ))
552
+ else :
553
+ abs_root = abs_path .root
549
554
550
555
if abs_path == abs_root :
556
+ # root itself is never hidden
551
557
return False
552
558
559
+ # check that arguments are valid
560
+ if not abs_path .is_absolute ():
561
+ _msg = f"{ abs_path = } is not absolute. abs_path must be absolute."
562
+ raise ValueError (_msg )
563
+ if not abs_root .is_absolute ():
564
+ _msg = f"{ abs_root = } is not absolute. abs_root must be absolute."
565
+ raise ValueError (_msg )
566
+ if not abs_path .is_relative_to (abs_root ):
567
+ _msg = (
568
+ f"{ abs_path = } is not a subdirectory of { abs_root = } . abs_path must be within abs_root."
569
+ )
570
+ raise ValueError (_msg )
571
+
553
572
if is_file_hidden (abs_path ):
554
573
return True
555
574
556
- if not abs_root :
557
- abs_root = abs_path .split (os .sep , 1 )[0 ] + os .sep
558
- inside_root = abs_path [len (abs_root ) :]
559
- if any (part .startswith ("." ) for part in Path (inside_root ).parts ):
575
+ relative_path = abs_path .relative_to (abs_root )
576
+ if any (part .startswith ("." ) for part in relative_path .parts ):
560
577
return True
561
578
562
579
# check UF_HIDDEN on any location up to root.
563
580
# is_file_hidden() already checked the file, so start from its parent dir
564
- path = str (Path (abs_path ).parent )
565
- while path and path .startswith (abs_root ) and path != abs_root :
566
- if not Path (path ).exists ():
567
- path = str (Path (path ).parent )
581
+ for parent in abs_path .parents :
582
+ if not parent .exists ():
568
583
continue
584
+ if parent == abs_root :
585
+ break
569
586
try :
570
587
# may fail on Windows junctions
571
- st = os .lstat (path )
588
+ st = parent .lstat ()
572
589
except OSError :
573
590
return True
574
591
if getattr (st , "st_flags" , 0 ) & UF_HIDDEN :
575
592
return True
576
- path = str (Path (path ).parent )
577
593
578
594
return False
579
595
0 commit comments