utils.py 4.9 KB

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