1010import subprocess
1111import sys
1212import tempfile
13+ from enum import IntEnum
1314from itertools import product
1415from pathlib import Path
1516from typing_extensions import TypeAlias
@@ -50,6 +51,12 @@ def package_with_test_cases(package_name: str) -> PackageInfo:
5051 raise argparse .ArgumentTypeError (f"No test cases found for { package_name !r} !" )
5152
5253
54+ class Verbosity (IntEnum ):
55+ QUIET = 0
56+ NORMAL = 1
57+ VERBOSE = 2
58+
59+
5360parser = argparse .ArgumentParser (description = "Script to run mypy against various test cases for typeshed's stubs" )
5461parser .add_argument (
5562 "packages_to_test" ,
@@ -66,7 +73,12 @@ def package_with_test_cases(package_name: str) -> PackageInfo:
6673 "Note that this cannot be specified if --platform and/or --python-version are specified."
6774 ),
6875)
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+ )
7082parser .add_argument (
7183 "--platform" ,
7284 dest = "platforms_to_test" ,
@@ -92,7 +104,13 @@ def package_with_test_cases(package_name: str) -> PackageInfo:
92104)
93105
94106
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 } " )
96114 # --warn-unused-ignores doesn't work for files inside typeshed.
97115 # SO, to work around this, we copy the test_cases directory into a TemporaryDirectory,
98116 # 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
119137 shutil .copytree (Path ("stubs" , requirement ), new_typeshed / "stubs" / requirement )
120138
121139 if requirements .external_pkgs :
140+ if verbosity is Verbosity .VERBOSE :
141+ verbose_log (f"Setting up venv in { tempdir / VENV_DIR } " )
122142 pip_exe = make_venv (tempdir / VENV_DIR ).pip_exe
123143 pip_command = [pip_exe , "install" , get_mypy_req (), * requirements .external_pkgs ]
144+ if verbosity is Verbosity .VERBOSE :
145+ verbose_log (f"{ pip_command = } " )
124146 try :
125147 subprocess .run (pip_command , check = True , capture_output = True , text = True )
126148 except subprocess .CalledProcessError as e :
127149 print (e .stderr )
128150 raise
129151
130152
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 ]:
132156 env_vars = dict (os .environ )
133157 new_test_case_dir = tempdir / TEST_CASES
134158 testcasedir_already_setup = new_test_case_dir .exists () and new_test_case_dir .is_dir ()
135159
136160 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 )
138162
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
140165 flags = [
141166 "--python-version" ,
142167 version ,
@@ -178,19 +203,27 @@ def run_testcases(package: PackageInfo, version: str, platform: str, *, tempdir:
178203 flags .append (str (path ))
179204
180205 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" )
181212 return subprocess .run (mypy_command , capture_output = True , text = True , env = env_vars )
182213
183214
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 :
185218 msg = f"Running mypy --platform { platform } --python-version { version } on the "
186219 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 :
188221 print (msg , end = " " , flush = True )
189222
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 )
191224
192225 if result .returncode :
193- if quiet :
226+ if verbosity > Verbosity . QUIET :
194227 # We'll already have printed this if --quiet wasn't passed.
195228 # If--quiet was passed, only print this if there were errors.
196229 # 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, *
201234 print_error (result .stderr , fix_path = replacements )
202235 if result .stdout :
203236 print_error (result .stdout , fix_path = replacements )
204- elif not quiet :
237+ elif verbosity > Verbosity . QUIET :
205238 print_success_msg ()
206239 return result .returncode
207240
@@ -210,6 +243,7 @@ def main() -> ReturnCode:
210243 args = parser .parse_args ()
211244
212245 testcase_directories = args .packages_to_test or get_all_testcase_directories ()
246+ verbosity = Verbosity [args .verbosity ]
213247 if args .all :
214248 if args .platforms_to_test :
215249 parser .error ("Cannot specify both --platform and --all" )
@@ -225,7 +259,7 @@ def main() -> ReturnCode:
225259 with tempfile .TemporaryDirectory () as td :
226260 tempdir = Path (td )
227261 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 )
229263 code = max (code , this_code )
230264 if code :
231265 print_error ("\n Test completed with errors" )
0 commit comments