37
37
HAVE_FWALK_BYTES = HAVE_FWALK and sys .version_info >= (3 , 7 )
38
38
39
39
40
+ class FSNodeType (enum .Enum ):
41
+ FILE = enum .auto ()
42
+ DIRECTORY = enum .auto ()
43
+
44
+
45
+ #XXX: This should be a generic `ty.NamedTuple` subclass, but GH/python/mypy#685 …
46
+ class FSNodeEntry (ty .Generic [AnyStr ]):
47
+ type : FSNodeType
48
+ path : AnyStr
49
+ relpath : AnyStr
50
+ name : AnyStr
51
+ parentfd : ty .Optional [int ]
52
+
53
+ def __init__ (
54
+ self ,
55
+ type : FSNodeType ,
56
+ path : AnyStr ,
57
+ relpath : AnyStr ,
58
+ name : AnyStr ,
59
+ parentfd : ty .Optional [int ]) -> None :
60
+ self .type = type
61
+ self .path = path
62
+ self .relpath = relpath
63
+ self .name = name
64
+ self .parentfd = parentfd
65
+
66
+ def __repr__ (self ) -> str :
67
+ return (
68
+ f'FSNodeEntry('
69
+ f'type={ self .type !r} , '
70
+ f'path={ self .path !r} , '
71
+ f'relpath={ self .relpath !r} , '
72
+ f'name={ self .name !r} , '
73
+ f'parentfd={ self .parentfd !r} '
74
+ f')'
75
+ )
76
+
77
+ def __str__ (self ) -> str :
78
+ return str (self .path )
79
+
80
+
40
81
class Matcher (ty .Generic [AnyStr ], metaclass = abc .ABCMeta ):
41
82
"""Represents a type that can match on file paths and decide whether they
42
83
should be included in some file scanning/adding operation"""
@@ -466,26 +507,10 @@ def _recursive_matcher_from_spec(spec: match_spec_t[AnyStr], *,
466
507
raise MatcherSpecInvalidError (spec )
467
508
468
509
469
- if ty .TYPE_CHECKING :
470
- from .filescanner_ty import FSNodeType , FSNodeEntry
471
- else :
472
- class FSNodeType (enum .Enum ):
473
- FILE = enum .auto ()
474
- DIRECTORY = enum .auto ()
475
-
476
- FSNodeEntry = ty .NamedTuple ("FSNodeEntry" , [
477
- ("type" , FSNodeType ),
478
- ("path" , AnyStr ),
479
- ("relpath" , AnyStr ),
480
- ("name" , AnyStr ),
481
- ("parentfd" , ty .Optional [int ])
482
- ])
483
-
484
-
485
- class walk (ty .Generator [FSNodeEntry , ty .Any , None ], ty .Generic [AnyStr ]):
510
+ class walk (ty .Generator [FSNodeEntry [AnyStr ], ty .Any , None ], ty .Generic [AnyStr ]):
486
511
__slots__ = ("_generator" , "_close_fd" )
487
512
488
- _generator : ty .Generator [FSNodeEntry , None , None ]
513
+ _generator : ty .Generator [FSNodeEntry [ AnyStr ], ty . Any , None ]
489
514
_close_fd : ty .Optional [int ]
490
515
491
516
def __init__ (
@@ -577,7 +602,7 @@ def __init__(
577
602
def __iter__ (self ) -> 'walk[AnyStr]' :
578
603
return self
579
604
580
- def __next__ (self ) -> FSNodeEntry :
605
+ def __next__ (self ) -> FSNodeEntry [ AnyStr ] :
581
606
return next (self ._generator )
582
607
583
608
def __enter__ (self ) -> 'walk[AnyStr]' :
@@ -586,21 +611,21 @@ def __enter__(self) -> 'walk[AnyStr]':
586
611
def __exit__ (self , * a : ty .Any ) -> None :
587
612
self .close ()
588
613
589
- def send (self , value : ty .Any ) -> FSNodeEntry :
614
+ def send (self , value : ty .Any ) -> FSNodeEntry [ AnyStr ] :
590
615
return self ._generator .send (value )
591
616
592
617
@ty .overload
593
618
def throw (self , typ : ty .Type [BaseException ], # noqa: E704
594
619
val : ty .Union [BaseException , object ] = ...,
595
- tb : ty .Optional [types .TracebackType ] = ...) -> FSNodeEntry : ...
620
+ tb : ty .Optional [types .TracebackType ] = ...) -> FSNodeEntry [ AnyStr ] : ...
596
621
597
622
@ty .overload
598
623
def throw (self , typ : BaseException , val : None = ..., # noqa: E704
599
- tb : ty .Optional [types .TracebackType ] = ...) -> FSNodeEntry : ...
624
+ tb : ty .Optional [types .TracebackType ] = ...) -> FSNodeEntry [ AnyStr ] : ...
600
625
601
626
def throw (self , typ : ty .Union [ty .Type [BaseException ], BaseException ],
602
627
val : ty .Union [BaseException , object ] = None ,
603
- tb : ty .Optional [types .TracebackType ] = None ) -> FSNodeEntry :
628
+ tb : ty .Optional [types .TracebackType ] = None ) -> FSNodeEntry [ AnyStr ] :
604
629
try :
605
630
if isinstance (typ , type ):
606
631
bt = ty .cast (ty .Type [BaseException ], typ ) # type: ignore[redundant-cast]
@@ -653,7 +678,11 @@ def _walk_wide(
653
678
dot : AnyStr ,
654
679
directory : ty .Union [AnyStr , int ],
655
680
follow_symlinks : bool
656
- ) -> ty .Iterator [ty .Tuple [AnyStr , ty .List [AnyStr ], ty .List [AnyStr ], ty .Optional [int ]]]:
681
+ ) -> ty .Generator [
682
+ ty .Tuple [AnyStr , ty .List [AnyStr ], ty .List [AnyStr ], ty .Optional [int ]],
683
+ ty .Any ,
684
+ None
685
+ ]:
657
686
"""
658
687
Return a four-part tuple just like os.fwalk does, even if we won't use os.fwalk.
659
688
@@ -673,7 +702,7 @@ def _walk(
673
702
matcher : Matcher [AnyStr ],
674
703
follow_symlinks : bool ,
675
704
intermediate_dirs : bool
676
- ) -> ty .Generator [FSNodeEntry , ty .Any , None ]:
705
+ ) -> ty .Generator [FSNodeEntry [ AnyStr ] , ty .Any , None ]:
677
706
separator = self ._walk_separator (matcher = matcher , directory_str = directory_str )
678
707
679
708
# TODO: Because os.fsencode can return a byte array, we need to refactor how we use 'sep'
@@ -692,12 +721,12 @@ def _walk(
692
721
693
722
# Always report the top-level directory even if nothing therein is matched
694
723
reported_directories .add (utils .maybe_fsencode ("" , sep ))
695
- yield FSNodeEntry ( # type: ignore[misc] # mypy bug: gh/python/mypy#685
696
- type = FSNodeType .DIRECTORY ,
697
- path = prefix [:- len (sep )], # type: ignore[arg-type]
698
- relpath = dot , # type: ignore[arg-type]
699
- name = dot , # type: ignore[arg-type]
700
- parentfd = None
724
+ yield FSNodeEntry (
725
+ type = FSNodeType .DIRECTORY ,
726
+ path = prefix [:- len (sep )],
727
+ relpath = dot ,
728
+ name = dot ,
729
+ parentfd = None
701
730
)
702
731
703
732
walk_iter = self ._walk_wide (dot = dot , directory = directory , follow_symlinks = follow_symlinks )
@@ -729,32 +758,32 @@ def _walk(
729
758
parent_dirpath = sep .join (parts [0 :(end_offset + 1 )])
730
759
if parent_dirpath not in reported_directories :
731
760
reported_directories .add (parent_dirpath )
732
- yield FSNodeEntry ( # type: ignore[misc] # mypy bug: gh/python/mypy#685
733
- type = FSNodeType .DIRECTORY ,
734
- path = (prefix + parent_dirpath ), # type: ignore[arg-type]
735
- relpath = parent_dirpath , # type: ignore[arg-type]
736
- name = parts [end_offset ], # type: ignore[arg-type]
737
- parentfd = None
761
+ yield FSNodeEntry (
762
+ type = FSNodeType .DIRECTORY ,
763
+ path = (prefix + parent_dirpath ),
764
+ relpath = parent_dirpath ,
765
+ name = parts [end_offset ],
766
+ parentfd = None
738
767
)
739
768
intermediates_reported = True
740
769
741
770
# Report the target file or directory
742
771
if is_dir :
743
772
reported_directories .add (filepath )
744
- yield FSNodeEntry ( # type: ignore[misc] # mypy bug: gh/python/mypy#685
745
- type = FSNodeType .DIRECTORY ,
746
- path = (prefix + filepath ), # type: ignore[arg-type]
747
- relpath = filepath , # type: ignore[arg-type]
748
- name = filename , # type: ignore[arg-type]
749
- parentfd = dirfd
773
+ yield FSNodeEntry (
774
+ type = FSNodeType .DIRECTORY ,
775
+ path = (prefix + filepath ),
776
+ relpath = filepath ,
777
+ name = filename ,
778
+ parentfd = dirfd
750
779
)
751
780
else :
752
- yield FSNodeEntry ( # type: ignore[misc] # mypy bug: gh/python/mypy#685
753
- type = FSNodeType .FILE ,
754
- path = (prefix + filepath ), # type: ignore[arg-type]
755
- relpath = filepath , # type: ignore[arg-type]
756
- name = filename , # type: ignore[arg-type]
757
- parentfd = dirfd
781
+ yield FSNodeEntry (
782
+ type = FSNodeType .FILE ,
783
+ path = (prefix + filepath ),
784
+ relpath = filepath ,
785
+ name = filename ,
786
+ parentfd = dirfd
758
787
)
759
788
finally :
760
789
# Make sure the file descriptors bound by `os.fwalk` are freed on error
0 commit comments