17
17
import sys
18
18
import argparse
19
19
20
- parser = argparse .ArgumentParser (description = "Test runner for typeshed. Patterns are unanchored regexps on the full path." )
20
+ parser = argparse .ArgumentParser (description = "Test runner for typeshed. "
21
+ "Patterns are unanchored regexps on the full path." )
21
22
parser .add_argument ('-v' , '--verbose' , action = 'count' , default = 0 , help = "More output" )
22
23
parser .add_argument ('-n' , '--dry-run' , action = 'store_true' , help = "Don't actually run mypy" )
23
24
parser .add_argument ('-x' , '--exclude' , type = str , nargs = '*' , help = "Exclude pattern" )
25
+ parser .add_argument ('-p' , '--python-version' , type = str , nargs = '*' ,
26
+ help = "These versions only (major[.minor])" )
24
27
parser .add_argument ('filter' , type = str , nargs = '*' , help = "Include pattern (default all)" )
25
28
26
29
27
30
def log (args , * varargs ):
28
31
if args .verbose >= 2 :
29
32
print (* varargs )
30
33
34
+
31
35
def match (args , fn ):
32
36
if not args .filter and not args .exclude :
33
37
log (args , fn , 'accept by default' )
@@ -49,6 +53,20 @@ def match(args, fn):
49
53
return True
50
54
51
55
56
+ def libpath (major , minor ):
57
+ versions = ['%d.%d' % (major , minor )
58
+ for minor in reversed (range (minor + 1 ))]
59
+ versions .append (str (major ))
60
+ versions .append ('2and3' )
61
+ paths = []
62
+ for v in versions :
63
+ for top in ['stdlib' , 'third_party' ]:
64
+ p = os .path .join (top , v )
65
+ if os .path .isdir (p ):
66
+ paths .append (p )
67
+ return paths
68
+
69
+
52
70
def main ():
53
71
args = parser .parse_args ()
54
72
@@ -58,39 +76,62 @@ def main():
58
76
print ("Cannot import mypy. Did you install it?" )
59
77
sys .exit (1 )
60
78
61
- files2 = []
62
- files3 = []
63
- for dir , subdirs , files in os .walk ('.' ):
64
- for file in files :
65
- if file == '__builtin__.pyi' :
66
- continue # Special case (alias for builtins.py).
67
- if file == 'typing.pyi' :
68
- continue # Hack for https://github.com/python/mypy/issues/1254
69
- if file .endswith ('.pyi' ) or file .endswith ('.py' ):
70
- full = os .path .join (dir , file )
71
- if match (args , full ):
72
- if '/2' in dir :
73
- files2 .append (full )
74
- if '/3' in dir or '/2and3' in dir :
75
- files3 .append (full )
76
- if not (files2 or files3 ):
77
- print ('--- nothing to do ---' )
79
+ versions = [(3 , 5 ), (3 , 4 ), (3 , 3 ), (3 , 2 ), (2 , 7 )]
80
+ if args .python_version :
81
+ versions = [v for v in versions
82
+ if any (('%d.%d' % v ).startswith (av ) for av in args .python_version )]
83
+ if not versions :
84
+ print ("--- no versions selected ---" )
85
+ sys .exit (1 )
86
+
78
87
code = 0
79
- for flags , files in [([], files3 ), (['--py2' ], files2 )]:
88
+ runs = 0
89
+ for major , minor in versions :
90
+ roots = libpath (major , minor )
91
+ files = []
92
+ seen = {'__builtin__' , 'builtins' , 'typing' } # Always ignore these.
93
+ for root in roots :
94
+ names = os .listdir (root )
95
+ for name in names :
96
+ full = os .path .join (root , name )
97
+ mod , ext = os .path .splitext (name )
98
+ if mod in seen :
99
+ continue
100
+ if ext in ['.pyi' , '.py' ]:
101
+ if match (args , full ):
102
+ seen .add (mod )
103
+ files .append (full )
104
+ elif (os .path .isfile (os .path .join (full , '__init__.pyi' )) or
105
+ os .path .isfile (os .path .join (full , '__init__.py' ))):
106
+ for r , ds , fs in os .walk (full ):
107
+ ds .sort ()
108
+ fs .sort ()
109
+ for f in fs :
110
+ m , x = os .path .splitext (f )
111
+ if x in ['.pyi' , '.py' ]:
112
+ fn = os .path .join (r , f )
113
+ if match (args , fn ):
114
+ seen .add (mod )
115
+ files .append (fn )
80
116
if files :
117
+ runs += 1
118
+ flags = ['--python-version' , '%d.%d' % (major , minor )]
81
119
sys .argv = ['mypy' ] + flags + files
82
120
if args .verbose :
83
- print (' running' , ' ' .join (sys .argv ))
121
+ print (" running" , ' ' .join (sys .argv ))
84
122
else :
85
- print (' running mypy' , ' ' .join (flags ), ' # with' , len (files ), ' files' )
123
+ print (" running mypy" , ' ' .join (flags ), " # with" , len (files ), " files" )
86
124
try :
87
125
if not args .dry_run :
88
126
mypy_main ('' )
89
127
except SystemExit as err :
90
128
code = max (code , err .code )
91
129
if code :
92
- print (' --- exit status' , code , ' ---' )
130
+ print (" --- exit status" , code , " ---" )
93
131
sys .exit (code )
132
+ if not runs :
133
+ print ("--- nothing to do; exit 1 ---" )
134
+ sys .exit (1 )
94
135
95
136
96
137
if __name__ == '__main__' :
0 commit comments