Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 1 | import atexit |
| 2 | import faulthandler |
| 3 | import os |
| 4 | import signal |
| 5 | import sys |
| 6 | import unittest |
| 7 | from test import support |
| 8 | try: |
| 9 | import gc |
| 10 | except ImportError: |
| 11 | gc = None |
| 12 | |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 13 | |
Victor Stinner | a204502 | 2015-09-30 02:17:28 +0200 | [diff] [blame] | 14 | def setup_tests(ns): |
Victor Stinner | ccef823 | 2017-10-13 12:59:12 -0700 | [diff] [blame] | 15 | try: |
| 16 | stderr_fd = sys.__stderr__.fileno() |
| 17 | except (ValueError, AttributeError): |
| 18 | # Catch ValueError to catch io.UnsupportedOperation on TextIOBase |
| 19 | # and ValueError on a closed stream. |
| 20 | # |
| 21 | # Catch AttributeError for stderr being None. |
| 22 | stderr_fd = None |
| 23 | else: |
| 24 | # Display the Python traceback on fatal errors (e.g. segfault) |
| 25 | faulthandler.enable(all_threads=True, file=stderr_fd) |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 26 | |
Victor Stinner | ccef823 | 2017-10-13 12:59:12 -0700 | [diff] [blame] | 27 | # Display the Python traceback on SIGALRM or SIGUSR1 signal |
| 28 | signals = [] |
| 29 | if hasattr(signal, 'SIGALRM'): |
| 30 | signals.append(signal.SIGALRM) |
| 31 | if hasattr(signal, 'SIGUSR1'): |
| 32 | signals.append(signal.SIGUSR1) |
| 33 | for signum in signals: |
| 34 | faulthandler.register(signum, chain=True, file=stderr_fd) |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 35 | |
| 36 | replace_stdout() |
| 37 | support.record_original_stdout(sys.stdout) |
| 38 | |
Victor Stinner | 9759dd3 | 2016-03-30 02:32:52 +0200 | [diff] [blame] | 39 | if ns.testdir: |
| 40 | # Prepend test directory to sys.path, so runtest() will be able |
| 41 | # to locate tests |
| 42 | sys.path.insert(0, os.path.abspath(ns.testdir)) |
| 43 | |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 44 | # Some times __path__ and __file__ are not absolute (e.g. while running from |
| 45 | # Lib/) and, if we change the CWD to run the tests in a temporary dir, some |
| 46 | # imports might fail. This affects only the modules imported before os.chdir(). |
| 47 | # These modules are searched first in sys.path[0] (so '' -- the CWD) and if |
| 48 | # they are found in the CWD their __file__ and __path__ will be relative (this |
| 49 | # happens before the chdir). All the modules imported after the chdir, are |
| 50 | # not found in the CWD, and since the other paths in sys.path[1:] are absolute |
| 51 | # (site.py absolutize them), the __file__ and __path__ will be absolute too. |
| 52 | # Therefore it is necessary to absolutize manually the __file__ and __path__ of |
| 53 | # the packages to prevent later imports to fail when the CWD is different. |
| 54 | for module in sys.modules.values(): |
| 55 | if hasattr(module, '__path__'): |
Victor Stinner | 82f04e2 | 2016-03-15 23:08:44 +0100 | [diff] [blame] | 56 | for index, path in enumerate(module.__path__): |
| 57 | module.__path__[index] = os.path.abspath(path) |
Ned Deily | e52ac04 | 2018-03-28 01:57:13 -0400 | [diff] [blame] | 58 | if getattr(module, '__file__', None): |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 59 | module.__file__ = os.path.abspath(module.__file__) |
| 60 | |
| 61 | # MacOSX (a.k.a. Darwin) has a default stack size that is too small |
| 62 | # for deeply recursive regular expressions. We see this as crashes in |
| 63 | # the Python test suite when running test_re.py and test_sre.py. The |
| 64 | # fix is to set the stack limit to 2048. |
| 65 | # This approach may also be useful for other Unixy platforms that |
| 66 | # suffer from small default stack limits. |
| 67 | if sys.platform == 'darwin': |
| 68 | try: |
| 69 | import resource |
| 70 | except ImportError: |
| 71 | pass |
| 72 | else: |
| 73 | soft, hard = resource.getrlimit(resource.RLIMIT_STACK) |
| 74 | newsoft = min(hard, max(soft, 1024*2048)) |
| 75 | resource.setrlimit(resource.RLIMIT_STACK, (newsoft, hard)) |
| 76 | |
| 77 | if ns.huntrleaks: |
| 78 | unittest.BaseTestSuite._cleanup = False |
| 79 | |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 80 | if ns.memlimit is not None: |
| 81 | support.set_memlimit(ns.memlimit) |
| 82 | |
| 83 | if ns.threshold is not None: |
| 84 | gc.set_threshold(ns.threshold) |
| 85 | |
Steve Dower | 12c2945 | 2015-10-08 09:05:36 -0700 | [diff] [blame] | 86 | try: |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 87 | import msvcrt |
Steve Dower | 12c2945 | 2015-10-08 09:05:36 -0700 | [diff] [blame] | 88 | except ImportError: |
| 89 | pass |
| 90 | else: |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 91 | msvcrt.SetErrorMode(msvcrt.SEM_FAILCRITICALERRORS| |
| 92 | msvcrt.SEM_NOALIGNMENTFAULTEXCEPT| |
| 93 | msvcrt.SEM_NOGPFAULTERRORBOX| |
| 94 | msvcrt.SEM_NOOPENFILEERRORBOX) |
| 95 | try: |
| 96 | msvcrt.CrtSetReportMode |
| 97 | except AttributeError: |
| 98 | # release build |
| 99 | pass |
| 100 | else: |
| 101 | for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]: |
Steve Dower | 12c2945 | 2015-10-08 09:05:36 -0700 | [diff] [blame] | 102 | if ns.verbose and ns.verbose >= 2: |
| 103 | msvcrt.CrtSetReportMode(m, msvcrt.CRTDBG_MODE_FILE) |
| 104 | msvcrt.CrtSetReportFile(m, msvcrt.CRTDBG_FILE_STDERR) |
| 105 | else: |
| 106 | msvcrt.CrtSetReportMode(m, 0) |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 107 | |
Victor Stinner | a204502 | 2015-09-30 02:17:28 +0200 | [diff] [blame] | 108 | support.use_resources = ns.use_resources |
| 109 | |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 110 | |
| 111 | def replace_stdout(): |
| 112 | """Set stdout encoder error handler to backslashreplace (as stderr error |
| 113 | handler) to avoid UnicodeEncodeError when printing a traceback""" |
| 114 | stdout = sys.stdout |
Victor Stinner | ccef823 | 2017-10-13 12:59:12 -0700 | [diff] [blame] | 115 | try: |
| 116 | fd = stdout.fileno() |
| 117 | except ValueError: |
| 118 | # On IDLE, sys.stdout has no file descriptor and is not a TextIOWrapper |
| 119 | # object. Leaving sys.stdout unchanged. |
| 120 | # |
| 121 | # Catch ValueError to catch io.UnsupportedOperation on TextIOBase |
| 122 | # and ValueError on a closed stream. |
| 123 | return |
| 124 | |
| 125 | sys.stdout = open(fd, 'w', |
Victor Stinner | 234cbef | 2015-09-30 01:13:53 +0200 | [diff] [blame] | 126 | encoding=stdout.encoding, |
| 127 | errors="backslashreplace", |
| 128 | closefd=False, |
| 129 | newline='\n') |
| 130 | |
| 131 | def restore_stdout(): |
| 132 | sys.stdout.close() |
| 133 | sys.stdout = stdout |
| 134 | atexit.register(restore_stdout) |