2121 re_pattern_t = re_pattern_type = type (re .compile ("" ))
2222
2323
24- if hasattr (enum , "auto" ): #PY36+
25- enum_auto = enum .auto
26- elif not ty .TYPE_CHECKING : #PY35
27- _counter = 0
28-
29- def enum_auto () -> int :
30- global _counter
31- _counter += 1
32- return _counter
24+ enum_auto = enum .auto
3325
3426
3527O_DIRECTORY = getattr (os , "O_DIRECTORY" , 0 ) # type: int
3628
3729
38- HAVE_FWALK = hasattr (os , "fwalk" ) # type: bool
39- HAVE_FWALK_BYTES = HAVE_FWALK and sys .version_info >= (3 , 7 ) # type: bool
30+ HAVE_FWALK : bool = hasattr (os , "fwalk" )
31+ HAVE_FWALK_BYTES = HAVE_FWALK and sys .version_info >= (3 , 7 )
4032
4133
4234class Matcher (ty .Generic [ty .AnyStr ], metaclass = abc .ABCMeta ):
4335 """Represents a type that can match on file paths and decide whether they
4436 should be included in some file scanning/adding operation"""
4537 __slots__ = ("is_binary" ,)
46- #is_binary: bool
47-
38+
4839 def __init__ (self , is_binary : bool = False ) -> None :
49- self .is_binary = is_binary # type: bool
40+ self .is_binary : bool = is_binary
5041
5142 @abc .abstractmethod
5243 def should_descend (self , path : ty .AnyStr ) -> bool :
@@ -111,8 +102,8 @@ def should_report(self, path: ty.AnyStr, *, is_dir: bool) -> utils.Literal_False
111102 return False
112103
113104
114- MATCH_ALL = MatchAll () # type : MatchAll[str]
115- MATCH_NONE = MatchNone () # type : MatchNone[str]
105+ MATCH_ALL : MatchAll [str ] = MatchAll ()
106+ MATCH_NONE : MatchNone [str ] = MatchNone ()
116107
117108
118109class GlobMatcher (Matcher [ty .AnyStr ], ty .Generic [ty .AnyStr ]):
@@ -136,11 +127,7 @@ class emulates. If your are accustomed the globing on real Unix shells
136127 pasting it into a real shell works this may be why.
137128 """
138129 __slots__ = ("period_special" , "_sep" , "_pat" , "_dir_only" )
139- #period_special: bool
140- #_sep: ty.AnyStr
141- #_pat: ty.List[ty.Optional[re_pattern_t[ty.AnyStr]]]
142- #_dir_only: bool
143-
130+
144131 def __init__ (self , pat : ty .AnyStr , * , period_special : bool = True ):
145132 """
146133 Arguments
@@ -153,14 +140,14 @@ def __init__(self, pat: ty.AnyStr, *, period_special: bool = True):
153140 shells allow one to disable this behaviour
154141 """
155142 super ().__init__ (isinstance (pat , bytes ))
156-
157- self .period_special = period_special # type: bool
158-
159- self ._sep = utils .maybe_fsencode (os .path .sep , pat ) # type: ty.AnyStr
160- dblstar = utils .maybe_fsencode ("**" , pat ) # type: ty.AnyStr
161- dot = utils .maybe_fsencode ("." , pat ) # type: ty.AnyStr
162- pat_ndot = utils .maybe_fsencode (r"(?![.])" , pat ) # type: ty.AnyStr
163-
143+
144+ self .period_special : bool = period_special
145+
146+ self ._sep : ty . AnyStr = utils .maybe_fsencode (os .path .sep , pat )
147+ dblstar = utils .maybe_fsencode ("**" , pat )
148+ dot = utils .maybe_fsencode ("." , pat )
149+ pat_ndot = utils .maybe_fsencode (r"(?![.])" , pat )
150+
164151 # Normalize path separator
165152 if os .path .altsep :
166153 pat = pat .replace (utils .maybe_fsencode (os .path .altsep , pat ), self ._sep )
@@ -174,9 +161,9 @@ def __init__(self, pat: ty.AnyStr, *, period_special: bool = True):
174161 # (TBH, I find it hard to see how that is useful, but everybody does it
175162 # and it keeps things consistent overall – something to only match files
176163 # would be nice however.)
177- self ._dir_only = pat .endswith (self ._sep ) # type: bool
178-
179- self ._pat = [] # type : ty.List[ty.Optional[re_pattern_t[ty.AnyStr]]]
164+ self ._dir_only : bool = pat .endswith (self ._sep )
165+
166+ self ._pat : ty .List [ty .Optional [re_pattern_t [ty .AnyStr ]]] = [ ]
180167 for label in pat .split (self ._sep ):
181168 # Skip over useless path components
182169 if len (label ) < 1 or label == dot :
@@ -193,7 +180,6 @@ def __init__(self, pat: ty.AnyStr, *, period_special: bool = True):
193180 "an issue if you need this!" .format (os .fsdecode (label ))
194181 )
195182 else :
196- #re_expr: ty.AnyStr
197183 if not isinstance (label , bytes ):
198184 re_expr = fnmatch .translate (label )
199185 else :
@@ -308,32 +294,30 @@ class ReMatcher(Matcher[ty.AnyStr], ty.Generic[ty.AnyStr]):
308294 own matcher with a proper :meth:`Matcher.should_descend` method.
309295 """
310296 __slots__ = ("_pat" ,)
311- #_pat: re_pattern_t[ty.AnyStr]
312-
297+
313298 def __init__ (self , pat : ty .Union [ty .AnyStr , "re_pattern_t[ty.AnyStr]" ]):
314- self ._pat = re .compile (pat ) # type: re_pattern_t[ty.AnyStr]
315-
299+ self ._pat : "re_pattern_t[ty.AnyStr]" = re .compile (pat )
300+
316301 super ().__init__ (not (self ._pat .flags & re .UNICODE ))
317302
318303 def should_descend (self , path : ty .AnyStr ) -> bool :
319304 return True
320305
321306 def should_report (self , path : ty .AnyStr , * , is_dir : bool ) -> bool :
322- suffix = utils .maybe_fsencode (os .path .sep , path ) if is_dir else type (path )() # type: ty.AnyStr
307+ suffix : ty . AnyStr = utils .maybe_fsencode (os .path .sep , path ) if is_dir else type (path )()
323308 return bool (self ._pat .match (path + suffix ))
324309
325310
326311class MetaMatcher (Matcher [ty .AnyStr ], ty .Generic [ty .AnyStr ]):
327312 """Match files and directories by delegating to other matchers"""
328313 __slots__ = ("_children" ,)
329- #_children: ty.List[Matcher[ty.AnyStr]]
330-
314+
331315 def __init__ (self , children : ty .List [Matcher [ty .AnyStr ]]):
332316 assert len (children ) > 0
333317 super ().__init__ (children [0 ].is_binary )
334-
335- self ._children = children # type : ty.List[Matcher[ty.AnyStr]]
336-
318+
319+ self ._children : ty .List [Matcher [ty .AnyStr ]] = children
320+
337321 def should_descend (self , path : ty .AnyStr ) -> bool :
338322 return any (m .should_descend (path ) for m in self ._children )
339323
@@ -350,13 +334,12 @@ class NoRecusionAdapterMatcher(Matcher[ty.AnyStr], ty.Generic[ty.AnyStr]):
350334 scanner and hence provides ``recursive=False`` semantics.
351335 """
352336 __slots__ = ("_child" ,)
353- #_child: Matcher[ty.AnyStr]
354-
337+
355338 def __init__ (self , child : Matcher [ty .AnyStr ]):
356339 super ().__init__ (child .is_binary )
357-
358- self ._child = child # type : Matcher[ty.AnyStr]
359-
340+
341+ self ._child : Matcher [ty .AnyStr ] = child
342+
360343 def should_descend (self , path : ty .AnyStr ) -> bool :
361344 return False
362345
@@ -367,8 +350,9 @@ def should_report(self, path: ty.AnyStr, *, is_dir: bool) -> bool:
367350
368351if ty .TYPE_CHECKING :
369352 _match_spec_t = ty .Union [ty .AnyStr , re_pattern_t [ty .AnyStr ], Matcher [ty .AnyStr ]]
370- else : # Using `re_pattern_t` here like in the type checking case makes
371- # sphinx_autodoc_typehints explode # noqa: E114
353+ else :
354+ # Using `re_pattern_t` here like in the type checking case makes
355+ # sphinx_autodoc_typehints explode
372356 _match_spec_t = ty .Union [ty .AnyStr , re_pattern_t , Matcher [ty .AnyStr ]]
373357match_spec_t = ty .Union [
374358 ty .Iterable [_match_spec_t [ty .AnyStr ]],
@@ -404,16 +388,20 @@ def matcher_from_spec(spec: match_spec_t[ty.AnyStr], *, # type: ignore[misc] #
404388 elif isinstance (spec , (str , bytes )):
405389 return GlobMatcher (spec , period_special = period_special )
406390 elif isinstance (spec , collections .abc .Iterable ) and not isinstance (spec , Matcher ):
407- spec = ty .cast (ty .Iterable [_match_spec_t [ty .AnyStr ]], spec ) # type: ignore[redundant-cast]
408-
409- matchers = [matcher_from_spec (s , # type: ignore[arg-type] # mypy bug
410- recursive = recursive , period_special = period_special ) for s in spec ]
391+ matchers : ty .List [Matcher [ty .AnyStr ]] = [
392+ matcher_from_spec (
393+ s , # type: ignore[arg-type]
394+ recursive = recursive ,
395+ period_special = period_special )
396+ for s in spec
397+ ]
398+
411399 if len (matchers ) == 0 : # Edge case: Empty list of matchers
412- return MATCH_NONE # type: ignore[return-value]
400+ return MatchNone ()
413401 elif len (matchers ) == 1 : # Edge case: List of exactly one matcher
414- return matchers [0 ] # type: ignore[return-value] # same mypy bug
402+ return matchers [0 ]
415403 else : # Actual list of matchers (plural)
416- return MetaMatcher (matchers ) # type: ignore[arg-type] # same mypy bug
404+ return MetaMatcher (matchers )
417405 else :
418406 return spec
419407
@@ -436,10 +424,7 @@ class FSNodeType(enum.Enum):
436424
437425class walk (ty .Generator [FSNodeEntry , ty .Any , None ], ty .Generic [ty .AnyStr ]):
438426 __slots__ = ("_generator" , "_close_fd" )
439- #_generator: ty.Generator[FSNodeEntry, ty.Any, None]
440- #_close_fd: ty.Optional[int]
441-
442-
427+
443428 def __init__ (
444429 self ,
445430 directory : ty .Union [ty .AnyStr , utils .PathLike [ty .AnyStr ], int ],
@@ -482,43 +467,44 @@ def __init__(
482467 :class:`NoRecusionAdapterMatcher` and hence prevent the scanner from
483468 doing any recursion.
484469 """
485- self ._close_fd = None # type : ty.Optional[int]
486-
470+ self ._close_fd : ty .Optional [int ] = None
471+
487472 # Create matcher object
488- matcher = matcher_from_spec (
489- match_spec , recursive = recursive , period_special = period_special
490- ) # type: Matcher[ty.AnyStr] # type: ignore[assignment]
491-
473+ matcher = matcher_from_spec ( # type: ignore[type-var]
474+ match_spec , recursive = recursive , period_special = period_special # type: ignore[arg-type]
475+ )
476+
492477 # Convert directory path to string …
493478 if isinstance (directory , int ):
494479 if not HAVE_FWALK :
495480 raise NotImplementedError ("Passing a file descriptor as directory is "
496481 "not supported on this platform" )
497-
498- self ._generator = self ._walk (
499- directory , None , matcher , follow_symlinks , intermediate_dirs
500- ) # type: ty.Generator[FSNodeEntry, ty.Any, None]
482+
483+ self ._generator : ty . Generator [ FSNodeEntry , None , None ] = self ._walk (
484+ directory , None , matcher , follow_symlinks , intermediate_dirs # type: ignore[arg-type]
485+ )
501486 else :
502- #directory_str: ty.AnyStr
503- if hasattr (os , "fspath" ): #PY36+
504- directory_str = os .fspath (directory )
505- elif not ty .TYPE_CHECKING : #PY35
506- directory_str = utils .convert_path (directory )
507-
487+ directory_str = os .fspath (directory )
488+
508489 # Best-effort ensure that target directory exists if it is accessed by path
509490 os .stat (directory_str )
510491
511492 # … and possibly open it as a FD if this is supported by the platform
512493 #
513494 # Note: `os.fwalk` support for binary paths was only added in 3.7+.
514- directory_str_or_fd = directory_str # type: ty.Union[ty.AnyStr, int]
495+ directory_str_or_fd = directory_str
515496 if HAVE_FWALK and (not isinstance (directory_str , bytes ) or HAVE_FWALK_BYTES ):
516- self ._close_fd = directory_str_or_fd = os .open (directory_str , os .O_RDONLY | O_DIRECTORY )
517-
497+ fd = os .open (directory_str , os .O_RDONLY | O_DIRECTORY )
498+ self ._close_fd = directory_str_or_fd = fd # type: ignore[assignment]
499+
518500 self ._generator = self ._walk (
519- directory_str_or_fd , directory_str , matcher , follow_symlinks , intermediate_dirs
501+ directory_str_or_fd ,
502+ directory_str ,
503+ matcher , # type: ignore[arg-type]
504+ follow_symlinks ,
505+ intermediate_dirs
520506 )
521-
507+
522508 def __iter__ (self ) -> 'walk[ty.AnyStr]' :
523509 return self
524510
@@ -548,7 +534,8 @@ def throw(self, typ: ty.Union[ty.Type[BaseException], BaseException],
548534 tb : ty .Optional [types .TracebackType ] = None ) -> FSNodeEntry :
549535 try :
550536 if isinstance (typ , type ):
551- return self ._generator .throw (typ , val , tb )
537+ bt = ty .cast (ty .Type [BaseException ], typ ) # type: ignore[redundant-cast]
538+ return self ._generator .throw (bt , val , tb )
552539 else :
553540 assert val is None
554541 return self ._generator .throw (typ , val , tb )
@@ -595,8 +582,8 @@ def _walk(
595582 while directory .endswith (sep ):
596583 directory = directory [:- len (sep )]
597584 prefix = (directory if not isinstance (directory , int ) else dot ) + sep
598-
599- reported_directories = set () # type : ty.Set[ty.AnyStr]
585+
586+ reported_directories : ty .Set [ty .AnyStr ] = set ()
600587
601588 # Always report the top-level directory even if nothing therein is matched
602589 reported_directories .add (utils .maybe_fsencode ("" , sep ))
@@ -616,14 +603,19 @@ def _walk(
616603 try :
617604 for result in walk_iter :
618605 dirpath , dirnames , filenames = result [0 :3 ]
619- dirfd = result [3 ] if len (result ) > 3 else None # type:ty.Optional[int] # type: ignore[misc]
620-
606+
607+ if len (result ) <= 3 :
608+ dirfd : ty .Optional [int ] = None
609+ else :
610+ # mypy wrongly believes this will produce an index-out-of-range exception.
611+ dirfd = result [3 ] # type: ignore[misc]
612+
621613 # Remove the directory prefix from the received path
622614 _ , _ , dirpath = dirpath .partition (prefix )
623615
624616 # Keep track of reported intermediaries, so that we only check for
625617 # these at most once per directory base
626- intermediates_reported = False # type: bool
618+ intermediates_reported = False
627619
628620 for filename , is_dir in self ._join_dirs_and_files (list (dirnames ), filenames ):
629621 filepath = os .path .join (dirpath , filename )
0 commit comments