@@ -72,13 +72,7 @@ def filter_by_include_exclude(
7272
7373
7474class Classifier :
75- def __init__ (self , filenames : Sequence [str ]) -> None :
76- # on windows we normalize all filenames to use forward slashes
77- # this makes it easier to filter using the `files:` regex
78- # this also makes improperly quoted shell-based hooks work better
79- # see #1173
80- if os .altsep == '/' and os .sep == '\\ ' :
81- filenames = [f .replace (os .sep , os .altsep ) for f in filenames ]
75+ def __init__ (self , filenames : Collection [str ]) -> None :
8276 self .filenames = [f for f in filenames if os .path .lexists (f )]
8377
8478 @functools .lru_cache (maxsize = None )
@@ -105,6 +99,22 @@ def filenames_for_hook(self, hook: Hook) -> Tuple[str, ...]:
10599 names = self .by_types (names , hook .types , hook .exclude_types )
106100 return tuple (names )
107101
102+ @classmethod
103+ def from_config (
104+ cls ,
105+ filenames : Collection [str ],
106+ include : str ,
107+ exclude : str ,
108+ ) -> 'Classifier' :
109+ # on windows we normalize all filenames to use forward slashes
110+ # this makes it easier to filter using the `files:` regex
111+ # this also makes improperly quoted shell-based hooks work better
112+ # see #1173
113+ if os .altsep == '/' and os .sep == '\\ ' :
114+ filenames = [f .replace (os .sep , os .altsep ) for f in filenames ]
115+ filenames = filter_by_include_exclude (filenames , include , exclude )
116+ return Classifier (filenames )
117+
108118
109119def _get_skips (environ : EnvironT ) -> Set [str ]:
110120 skips = environ .get ('SKIP' , '' )
@@ -247,10 +257,9 @@ def _run_hooks(
247257 """Actually run the hooks."""
248258 skips = _get_skips (environ )
249259 cols = _compute_cols (hooks )
250- filenames = filter_by_include_exclude (
260+ classifier = Classifier . from_config (
251261 _all_filenames (args ), config ['files' ], config ['exclude' ],
252262 )
253- classifier = Classifier (filenames )
254263 retval = 0
255264 for hook in hooks :
256265 retval |= _run_single_hook (
0 commit comments