1212
1313import argparse
1414import os
15- import re
1615import sys
1716import traceback
18- from typing import List , Match , Optional , Sequence , Tuple
17+ from typing import List , Optional , Sequence , Tuple
1918
2019from pytype import config as pytype_config , load_pytd
20+ from pytype .pytd import typeshed
2121
22- TYPESHED_SUBDIRS = ["stdlib" , "third_party " ]
22+ TYPESHED_SUBDIRS = ["stdlib" , "stubs " ]
2323
2424
2525TYPESHED_HOME = "TYPESHED_HOME"
@@ -61,31 +61,6 @@ def create_parser() -> argparse.ArgumentParser:
6161 return parser
6262
6363
64- class PathMatcher :
65- def __init__ (self , patterns : Sequence [str ]) -> None :
66- patterns = [re .escape (os .path .join (* x .split ("/" ))) for x in patterns ]
67- self .matcher = re .compile (r"({})$" .format ("|" .join (patterns ))) if patterns else None
68-
69- def search (self , path : str ) -> Optional [Match [str ]]:
70- if not self .matcher :
71- return None
72- return self .matcher .search (path )
73-
74-
75- def load_exclude_list (typeshed_location : str ) -> List [str ]:
76- filename = os .path .join (typeshed_location , "tests" , "pytype_exclude_list.txt" )
77- skip_re = re .compile (r"^\s*([^\s#]+)\s*(?:#.*)?$" )
78- skip = []
79-
80- with open (filename ) as f :
81- for line in f :
82- skip_match = skip_re .match (line )
83- if skip_match :
84- skip .append (skip_match .group (1 ))
85-
86- return skip
87-
88-
8964def run_pytype (* , filename : str , python_version : str , typeshed_location : str ) -> Optional [str ]:
9065 """Runs pytype, returning the stderr if any."""
9166 if python_version not in _LOADERS :
@@ -125,7 +100,15 @@ def _get_relative(filename: str) -> str:
125100
126101def _get_module_name (filename : str ) -> str :
127102 """Converts a filename {subdir}/m.n/module/foo to module.foo."""
128- return "." .join (_get_relative (filename ).split (os .path .sep )[2 :]).replace (".pyi" , "" ).replace (".__init__" , "" )
103+ parts = _get_relative (filename ).split (os .path .sep )
104+ if "@python2" in parts :
105+ module_parts = parts [parts .index ("@python2" ) + 1 :]
106+ elif parts [0 ] == "stdlib" :
107+ module_parts = parts [1 :]
108+ else :
109+ assert parts [0 ] == "stubs"
110+ module_parts = parts [2 :]
111+ return "." .join (module_parts ).replace (".pyi" , "" ).replace (".__init__" , "" )
129112
130113
131114def _is_version (path : str , version : str ) -> bool :
@@ -142,20 +125,17 @@ def determine_files_to_test(*, typeshed_location: str, paths: Sequence[str]) ->
142125 """Determine all files to test, checking if it's in the exclude list and which Python versions to use.
143126
144127 Returns a list of pairs of the file path and Python version as an int."""
145- skipped = PathMatcher (load_exclude_list (typeshed_location ))
146128 filenames = find_stubs_in_paths (paths )
129+ ts = typeshed .Typeshed ()
130+ skipped = set (ts .read_blacklist ())
147131 files = []
148132 for f in sorted (filenames ):
149133 rel = _get_relative (f )
150- if skipped . search ( rel ) :
134+ if rel in skipped :
151135 continue
152- if _is_version (f , "2and3" ):
153- files .append ((f , 2 ))
154- files .append ((f , 3 ))
155- elif _is_version (f , "2" ):
156- files .append ((f , 2 ))
157- elif _is_version (f , "3" ):
158- files .append ((f , 3 ))
136+ versions = ts .get_python_major_versions (rel )
137+ if versions :
138+ files .extend ((f , v ) for v in versions )
159139 else :
160140 print ("Unrecognized path: {}" .format (f ))
161141 return files
@@ -178,10 +158,11 @@ def run_all_tests(*, files_to_test: Sequence[Tuple[str, int]], typeshed_location
178158 total_tests = len (files_to_test )
179159 print ("Testing files with pytype..." )
180160 for i , (f , version ) in enumerate (files_to_test ):
161+ python_version = "2.7" if version == 2 else "{0.major}.{0.minor}" .format (sys .version_info )
181162 stderr = (
182163 run_pytype (
183164 filename = f ,
184- python_version = "2.7" if version == 2 else "{0.major}.{0.minor}" . format ( sys . version_info ) ,
165+ python_version = python_version ,
185166 typeshed_location = typeshed_location ,
186167 )
187168 if not dry_run
@@ -192,15 +173,15 @@ def run_all_tests(*, files_to_test: Sequence[Tuple[str, int]], typeshed_location
192173 print (stderr )
193174 errors += 1
194175 stacktrace_final_line = stderr .rstrip ().rsplit ("\n " , 1 )[- 1 ]
195- bad .append ((_get_relative (f ), stacktrace_final_line ))
176+ bad .append ((_get_relative (f ), python_version , stacktrace_final_line ))
196177
197178 runs = i + 1
198179 if runs % 25 == 0 :
199180 print (" {:3d}/{:d} with {:3d} errors" .format (runs , total_tests , errors ))
200181
201182 print ("Ran pytype with {:d} pyis, got {:d} errors." .format (total_tests , errors ))
202- for f , err in bad :
203- print ("{}: {}" .format (f , err ))
183+ for f , v , err in bad :
184+ print ("{} ({}) : {}" .format (f , v , err ))
204185 if errors :
205186 raise SystemExit ("\n Run again with --print-stderr to get the full stacktrace." )
206187
0 commit comments