1import math 2import os.path 3import sys 4import textwrap 5from test import support 6 7 8def format_duration(seconds): 9 ms = math.ceil(seconds * 1e3) 10 seconds, ms = divmod(ms, 1000) 11 minutes, seconds = divmod(seconds, 60) 12 hours, minutes = divmod(minutes, 60) 13 14 parts = [] 15 if hours: 16 parts.append('%s hour' % hours) 17 if minutes: 18 parts.append('%s min' % minutes) 19 if seconds: 20 if parts: 21 # 2 min 1 sec 22 parts.append('%s sec' % seconds) 23 else: 24 # 1.0 sec 25 parts.append('%.1f sec' % (seconds + ms / 1000)) 26 if not parts: 27 return '%s ms' % ms 28 29 parts = parts[:2] 30 return ' '.join(parts) 31 32 33def removepy(names): 34 if not names: 35 return 36 for idx, name in enumerate(names): 37 basename, ext = os.path.splitext(name) 38 if ext == '.py': 39 names[idx] = basename 40 41 42def count(n, word): 43 if n == 1: 44 return "%d %s" % (n, word) 45 else: 46 return "%d %ss" % (n, word) 47 48 49def printlist(x, width=70, indent=4, file=None): 50 """Print the elements of iterable x to stdout. 51 52 Optional arg width (default 70) is the maximum line length. 53 Optional arg indent (default 4) is the number of blanks with which to 54 begin each line. 55 """ 56 57 blanks = ' ' * indent 58 # Print the sorted list: 'x' may be a '--random' list or a set() 59 print(textwrap.fill(' '.join(str(elt) for elt in sorted(x)), width, 60 initial_indent=blanks, subsequent_indent=blanks), 61 file=file) 62 63 64def print_warning(msg): 65 support.print_warning(msg) 66 67 68orig_unraisablehook = None 69 70 71def flush_std_streams(): 72 if sys.stdout is not None: 73 sys.stdout.flush() 74 if sys.stderr is not None: 75 sys.stderr.flush() 76 77 78def regrtest_unraisable_hook(unraisable): 79 global orig_unraisablehook 80 support.environment_altered = True 81 print_warning("Unraisable exception") 82 old_stderr = sys.stderr 83 try: 84 flush_std_streams() 85 sys.stderr = sys.__stderr__ 86 orig_unraisablehook(unraisable) 87 sys.stderr.flush() 88 finally: 89 sys.stderr = old_stderr 90 91 92def setup_unraisable_hook(): 93 global orig_unraisablehook 94 orig_unraisablehook = sys.unraisablehook 95 sys.unraisablehook = regrtest_unraisable_hook 96 97 98orig_threading_excepthook = None 99 100 101def regrtest_threading_excepthook(args): 102 global orig_threading_excepthook 103 support.environment_altered = True 104 print_warning(f"Uncaught thread exception: {args.exc_type.__name__}") 105 old_stderr = sys.stderr 106 try: 107 flush_std_streams() 108 sys.stderr = sys.__stderr__ 109 orig_threading_excepthook(args) 110 sys.stderr.flush() 111 finally: 112 sys.stderr = old_stderr 113 114 115def setup_threading_excepthook(): 116 global orig_threading_excepthook 117 import threading 118 orig_threading_excepthook = threading.excepthook 119 threading.excepthook = regrtest_threading_excepthook 120 121 122def clear_caches(): 123 # Clear the warnings registry, so they can be displayed again 124 for mod in sys.modules.values(): 125 if hasattr(mod, '__warningregistry__'): 126 del mod.__warningregistry__ 127 128 # Flush standard output, so that buffered data is sent to the OS and 129 # associated Python objects are reclaimed. 130 for stream in (sys.stdout, sys.stderr, sys.__stdout__, sys.__stderr__): 131 if stream is not None: 132 stream.flush() 133 134 # Clear assorted module caches. 135 # Don't worry about resetting the cache if the module is not loaded 136 try: 137 distutils_dir_util = sys.modules['distutils.dir_util'] 138 except KeyError: 139 pass 140 else: 141 distutils_dir_util._path_created.clear() 142 143 try: 144 re = sys.modules['re'] 145 except KeyError: 146 pass 147 else: 148 re.purge() 149 150 try: 151 _strptime = sys.modules['_strptime'] 152 except KeyError: 153 pass 154 else: 155 _strptime._regex_cache.clear() 156 157 try: 158 urllib_parse = sys.modules['urllib.parse'] 159 except KeyError: 160 pass 161 else: 162 urllib_parse.clear_cache() 163 164 try: 165 urllib_request = sys.modules['urllib.request'] 166 except KeyError: 167 pass 168 else: 169 urllib_request.urlcleanup() 170 171 try: 172 linecache = sys.modules['linecache'] 173 except KeyError: 174 pass 175 else: 176 linecache.clearcache() 177 178 try: 179 mimetypes = sys.modules['mimetypes'] 180 except KeyError: 181 pass 182 else: 183 mimetypes._default_mime_types() 184 185 try: 186 filecmp = sys.modules['filecmp'] 187 except KeyError: 188 pass 189 else: 190 filecmp._cache.clear() 191 192 try: 193 struct = sys.modules['struct'] 194 except KeyError: 195 pass 196 else: 197 struct._clearcache() 198 199 try: 200 doctest = sys.modules['doctest'] 201 except KeyError: 202 pass 203 else: 204 doctest.master = None 205 206 try: 207 ctypes = sys.modules['ctypes'] 208 except KeyError: 209 pass 210 else: 211 ctypes._reset_cache() 212 213 try: 214 typing = sys.modules['typing'] 215 except KeyError: 216 pass 217 else: 218 for f in typing._cleanups: 219 f() 220 221 support.gc_collect() 222