10
10
import subprocess
11
11
import sys
12
12
import tempfile
13
+ from enum import IntEnum
13
14
from itertools import product
14
15
from pathlib import Path
15
16
from typing_extensions import TypeAlias
@@ -50,6 +51,12 @@ def package_with_test_cases(package_name: str) -> PackageInfo:
50
51
raise argparse .ArgumentTypeError (f"No test cases found for { package_name !r} !" )
51
52
52
53
54
+ class Verbosity (IntEnum ):
55
+ QUIET = 0
56
+ NORMAL = 1
57
+ VERBOSE = 2
58
+
59
+
53
60
parser = argparse .ArgumentParser (description = "Script to run mypy against various test cases for typeshed's stubs" )
54
61
parser .add_argument (
55
62
"packages_to_test" ,
@@ -66,7 +73,12 @@ def package_with_test_cases(package_name: str) -> PackageInfo:
66
73
"Note that this cannot be specified if --platform and/or --python-version are specified."
67
74
),
68
75
)
69
- parser .add_argument ("--quiet" , action = "store_true" , help = "Print less output to the terminal" )
76
+ parser .add_argument (
77
+ "--verbosity" ,
78
+ choices = [member .name for member in Verbosity ],
79
+ default = Verbosity .NORMAL .name ,
80
+ help = "Control how much output to print to the terminal" ,
81
+ )
70
82
parser .add_argument (
71
83
"--platform" ,
72
84
dest = "platforms_to_test" ,
@@ -92,7 +104,13 @@ def package_with_test_cases(package_name: str) -> PackageInfo:
92
104
)
93
105
94
106
95
- def setup_testcase_dir (package : PackageInfo , tempdir : Path , new_test_case_dir : Path ) -> None :
107
+ def verbose_log (msg : str ) -> None :
108
+ print (colored ("\n " + msg , "blue" ))
109
+
110
+
111
+ def setup_testcase_dir (package : PackageInfo , tempdir : Path , new_test_case_dir : Path , verbosity : Verbosity ) -> None :
112
+ if verbosity is verbosity .VERBOSE :
113
+ verbose_log (f"Setting up testcase dir in { tempdir } " )
96
114
# --warn-unused-ignores doesn't work for files inside typeshed.
97
115
# SO, to work around this, we copy the test_cases directory into a TemporaryDirectory,
98
116
# and run the test cases inside of that.
@@ -119,24 +137,31 @@ def setup_testcase_dir(package: PackageInfo, tempdir: Path, new_test_case_dir: P
119
137
shutil .copytree (Path ("stubs" , requirement ), new_typeshed / "stubs" / requirement )
120
138
121
139
if requirements .external_pkgs :
140
+ if verbosity is Verbosity .VERBOSE :
141
+ verbose_log (f"Setting up venv in { tempdir / VENV_DIR } " )
122
142
pip_exe = make_venv (tempdir / VENV_DIR ).pip_exe
123
143
pip_command = [pip_exe , "install" , get_mypy_req (), * requirements .external_pkgs ]
144
+ if verbosity is Verbosity .VERBOSE :
145
+ verbose_log (f"{ pip_command = } " )
124
146
try :
125
147
subprocess .run (pip_command , check = True , capture_output = True , text = True )
126
148
except subprocess .CalledProcessError as e :
127
149
print (e .stderr )
128
150
raise
129
151
130
152
131
- def run_testcases (package : PackageInfo , version : str , platform : str , * , tempdir : Path ) -> subprocess .CompletedProcess [str ]:
153
+ def run_testcases (
154
+ package : PackageInfo , version : str , platform : str , * , tempdir : Path , verbosity : Verbosity
155
+ ) -> subprocess .CompletedProcess [str ]:
132
156
env_vars = dict (os .environ )
133
157
new_test_case_dir = tempdir / TEST_CASES
134
158
testcasedir_already_setup = new_test_case_dir .exists () and new_test_case_dir .is_dir ()
135
159
136
160
if not testcasedir_already_setup :
137
- setup_testcase_dir (package , tempdir = tempdir , new_test_case_dir = new_test_case_dir )
161
+ setup_testcase_dir (package , tempdir = tempdir , new_test_case_dir = new_test_case_dir , verbosity = verbosity )
138
162
139
- # "--enable-error-code ignore-without-code" is purposefully ommited. See https://github.com/python/typeshed/pull/8083
163
+ # "--enable-error-code ignore-without-code" is purposefully ommited.
164
+ # See https://github.com/python/typeshed/pull/8083
140
165
flags = [
141
166
"--python-version" ,
142
167
version ,
@@ -178,19 +203,27 @@ def run_testcases(package: PackageInfo, version: str, platform: str, *, tempdir:
178
203
flags .append (str (path ))
179
204
180
205
mypy_command = [python_exe , "-m" , "mypy" ] + flags
206
+ if verbosity is Verbosity .VERBOSE :
207
+ verbose_log (f"\n { mypy_command = } " )
208
+ if "MYPYPATH" in env_vars :
209
+ verbose_log (f"{ env_vars ['MYPYPATH' ]= } " )
210
+ else :
211
+ verbose_log ("MYPYPATH not set" )
181
212
return subprocess .run (mypy_command , capture_output = True , text = True , env = env_vars )
182
213
183
214
184
- def test_testcase_directory (package : PackageInfo , version : str , platform : str , * , quiet : bool , tempdir : Path ) -> ReturnCode :
215
+ def test_testcase_directory (
216
+ package : PackageInfo , version : str , platform : str , * , verbosity : Verbosity , tempdir : Path
217
+ ) -> ReturnCode :
185
218
msg = f"Running mypy --platform { platform } --python-version { version } on the "
186
219
msg += "standard library test cases..." if package .is_stdlib else f"test cases for { package .name !r} ..."
187
- if not quiet :
220
+ if verbosity > Verbosity . QUIET :
188
221
print (msg , end = " " , flush = True )
189
222
190
- result = run_testcases (package = package , version = version , platform = platform , tempdir = tempdir )
223
+ result = run_testcases (package = package , version = version , platform = platform , tempdir = tempdir , verbosity = verbosity )
191
224
192
225
if result .returncode :
193
- if quiet :
226
+ if verbosity > Verbosity . QUIET :
194
227
# We'll already have printed this if --quiet wasn't passed.
195
228
# If--quiet was passed, only print this if there were errors.
196
229
# If there are errors, the output is inscrutable if this isn't printed.
@@ -201,7 +234,7 @@ def test_testcase_directory(package: PackageInfo, version: str, platform: str, *
201
234
print_error (result .stderr , fix_path = replacements )
202
235
if result .stdout :
203
236
print_error (result .stdout , fix_path = replacements )
204
- elif not quiet :
237
+ elif verbosity > Verbosity . QUIET :
205
238
print_success_msg ()
206
239
return result .returncode
207
240
@@ -210,6 +243,7 @@ def main() -> ReturnCode:
210
243
args = parser .parse_args ()
211
244
212
245
testcase_directories = args .packages_to_test or get_all_testcase_directories ()
246
+ verbosity = Verbosity [args .verbosity ]
213
247
if args .all :
214
248
if args .platforms_to_test :
215
249
parser .error ("Cannot specify both --platform and --all" )
@@ -225,7 +259,7 @@ def main() -> ReturnCode:
225
259
with tempfile .TemporaryDirectory () as td :
226
260
tempdir = Path (td )
227
261
for platform , version in product (platforms_to_test , versions_to_test ):
228
- this_code = test_testcase_directory (testcase_dir , version , platform , quiet = args . quiet , tempdir = tempdir )
262
+ this_code = test_testcase_directory (testcase_dir , version , platform , verbosity = verbosity , tempdir = tempdir )
229
263
code = max (code , this_code )
230
264
if code :
231
265
print_error ("\n Test completed with errors" )
0 commit comments