17db96d56Sopenharmony_ci"""Supporting definitions for the Python regression tests.""" 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ciif __name__ != 'test.support': 47db96d56Sopenharmony_ci raise ImportError('support must be imported from the test package') 57db96d56Sopenharmony_ci 67db96d56Sopenharmony_ciimport contextlib 77db96d56Sopenharmony_ciimport functools 87db96d56Sopenharmony_ciimport getpass 97db96d56Sopenharmony_ciimport os 107db96d56Sopenharmony_ciimport re 117db96d56Sopenharmony_ciimport stat 127db96d56Sopenharmony_ciimport sys 137db96d56Sopenharmony_ciimport sysconfig 147db96d56Sopenharmony_ciimport time 157db96d56Sopenharmony_ciimport types 167db96d56Sopenharmony_ciimport unittest 177db96d56Sopenharmony_ciimport warnings 187db96d56Sopenharmony_ci 197db96d56Sopenharmony_cifrom .testresult import get_test_runner 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_ci 227db96d56Sopenharmony_citry: 237db96d56Sopenharmony_ci from _testcapi import unicode_legacy_string 247db96d56Sopenharmony_ciexcept ImportError: 257db96d56Sopenharmony_ci unicode_legacy_string = None 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_ci__all__ = [ 287db96d56Sopenharmony_ci # globals 297db96d56Sopenharmony_ci "PIPE_MAX_SIZE", "verbose", "max_memuse", "use_resources", "failfast", 307db96d56Sopenharmony_ci # exceptions 317db96d56Sopenharmony_ci "Error", "TestFailed", "TestDidNotRun", "ResourceDenied", 327db96d56Sopenharmony_ci # io 337db96d56Sopenharmony_ci "record_original_stdout", "get_original_stdout", "captured_stdout", 347db96d56Sopenharmony_ci "captured_stdin", "captured_stderr", 357db96d56Sopenharmony_ci # unittest 367db96d56Sopenharmony_ci "is_resource_enabled", "requires", "requires_freebsd_version", 377db96d56Sopenharmony_ci "requires_linux_version", "requires_mac_ver", 387db96d56Sopenharmony_ci "check_syntax_error", 397db96d56Sopenharmony_ci "BasicTestRunner", "run_unittest", "run_doctest", 407db96d56Sopenharmony_ci "requires_gzip", "requires_bz2", "requires_lzma", 417db96d56Sopenharmony_ci "bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute", 427db96d56Sopenharmony_ci "requires_IEEE_754", "requires_zlib", 437db96d56Sopenharmony_ci "has_fork_support", "requires_fork", 447db96d56Sopenharmony_ci "has_subprocess_support", "requires_subprocess", 457db96d56Sopenharmony_ci "has_socket_support", "requires_working_socket", 467db96d56Sopenharmony_ci "anticipate_failure", "load_package_tests", "detect_api_mismatch", 477db96d56Sopenharmony_ci "check__all__", "skip_if_buggy_ucrt_strfptime", 487db96d56Sopenharmony_ci "check_disallow_instantiation", "check_sanitizer", "skip_if_sanitizer", 497db96d56Sopenharmony_ci # sys 507db96d56Sopenharmony_ci "is_jython", "is_android", "is_emscripten", "is_wasi", 517db96d56Sopenharmony_ci "check_impl_detail", "unix_shell", "setswitchinterval", 527db96d56Sopenharmony_ci # network 537db96d56Sopenharmony_ci "open_urlresource", 547db96d56Sopenharmony_ci # processes 557db96d56Sopenharmony_ci "reap_children", 567db96d56Sopenharmony_ci # miscellaneous 577db96d56Sopenharmony_ci "run_with_locale", "swap_item", "findfile", "infinite_recursion", 587db96d56Sopenharmony_ci "swap_attr", "Matcher", "set_memlimit", "SuppressCrashReport", "sortdict", 597db96d56Sopenharmony_ci "run_with_tz", "PGO", "missing_compiler_executable", 607db96d56Sopenharmony_ci "ALWAYS_EQ", "NEVER_EQ", "LARGEST", "SMALLEST", 617db96d56Sopenharmony_ci "LOOPBACK_TIMEOUT", "INTERNET_TIMEOUT", "SHORT_TIMEOUT", "LONG_TIMEOUT", 627db96d56Sopenharmony_ci ] 637db96d56Sopenharmony_ci 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ci# Timeout in seconds for tests using a network server listening on the network 667db96d56Sopenharmony_ci# local loopback interface like 127.0.0.1. 677db96d56Sopenharmony_ci# 687db96d56Sopenharmony_ci# The timeout is long enough to prevent test failure: it takes into account 697db96d56Sopenharmony_ci# that the client and the server can run in different threads or even different 707db96d56Sopenharmony_ci# processes. 717db96d56Sopenharmony_ci# 727db96d56Sopenharmony_ci# The timeout should be long enough for connect(), recv() and send() methods 737db96d56Sopenharmony_ci# of socket.socket. 747db96d56Sopenharmony_ciLOOPBACK_TIMEOUT = 5.0 757db96d56Sopenharmony_ciif sys.platform == 'win32' and ' 32 bit (ARM)' in sys.version: 767db96d56Sopenharmony_ci # bpo-37553: test_socket.SendfileUsingSendTest is taking longer than 2 777db96d56Sopenharmony_ci # seconds on Windows ARM32 buildbot 787db96d56Sopenharmony_ci LOOPBACK_TIMEOUT = 10 797db96d56Sopenharmony_cielif sys.platform == 'vxworks': 807db96d56Sopenharmony_ci LOOPBACK_TIMEOUT = 10 817db96d56Sopenharmony_ci 827db96d56Sopenharmony_ci# Timeout in seconds for network requests going to the internet. The timeout is 837db96d56Sopenharmony_ci# short enough to prevent a test to wait for too long if the internet request 847db96d56Sopenharmony_ci# is blocked for whatever reason. 857db96d56Sopenharmony_ci# 867db96d56Sopenharmony_ci# Usually, a timeout using INTERNET_TIMEOUT should not mark a test as failed, 877db96d56Sopenharmony_ci# but skip the test instead: see transient_internet(). 887db96d56Sopenharmony_ciINTERNET_TIMEOUT = 60.0 897db96d56Sopenharmony_ci 907db96d56Sopenharmony_ci# Timeout in seconds to mark a test as failed if the test takes "too long". 917db96d56Sopenharmony_ci# 927db96d56Sopenharmony_ci# The timeout value depends on the regrtest --timeout command line option. 937db96d56Sopenharmony_ci# 947db96d56Sopenharmony_ci# If a test using SHORT_TIMEOUT starts to fail randomly on slow buildbots, use 957db96d56Sopenharmony_ci# LONG_TIMEOUT instead. 967db96d56Sopenharmony_ciSHORT_TIMEOUT = 30.0 977db96d56Sopenharmony_ci 987db96d56Sopenharmony_ci# Timeout in seconds to detect when a test hangs. 997db96d56Sopenharmony_ci# 1007db96d56Sopenharmony_ci# It is long enough to reduce the risk of test failure on the slowest Python 1017db96d56Sopenharmony_ci# buildbots. It should not be used to mark a test as failed if the test takes 1027db96d56Sopenharmony_ci# "too long". The timeout value depends on the regrtest --timeout command line 1037db96d56Sopenharmony_ci# option. 1047db96d56Sopenharmony_ciLONG_TIMEOUT = 5 * 60.0 1057db96d56Sopenharmony_ci 1067db96d56Sopenharmony_ci# TEST_HOME_DIR refers to the top level directory of the "test" package 1077db96d56Sopenharmony_ci# that contains Python's regression test suite 1087db96d56Sopenharmony_ciTEST_SUPPORT_DIR = os.path.dirname(os.path.abspath(__file__)) 1097db96d56Sopenharmony_ciTEST_HOME_DIR = os.path.dirname(TEST_SUPPORT_DIR) 1107db96d56Sopenharmony_ciSTDLIB_DIR = os.path.dirname(TEST_HOME_DIR) 1117db96d56Sopenharmony_ciREPO_ROOT = os.path.dirname(STDLIB_DIR) 1127db96d56Sopenharmony_ci 1137db96d56Sopenharmony_ci 1147db96d56Sopenharmony_ciclass Error(Exception): 1157db96d56Sopenharmony_ci """Base class for regression test exceptions.""" 1167db96d56Sopenharmony_ci 1177db96d56Sopenharmony_ciclass TestFailed(Error): 1187db96d56Sopenharmony_ci """Test failed.""" 1197db96d56Sopenharmony_ci 1207db96d56Sopenharmony_ciclass TestFailedWithDetails(TestFailed): 1217db96d56Sopenharmony_ci """Test failed.""" 1227db96d56Sopenharmony_ci def __init__(self, msg, errors, failures): 1237db96d56Sopenharmony_ci self.msg = msg 1247db96d56Sopenharmony_ci self.errors = errors 1257db96d56Sopenharmony_ci self.failures = failures 1267db96d56Sopenharmony_ci super().__init__(msg, errors, failures) 1277db96d56Sopenharmony_ci 1287db96d56Sopenharmony_ci def __str__(self): 1297db96d56Sopenharmony_ci return self.msg 1307db96d56Sopenharmony_ci 1317db96d56Sopenharmony_ciclass TestDidNotRun(Error): 1327db96d56Sopenharmony_ci """Test did not run any subtests.""" 1337db96d56Sopenharmony_ci 1347db96d56Sopenharmony_ciclass ResourceDenied(unittest.SkipTest): 1357db96d56Sopenharmony_ci """Test skipped because it requested a disallowed resource. 1367db96d56Sopenharmony_ci 1377db96d56Sopenharmony_ci This is raised when a test calls requires() for a resource that 1387db96d56Sopenharmony_ci has not be enabled. It is used to distinguish between expected 1397db96d56Sopenharmony_ci and unexpected skips. 1407db96d56Sopenharmony_ci """ 1417db96d56Sopenharmony_ci 1427db96d56Sopenharmony_cidef anticipate_failure(condition): 1437db96d56Sopenharmony_ci """Decorator to mark a test that is known to be broken in some cases 1447db96d56Sopenharmony_ci 1457db96d56Sopenharmony_ci Any use of this decorator should have a comment identifying the 1467db96d56Sopenharmony_ci associated tracker issue. 1477db96d56Sopenharmony_ci """ 1487db96d56Sopenharmony_ci if condition: 1497db96d56Sopenharmony_ci return unittest.expectedFailure 1507db96d56Sopenharmony_ci return lambda f: f 1517db96d56Sopenharmony_ci 1527db96d56Sopenharmony_cidef load_package_tests(pkg_dir, loader, standard_tests, pattern): 1537db96d56Sopenharmony_ci """Generic load_tests implementation for simple test packages. 1547db96d56Sopenharmony_ci 1557db96d56Sopenharmony_ci Most packages can implement load_tests using this function as follows: 1567db96d56Sopenharmony_ci 1577db96d56Sopenharmony_ci def load_tests(*args): 1587db96d56Sopenharmony_ci return load_package_tests(os.path.dirname(__file__), *args) 1597db96d56Sopenharmony_ci """ 1607db96d56Sopenharmony_ci if pattern is None: 1617db96d56Sopenharmony_ci pattern = "test*" 1627db96d56Sopenharmony_ci top_dir = STDLIB_DIR 1637db96d56Sopenharmony_ci package_tests = loader.discover(start_dir=pkg_dir, 1647db96d56Sopenharmony_ci top_level_dir=top_dir, 1657db96d56Sopenharmony_ci pattern=pattern) 1667db96d56Sopenharmony_ci standard_tests.addTests(package_tests) 1677db96d56Sopenharmony_ci return standard_tests 1687db96d56Sopenharmony_ci 1697db96d56Sopenharmony_ci 1707db96d56Sopenharmony_cidef get_attribute(obj, name): 1717db96d56Sopenharmony_ci """Get an attribute, raising SkipTest if AttributeError is raised.""" 1727db96d56Sopenharmony_ci try: 1737db96d56Sopenharmony_ci attribute = getattr(obj, name) 1747db96d56Sopenharmony_ci except AttributeError: 1757db96d56Sopenharmony_ci raise unittest.SkipTest("object %r has no attribute %r" % (obj, name)) 1767db96d56Sopenharmony_ci else: 1777db96d56Sopenharmony_ci return attribute 1787db96d56Sopenharmony_ci 1797db96d56Sopenharmony_civerbose = 1 # Flag set to 0 by regrtest.py 1807db96d56Sopenharmony_ciuse_resources = None # Flag set to [] by regrtest.py 1817db96d56Sopenharmony_cimax_memuse = 0 # Disable bigmem tests (they will still be run with 1827db96d56Sopenharmony_ci # small sizes, to make sure they work.) 1837db96d56Sopenharmony_cireal_max_memuse = 0 1847db96d56Sopenharmony_cijunit_xml_list = None # list of testsuite XML elements 1857db96d56Sopenharmony_cifailfast = False 1867db96d56Sopenharmony_ci 1877db96d56Sopenharmony_ci# _original_stdout is meant to hold stdout at the time regrtest began. 1887db96d56Sopenharmony_ci# This may be "the real" stdout, or IDLE's emulation of stdout, or whatever. 1897db96d56Sopenharmony_ci# The point is to have some flavor of stdout the user can actually see. 1907db96d56Sopenharmony_ci_original_stdout = None 1917db96d56Sopenharmony_cidef record_original_stdout(stdout): 1927db96d56Sopenharmony_ci global _original_stdout 1937db96d56Sopenharmony_ci _original_stdout = stdout 1947db96d56Sopenharmony_ci 1957db96d56Sopenharmony_cidef get_original_stdout(): 1967db96d56Sopenharmony_ci return _original_stdout or sys.stdout 1977db96d56Sopenharmony_ci 1987db96d56Sopenharmony_ci 1997db96d56Sopenharmony_cidef _force_run(path, func, *args): 2007db96d56Sopenharmony_ci try: 2017db96d56Sopenharmony_ci return func(*args) 2027db96d56Sopenharmony_ci except FileNotFoundError as err: 2037db96d56Sopenharmony_ci # chmod() won't fix a missing file. 2047db96d56Sopenharmony_ci if verbose >= 2: 2057db96d56Sopenharmony_ci print('%s: %s' % (err.__class__.__name__, err)) 2067db96d56Sopenharmony_ci raise 2077db96d56Sopenharmony_ci except OSError as err: 2087db96d56Sopenharmony_ci if verbose >= 2: 2097db96d56Sopenharmony_ci print('%s: %s' % (err.__class__.__name__, err)) 2107db96d56Sopenharmony_ci print('re-run %s%r' % (func.__name__, args)) 2117db96d56Sopenharmony_ci os.chmod(path, stat.S_IRWXU) 2127db96d56Sopenharmony_ci return func(*args) 2137db96d56Sopenharmony_ci 2147db96d56Sopenharmony_ci 2157db96d56Sopenharmony_ci# Check whether a gui is actually available 2167db96d56Sopenharmony_cidef _is_gui_available(): 2177db96d56Sopenharmony_ci if hasattr(_is_gui_available, 'result'): 2187db96d56Sopenharmony_ci return _is_gui_available.result 2197db96d56Sopenharmony_ci import platform 2207db96d56Sopenharmony_ci reason = None 2217db96d56Sopenharmony_ci if sys.platform.startswith('win') and platform.win32_is_iot(): 2227db96d56Sopenharmony_ci reason = "gui is not available on Windows IoT Core" 2237db96d56Sopenharmony_ci elif sys.platform.startswith('win'): 2247db96d56Sopenharmony_ci # if Python is running as a service (such as the buildbot service), 2257db96d56Sopenharmony_ci # gui interaction may be disallowed 2267db96d56Sopenharmony_ci import ctypes 2277db96d56Sopenharmony_ci import ctypes.wintypes 2287db96d56Sopenharmony_ci UOI_FLAGS = 1 2297db96d56Sopenharmony_ci WSF_VISIBLE = 0x0001 2307db96d56Sopenharmony_ci class USEROBJECTFLAGS(ctypes.Structure): 2317db96d56Sopenharmony_ci _fields_ = [("fInherit", ctypes.wintypes.BOOL), 2327db96d56Sopenharmony_ci ("fReserved", ctypes.wintypes.BOOL), 2337db96d56Sopenharmony_ci ("dwFlags", ctypes.wintypes.DWORD)] 2347db96d56Sopenharmony_ci dll = ctypes.windll.user32 2357db96d56Sopenharmony_ci h = dll.GetProcessWindowStation() 2367db96d56Sopenharmony_ci if not h: 2377db96d56Sopenharmony_ci raise ctypes.WinError() 2387db96d56Sopenharmony_ci uof = USEROBJECTFLAGS() 2397db96d56Sopenharmony_ci needed = ctypes.wintypes.DWORD() 2407db96d56Sopenharmony_ci res = dll.GetUserObjectInformationW(h, 2417db96d56Sopenharmony_ci UOI_FLAGS, 2427db96d56Sopenharmony_ci ctypes.byref(uof), 2437db96d56Sopenharmony_ci ctypes.sizeof(uof), 2447db96d56Sopenharmony_ci ctypes.byref(needed)) 2457db96d56Sopenharmony_ci if not res: 2467db96d56Sopenharmony_ci raise ctypes.WinError() 2477db96d56Sopenharmony_ci if not bool(uof.dwFlags & WSF_VISIBLE): 2487db96d56Sopenharmony_ci reason = "gui not available (WSF_VISIBLE flag not set)" 2497db96d56Sopenharmony_ci elif sys.platform == 'darwin': 2507db96d56Sopenharmony_ci # The Aqua Tk implementations on OS X can abort the process if 2517db96d56Sopenharmony_ci # being called in an environment where a window server connection 2527db96d56Sopenharmony_ci # cannot be made, for instance when invoked by a buildbot or ssh 2537db96d56Sopenharmony_ci # process not running under the same user id as the current console 2547db96d56Sopenharmony_ci # user. To avoid that, raise an exception if the window manager 2557db96d56Sopenharmony_ci # connection is not available. 2567db96d56Sopenharmony_ci from ctypes import cdll, c_int, pointer, Structure 2577db96d56Sopenharmony_ci from ctypes.util import find_library 2587db96d56Sopenharmony_ci 2597db96d56Sopenharmony_ci app_services = cdll.LoadLibrary(find_library("ApplicationServices")) 2607db96d56Sopenharmony_ci 2617db96d56Sopenharmony_ci if app_services.CGMainDisplayID() == 0: 2627db96d56Sopenharmony_ci reason = "gui tests cannot run without OS X window manager" 2637db96d56Sopenharmony_ci else: 2647db96d56Sopenharmony_ci class ProcessSerialNumber(Structure): 2657db96d56Sopenharmony_ci _fields_ = [("highLongOfPSN", c_int), 2667db96d56Sopenharmony_ci ("lowLongOfPSN", c_int)] 2677db96d56Sopenharmony_ci psn = ProcessSerialNumber() 2687db96d56Sopenharmony_ci psn_p = pointer(psn) 2697db96d56Sopenharmony_ci if ( (app_services.GetCurrentProcess(psn_p) < 0) or 2707db96d56Sopenharmony_ci (app_services.SetFrontProcess(psn_p) < 0) ): 2717db96d56Sopenharmony_ci reason = "cannot run without OS X gui process" 2727db96d56Sopenharmony_ci 2737db96d56Sopenharmony_ci # check on every platform whether tkinter can actually do anything 2747db96d56Sopenharmony_ci if not reason: 2757db96d56Sopenharmony_ci try: 2767db96d56Sopenharmony_ci from tkinter import Tk 2777db96d56Sopenharmony_ci root = Tk() 2787db96d56Sopenharmony_ci root.withdraw() 2797db96d56Sopenharmony_ci root.update() 2807db96d56Sopenharmony_ci root.destroy() 2817db96d56Sopenharmony_ci except Exception as e: 2827db96d56Sopenharmony_ci err_string = str(e) 2837db96d56Sopenharmony_ci if len(err_string) > 50: 2847db96d56Sopenharmony_ci err_string = err_string[:50] + ' [...]' 2857db96d56Sopenharmony_ci reason = 'Tk unavailable due to {}: {}'.format(type(e).__name__, 2867db96d56Sopenharmony_ci err_string) 2877db96d56Sopenharmony_ci 2887db96d56Sopenharmony_ci _is_gui_available.reason = reason 2897db96d56Sopenharmony_ci _is_gui_available.result = not reason 2907db96d56Sopenharmony_ci 2917db96d56Sopenharmony_ci return _is_gui_available.result 2927db96d56Sopenharmony_ci 2937db96d56Sopenharmony_cidef is_resource_enabled(resource): 2947db96d56Sopenharmony_ci """Test whether a resource is enabled. 2957db96d56Sopenharmony_ci 2967db96d56Sopenharmony_ci Known resources are set by regrtest.py. If not running under regrtest.py, 2977db96d56Sopenharmony_ci all resources are assumed enabled unless use_resources has been set. 2987db96d56Sopenharmony_ci """ 2997db96d56Sopenharmony_ci return use_resources is None or resource in use_resources 3007db96d56Sopenharmony_ci 3017db96d56Sopenharmony_cidef requires(resource, msg=None): 3027db96d56Sopenharmony_ci """Raise ResourceDenied if the specified resource is not available.""" 3037db96d56Sopenharmony_ci if not is_resource_enabled(resource): 3047db96d56Sopenharmony_ci if msg is None: 3057db96d56Sopenharmony_ci msg = "Use of the %r resource not enabled" % resource 3067db96d56Sopenharmony_ci raise ResourceDenied(msg) 3077db96d56Sopenharmony_ci if resource in {"network", "urlfetch"} and not has_socket_support: 3087db96d56Sopenharmony_ci raise ResourceDenied("No socket support") 3097db96d56Sopenharmony_ci if resource == 'gui' and not _is_gui_available(): 3107db96d56Sopenharmony_ci raise ResourceDenied(_is_gui_available.reason) 3117db96d56Sopenharmony_ci 3127db96d56Sopenharmony_cidef _requires_unix_version(sysname, min_version): 3137db96d56Sopenharmony_ci """Decorator raising SkipTest if the OS is `sysname` and the version is less 3147db96d56Sopenharmony_ci than `min_version`. 3157db96d56Sopenharmony_ci 3167db96d56Sopenharmony_ci For example, @_requires_unix_version('FreeBSD', (7, 2)) raises SkipTest if 3177db96d56Sopenharmony_ci the FreeBSD version is less than 7.2. 3187db96d56Sopenharmony_ci """ 3197db96d56Sopenharmony_ci import platform 3207db96d56Sopenharmony_ci min_version_txt = '.'.join(map(str, min_version)) 3217db96d56Sopenharmony_ci version_txt = platform.release().split('-', 1)[0] 3227db96d56Sopenharmony_ci if platform.system() == sysname: 3237db96d56Sopenharmony_ci try: 3247db96d56Sopenharmony_ci version = tuple(map(int, version_txt.split('.'))) 3257db96d56Sopenharmony_ci except ValueError: 3267db96d56Sopenharmony_ci skip = False 3277db96d56Sopenharmony_ci else: 3287db96d56Sopenharmony_ci skip = version < min_version 3297db96d56Sopenharmony_ci else: 3307db96d56Sopenharmony_ci skip = False 3317db96d56Sopenharmony_ci 3327db96d56Sopenharmony_ci return unittest.skipIf( 3337db96d56Sopenharmony_ci skip, 3347db96d56Sopenharmony_ci f"{sysname} version {min_version_txt} or higher required, not " 3357db96d56Sopenharmony_ci f"{version_txt}" 3367db96d56Sopenharmony_ci ) 3377db96d56Sopenharmony_ci 3387db96d56Sopenharmony_ci 3397db96d56Sopenharmony_cidef requires_freebsd_version(*min_version): 3407db96d56Sopenharmony_ci """Decorator raising SkipTest if the OS is FreeBSD and the FreeBSD version is 3417db96d56Sopenharmony_ci less than `min_version`. 3427db96d56Sopenharmony_ci 3437db96d56Sopenharmony_ci For example, @requires_freebsd_version(7, 2) raises SkipTest if the FreeBSD 3447db96d56Sopenharmony_ci version is less than 7.2. 3457db96d56Sopenharmony_ci """ 3467db96d56Sopenharmony_ci return _requires_unix_version('FreeBSD', min_version) 3477db96d56Sopenharmony_ci 3487db96d56Sopenharmony_cidef requires_linux_version(*min_version): 3497db96d56Sopenharmony_ci """Decorator raising SkipTest if the OS is Linux and the Linux version is 3507db96d56Sopenharmony_ci less than `min_version`. 3517db96d56Sopenharmony_ci 3527db96d56Sopenharmony_ci For example, @requires_linux_version(2, 6, 32) raises SkipTest if the Linux 3537db96d56Sopenharmony_ci version is less than 2.6.32. 3547db96d56Sopenharmony_ci """ 3557db96d56Sopenharmony_ci return _requires_unix_version('Linux', min_version) 3567db96d56Sopenharmony_ci 3577db96d56Sopenharmony_cidef requires_mac_ver(*min_version): 3587db96d56Sopenharmony_ci """Decorator raising SkipTest if the OS is Mac OS X and the OS X 3597db96d56Sopenharmony_ci version if less than min_version. 3607db96d56Sopenharmony_ci 3617db96d56Sopenharmony_ci For example, @requires_mac_ver(10, 5) raises SkipTest if the OS X version 3627db96d56Sopenharmony_ci is lesser than 10.5. 3637db96d56Sopenharmony_ci """ 3647db96d56Sopenharmony_ci def decorator(func): 3657db96d56Sopenharmony_ci @functools.wraps(func) 3667db96d56Sopenharmony_ci def wrapper(*args, **kw): 3677db96d56Sopenharmony_ci if sys.platform == 'darwin': 3687db96d56Sopenharmony_ci import platform 3697db96d56Sopenharmony_ci version_txt = platform.mac_ver()[0] 3707db96d56Sopenharmony_ci try: 3717db96d56Sopenharmony_ci version = tuple(map(int, version_txt.split('.'))) 3727db96d56Sopenharmony_ci except ValueError: 3737db96d56Sopenharmony_ci pass 3747db96d56Sopenharmony_ci else: 3757db96d56Sopenharmony_ci if version < min_version: 3767db96d56Sopenharmony_ci min_version_txt = '.'.join(map(str, min_version)) 3777db96d56Sopenharmony_ci raise unittest.SkipTest( 3787db96d56Sopenharmony_ci "Mac OS X %s or higher required, not %s" 3797db96d56Sopenharmony_ci % (min_version_txt, version_txt)) 3807db96d56Sopenharmony_ci return func(*args, **kw) 3817db96d56Sopenharmony_ci wrapper.min_version = min_version 3827db96d56Sopenharmony_ci return wrapper 3837db96d56Sopenharmony_ci return decorator 3847db96d56Sopenharmony_ci 3857db96d56Sopenharmony_ci 3867db96d56Sopenharmony_cidef skip_if_buildbot(reason=None): 3877db96d56Sopenharmony_ci """Decorator raising SkipTest if running on a buildbot.""" 3887db96d56Sopenharmony_ci if not reason: 3897db96d56Sopenharmony_ci reason = 'not suitable for buildbots' 3907db96d56Sopenharmony_ci try: 3917db96d56Sopenharmony_ci isbuildbot = getpass.getuser().lower() == 'buildbot' 3927db96d56Sopenharmony_ci except (KeyError, EnvironmentError) as err: 3937db96d56Sopenharmony_ci warnings.warn(f'getpass.getuser() failed {err}.', RuntimeWarning) 3947db96d56Sopenharmony_ci isbuildbot = False 3957db96d56Sopenharmony_ci return unittest.skipIf(isbuildbot, reason) 3967db96d56Sopenharmony_ci 3977db96d56Sopenharmony_cidef check_sanitizer(*, address=False, memory=False, ub=False): 3987db96d56Sopenharmony_ci """Returns True if Python is compiled with sanitizer support""" 3997db96d56Sopenharmony_ci if not (address or memory or ub): 4007db96d56Sopenharmony_ci raise ValueError('At least one of address, memory, or ub must be True') 4017db96d56Sopenharmony_ci 4027db96d56Sopenharmony_ci 4037db96d56Sopenharmony_ci _cflags = sysconfig.get_config_var('CFLAGS') or '' 4047db96d56Sopenharmony_ci _config_args = sysconfig.get_config_var('CONFIG_ARGS') or '' 4057db96d56Sopenharmony_ci memory_sanitizer = ( 4067db96d56Sopenharmony_ci '-fsanitize=memory' in _cflags or 4077db96d56Sopenharmony_ci '--with-memory-sanitizer' in _config_args 4087db96d56Sopenharmony_ci ) 4097db96d56Sopenharmony_ci address_sanitizer = ( 4107db96d56Sopenharmony_ci '-fsanitize=address' in _cflags or 4117db96d56Sopenharmony_ci '--with-memory-sanitizer' in _config_args 4127db96d56Sopenharmony_ci ) 4137db96d56Sopenharmony_ci ub_sanitizer = ( 4147db96d56Sopenharmony_ci '-fsanitize=undefined' in _cflags or 4157db96d56Sopenharmony_ci '--with-undefined-behavior-sanitizer' in _config_args 4167db96d56Sopenharmony_ci ) 4177db96d56Sopenharmony_ci return ( 4187db96d56Sopenharmony_ci (memory and memory_sanitizer) or 4197db96d56Sopenharmony_ci (address and address_sanitizer) or 4207db96d56Sopenharmony_ci (ub and ub_sanitizer) 4217db96d56Sopenharmony_ci ) 4227db96d56Sopenharmony_ci 4237db96d56Sopenharmony_ci 4247db96d56Sopenharmony_cidef skip_if_sanitizer(reason=None, *, address=False, memory=False, ub=False): 4257db96d56Sopenharmony_ci """Decorator raising SkipTest if running with a sanitizer active.""" 4267db96d56Sopenharmony_ci if not reason: 4277db96d56Sopenharmony_ci reason = 'not working with sanitizers active' 4287db96d56Sopenharmony_ci skip = check_sanitizer(address=address, memory=memory, ub=ub) 4297db96d56Sopenharmony_ci return unittest.skipIf(skip, reason) 4307db96d56Sopenharmony_ci 4317db96d56Sopenharmony_ci 4327db96d56Sopenharmony_cidef system_must_validate_cert(f): 4337db96d56Sopenharmony_ci """Skip the test on TLS certificate validation failures.""" 4347db96d56Sopenharmony_ci @functools.wraps(f) 4357db96d56Sopenharmony_ci def dec(*args, **kwargs): 4367db96d56Sopenharmony_ci try: 4377db96d56Sopenharmony_ci f(*args, **kwargs) 4387db96d56Sopenharmony_ci except OSError as e: 4397db96d56Sopenharmony_ci if "CERTIFICATE_VERIFY_FAILED" in str(e): 4407db96d56Sopenharmony_ci raise unittest.SkipTest("system does not contain " 4417db96d56Sopenharmony_ci "necessary certificates") 4427db96d56Sopenharmony_ci raise 4437db96d56Sopenharmony_ci return dec 4447db96d56Sopenharmony_ci 4457db96d56Sopenharmony_ci# A constant likely larger than the underlying OS pipe buffer size, to 4467db96d56Sopenharmony_ci# make writes blocking. 4477db96d56Sopenharmony_ci# Windows limit seems to be around 512 B, and many Unix kernels have a 4487db96d56Sopenharmony_ci# 64 KiB pipe buffer size or 16 * PAGE_SIZE: take a few megs to be sure. 4497db96d56Sopenharmony_ci# (see issue #17835 for a discussion of this number). 4507db96d56Sopenharmony_ciPIPE_MAX_SIZE = 4 * 1024 * 1024 + 1 4517db96d56Sopenharmony_ci 4527db96d56Sopenharmony_ci# A constant likely larger than the underlying OS socket buffer size, to make 4537db96d56Sopenharmony_ci# writes blocking. 4547db96d56Sopenharmony_ci# The socket buffer sizes can usually be tuned system-wide (e.g. through sysctl 4557db96d56Sopenharmony_ci# on Linux), or on a per-socket basis (SO_SNDBUF/SO_RCVBUF). See issue #18643 4567db96d56Sopenharmony_ci# for a discussion of this number. 4577db96d56Sopenharmony_ciSOCK_MAX_SIZE = 16 * 1024 * 1024 + 1 4587db96d56Sopenharmony_ci 4597db96d56Sopenharmony_ci# decorator for skipping tests on non-IEEE 754 platforms 4607db96d56Sopenharmony_cirequires_IEEE_754 = unittest.skipUnless( 4617db96d56Sopenharmony_ci float.__getformat__("double").startswith("IEEE"), 4627db96d56Sopenharmony_ci "test requires IEEE 754 doubles") 4637db96d56Sopenharmony_ci 4647db96d56Sopenharmony_cidef requires_zlib(reason='requires zlib'): 4657db96d56Sopenharmony_ci try: 4667db96d56Sopenharmony_ci import zlib 4677db96d56Sopenharmony_ci except ImportError: 4687db96d56Sopenharmony_ci zlib = None 4697db96d56Sopenharmony_ci return unittest.skipUnless(zlib, reason) 4707db96d56Sopenharmony_ci 4717db96d56Sopenharmony_cidef requires_gzip(reason='requires gzip'): 4727db96d56Sopenharmony_ci try: 4737db96d56Sopenharmony_ci import gzip 4747db96d56Sopenharmony_ci except ImportError: 4757db96d56Sopenharmony_ci gzip = None 4767db96d56Sopenharmony_ci return unittest.skipUnless(gzip, reason) 4777db96d56Sopenharmony_ci 4787db96d56Sopenharmony_cidef requires_bz2(reason='requires bz2'): 4797db96d56Sopenharmony_ci try: 4807db96d56Sopenharmony_ci import bz2 4817db96d56Sopenharmony_ci except ImportError: 4827db96d56Sopenharmony_ci bz2 = None 4837db96d56Sopenharmony_ci return unittest.skipUnless(bz2, reason) 4847db96d56Sopenharmony_ci 4857db96d56Sopenharmony_cidef requires_lzma(reason='requires lzma'): 4867db96d56Sopenharmony_ci try: 4877db96d56Sopenharmony_ci import lzma 4887db96d56Sopenharmony_ci except ImportError: 4897db96d56Sopenharmony_ci lzma = None 4907db96d56Sopenharmony_ci return unittest.skipUnless(lzma, reason) 4917db96d56Sopenharmony_ci 4927db96d56Sopenharmony_cidef has_no_debug_ranges(): 4937db96d56Sopenharmony_ci try: 4947db96d56Sopenharmony_ci import _testinternalcapi 4957db96d56Sopenharmony_ci except ImportError: 4967db96d56Sopenharmony_ci raise unittest.SkipTest("_testinternalcapi required") 4977db96d56Sopenharmony_ci config = _testinternalcapi.get_config() 4987db96d56Sopenharmony_ci return not bool(config['code_debug_ranges']) 4997db96d56Sopenharmony_ci 5007db96d56Sopenharmony_cidef requires_debug_ranges(reason='requires co_positions / debug_ranges'): 5017db96d56Sopenharmony_ci return unittest.skipIf(has_no_debug_ranges(), reason) 5027db96d56Sopenharmony_ci 5037db96d56Sopenharmony_cirequires_legacy_unicode_capi = unittest.skipUnless(unicode_legacy_string, 5047db96d56Sopenharmony_ci 'requires legacy Unicode C API') 5057db96d56Sopenharmony_ci 5067db96d56Sopenharmony_ciis_jython = sys.platform.startswith('java') 5077db96d56Sopenharmony_ci 5087db96d56Sopenharmony_ciis_android = hasattr(sys, 'getandroidapilevel') 5097db96d56Sopenharmony_ci 5107db96d56Sopenharmony_ciif sys.platform not in ('win32', 'vxworks'): 5117db96d56Sopenharmony_ci unix_shell = '/system/bin/sh' if is_android else '/bin/sh' 5127db96d56Sopenharmony_cielse: 5137db96d56Sopenharmony_ci unix_shell = None 5147db96d56Sopenharmony_ci 5157db96d56Sopenharmony_ci# wasm32-emscripten and -wasi are POSIX-like but do not 5167db96d56Sopenharmony_ci# have subprocess or fork support. 5177db96d56Sopenharmony_ciis_emscripten = sys.platform == "emscripten" 5187db96d56Sopenharmony_ciis_wasi = sys.platform == "wasi" 5197db96d56Sopenharmony_ci 5207db96d56Sopenharmony_cihas_fork_support = hasattr(os, "fork") and not is_emscripten and not is_wasi 5217db96d56Sopenharmony_ci 5227db96d56Sopenharmony_cidef requires_fork(): 5237db96d56Sopenharmony_ci return unittest.skipUnless(has_fork_support, "requires working os.fork()") 5247db96d56Sopenharmony_ci 5257db96d56Sopenharmony_cihas_subprocess_support = not is_emscripten and not is_wasi 5267db96d56Sopenharmony_ci 5277db96d56Sopenharmony_cidef requires_subprocess(): 5287db96d56Sopenharmony_ci """Used for subprocess, os.spawn calls, fd inheritance""" 5297db96d56Sopenharmony_ci return unittest.skipUnless(has_subprocess_support, "requires subprocess support") 5307db96d56Sopenharmony_ci 5317db96d56Sopenharmony_ci# Emscripten's socket emulation and WASI sockets have limitations. 5327db96d56Sopenharmony_cihas_socket_support = not is_emscripten and not is_wasi 5337db96d56Sopenharmony_ci 5347db96d56Sopenharmony_cidef requires_working_socket(*, module=False): 5357db96d56Sopenharmony_ci """Skip tests or modules that require working sockets 5367db96d56Sopenharmony_ci 5377db96d56Sopenharmony_ci Can be used as a function/class decorator or to skip an entire module. 5387db96d56Sopenharmony_ci """ 5397db96d56Sopenharmony_ci msg = "requires socket support" 5407db96d56Sopenharmony_ci if module: 5417db96d56Sopenharmony_ci if not has_socket_support: 5427db96d56Sopenharmony_ci raise unittest.SkipTest(msg) 5437db96d56Sopenharmony_ci else: 5447db96d56Sopenharmony_ci return unittest.skipUnless(has_socket_support, msg) 5457db96d56Sopenharmony_ci 5467db96d56Sopenharmony_ci# Does strftime() support glibc extension like '%4Y'? 5477db96d56Sopenharmony_cihas_strftime_extensions = False 5487db96d56Sopenharmony_ciif sys.platform != "win32": 5497db96d56Sopenharmony_ci # bpo-47037: Windows debug builds crash with "Debug Assertion Failed" 5507db96d56Sopenharmony_ci try: 5517db96d56Sopenharmony_ci has_strftime_extensions = time.strftime("%4Y") != "%4Y" 5527db96d56Sopenharmony_ci except ValueError: 5537db96d56Sopenharmony_ci pass 5547db96d56Sopenharmony_ci 5557db96d56Sopenharmony_ci# Define the URL of a dedicated HTTP server for the network tests. 5567db96d56Sopenharmony_ci# The URL must use clear-text HTTP: no redirection to encrypted HTTPS. 5577db96d56Sopenharmony_ciTEST_HTTP_URL = "http://www.pythontest.net" 5587db96d56Sopenharmony_ci 5597db96d56Sopenharmony_ci# Set by libregrtest/main.py so we can skip tests that are not 5607db96d56Sopenharmony_ci# useful for PGO 5617db96d56Sopenharmony_ciPGO = False 5627db96d56Sopenharmony_ci 5637db96d56Sopenharmony_ci# Set by libregrtest/main.py if we are running the extended (time consuming) 5647db96d56Sopenharmony_ci# PGO task. If this is True, PGO is also True. 5657db96d56Sopenharmony_ciPGO_EXTENDED = False 5667db96d56Sopenharmony_ci 5677db96d56Sopenharmony_ci# TEST_DATA_DIR is used as a target download location for remote resources 5687db96d56Sopenharmony_ciTEST_DATA_DIR = os.path.join(TEST_HOME_DIR, "data") 5697db96d56Sopenharmony_ci 5707db96d56Sopenharmony_ci 5717db96d56Sopenharmony_cidef darwin_malloc_err_warning(test_name): 5727db96d56Sopenharmony_ci """Assure user that loud errors generated by macOS libc's malloc are 5737db96d56Sopenharmony_ci expected.""" 5747db96d56Sopenharmony_ci if sys.platform != 'darwin': 5757db96d56Sopenharmony_ci return 5767db96d56Sopenharmony_ci 5777db96d56Sopenharmony_ci import shutil 5787db96d56Sopenharmony_ci msg = ' NOTICE ' 5797db96d56Sopenharmony_ci detail = (f'{test_name} may generate "malloc can\'t allocate region"\n' 5807db96d56Sopenharmony_ci 'warnings on macOS systems. This behavior is known. Do not\n' 5817db96d56Sopenharmony_ci 'report a bug unless tests are also failing. See bpo-40928.') 5827db96d56Sopenharmony_ci 5837db96d56Sopenharmony_ci padding, _ = shutil.get_terminal_size() 5847db96d56Sopenharmony_ci print(msg.center(padding, '-')) 5857db96d56Sopenharmony_ci print(detail) 5867db96d56Sopenharmony_ci print('-' * padding) 5877db96d56Sopenharmony_ci 5887db96d56Sopenharmony_ci 5897db96d56Sopenharmony_cidef findfile(filename, subdir=None): 5907db96d56Sopenharmony_ci """Try to find a file on sys.path or in the test directory. If it is not 5917db96d56Sopenharmony_ci found the argument passed to the function is returned (this does not 5927db96d56Sopenharmony_ci necessarily signal failure; could still be the legitimate path). 5937db96d56Sopenharmony_ci 5947db96d56Sopenharmony_ci Setting *subdir* indicates a relative path to use to find the file 5957db96d56Sopenharmony_ci rather than looking directly in the path directories. 5967db96d56Sopenharmony_ci """ 5977db96d56Sopenharmony_ci if os.path.isabs(filename): 5987db96d56Sopenharmony_ci return filename 5997db96d56Sopenharmony_ci if subdir is not None: 6007db96d56Sopenharmony_ci filename = os.path.join(subdir, filename) 6017db96d56Sopenharmony_ci path = [TEST_HOME_DIR] + sys.path 6027db96d56Sopenharmony_ci for dn in path: 6037db96d56Sopenharmony_ci fn = os.path.join(dn, filename) 6047db96d56Sopenharmony_ci if os.path.exists(fn): return fn 6057db96d56Sopenharmony_ci return filename 6067db96d56Sopenharmony_ci 6077db96d56Sopenharmony_ci 6087db96d56Sopenharmony_cidef sortdict(dict): 6097db96d56Sopenharmony_ci "Like repr(dict), but in sorted order." 6107db96d56Sopenharmony_ci items = sorted(dict.items()) 6117db96d56Sopenharmony_ci reprpairs = ["%r: %r" % pair for pair in items] 6127db96d56Sopenharmony_ci withcommas = ", ".join(reprpairs) 6137db96d56Sopenharmony_ci return "{%s}" % withcommas 6147db96d56Sopenharmony_ci 6157db96d56Sopenharmony_cidef check_syntax_error(testcase, statement, errtext='', *, lineno=None, offset=None): 6167db96d56Sopenharmony_ci with testcase.assertRaisesRegex(SyntaxError, errtext) as cm: 6177db96d56Sopenharmony_ci compile(statement, '<test string>', 'exec') 6187db96d56Sopenharmony_ci err = cm.exception 6197db96d56Sopenharmony_ci testcase.assertIsNotNone(err.lineno) 6207db96d56Sopenharmony_ci if lineno is not None: 6217db96d56Sopenharmony_ci testcase.assertEqual(err.lineno, lineno) 6227db96d56Sopenharmony_ci testcase.assertIsNotNone(err.offset) 6237db96d56Sopenharmony_ci if offset is not None: 6247db96d56Sopenharmony_ci testcase.assertEqual(err.offset, offset) 6257db96d56Sopenharmony_ci 6267db96d56Sopenharmony_ci 6277db96d56Sopenharmony_cidef open_urlresource(url, *args, **kw): 6287db96d56Sopenharmony_ci import urllib.request, urllib.parse 6297db96d56Sopenharmony_ci from .os_helper import unlink 6307db96d56Sopenharmony_ci try: 6317db96d56Sopenharmony_ci import gzip 6327db96d56Sopenharmony_ci except ImportError: 6337db96d56Sopenharmony_ci gzip = None 6347db96d56Sopenharmony_ci 6357db96d56Sopenharmony_ci check = kw.pop('check', None) 6367db96d56Sopenharmony_ci 6377db96d56Sopenharmony_ci filename = urllib.parse.urlparse(url)[2].split('/')[-1] # '/': it's URL! 6387db96d56Sopenharmony_ci 6397db96d56Sopenharmony_ci fn = os.path.join(TEST_DATA_DIR, filename) 6407db96d56Sopenharmony_ci 6417db96d56Sopenharmony_ci def check_valid_file(fn): 6427db96d56Sopenharmony_ci f = open(fn, *args, **kw) 6437db96d56Sopenharmony_ci if check is None: 6447db96d56Sopenharmony_ci return f 6457db96d56Sopenharmony_ci elif check(f): 6467db96d56Sopenharmony_ci f.seek(0) 6477db96d56Sopenharmony_ci return f 6487db96d56Sopenharmony_ci f.close() 6497db96d56Sopenharmony_ci 6507db96d56Sopenharmony_ci if os.path.exists(fn): 6517db96d56Sopenharmony_ci f = check_valid_file(fn) 6527db96d56Sopenharmony_ci if f is not None: 6537db96d56Sopenharmony_ci return f 6547db96d56Sopenharmony_ci unlink(fn) 6557db96d56Sopenharmony_ci 6567db96d56Sopenharmony_ci # Verify the requirement before downloading the file 6577db96d56Sopenharmony_ci requires('urlfetch') 6587db96d56Sopenharmony_ci 6597db96d56Sopenharmony_ci if verbose: 6607db96d56Sopenharmony_ci print('\tfetching %s ...' % url, file=get_original_stdout()) 6617db96d56Sopenharmony_ci opener = urllib.request.build_opener() 6627db96d56Sopenharmony_ci if gzip: 6637db96d56Sopenharmony_ci opener.addheaders.append(('Accept-Encoding', 'gzip')) 6647db96d56Sopenharmony_ci f = opener.open(url, timeout=INTERNET_TIMEOUT) 6657db96d56Sopenharmony_ci if gzip and f.headers.get('Content-Encoding') == 'gzip': 6667db96d56Sopenharmony_ci f = gzip.GzipFile(fileobj=f) 6677db96d56Sopenharmony_ci try: 6687db96d56Sopenharmony_ci with open(fn, "wb") as out: 6697db96d56Sopenharmony_ci s = f.read() 6707db96d56Sopenharmony_ci while s: 6717db96d56Sopenharmony_ci out.write(s) 6727db96d56Sopenharmony_ci s = f.read() 6737db96d56Sopenharmony_ci finally: 6747db96d56Sopenharmony_ci f.close() 6757db96d56Sopenharmony_ci 6767db96d56Sopenharmony_ci f = check_valid_file(fn) 6777db96d56Sopenharmony_ci if f is not None: 6787db96d56Sopenharmony_ci return f 6797db96d56Sopenharmony_ci raise TestFailed('invalid resource %r' % fn) 6807db96d56Sopenharmony_ci 6817db96d56Sopenharmony_ci 6827db96d56Sopenharmony_ci@contextlib.contextmanager 6837db96d56Sopenharmony_cidef captured_output(stream_name): 6847db96d56Sopenharmony_ci """Return a context manager used by captured_stdout/stdin/stderr 6857db96d56Sopenharmony_ci that temporarily replaces the sys stream *stream_name* with a StringIO.""" 6867db96d56Sopenharmony_ci import io 6877db96d56Sopenharmony_ci orig_stdout = getattr(sys, stream_name) 6887db96d56Sopenharmony_ci setattr(sys, stream_name, io.StringIO()) 6897db96d56Sopenharmony_ci try: 6907db96d56Sopenharmony_ci yield getattr(sys, stream_name) 6917db96d56Sopenharmony_ci finally: 6927db96d56Sopenharmony_ci setattr(sys, stream_name, orig_stdout) 6937db96d56Sopenharmony_ci 6947db96d56Sopenharmony_cidef captured_stdout(): 6957db96d56Sopenharmony_ci """Capture the output of sys.stdout: 6967db96d56Sopenharmony_ci 6977db96d56Sopenharmony_ci with captured_stdout() as stdout: 6987db96d56Sopenharmony_ci print("hello") 6997db96d56Sopenharmony_ci self.assertEqual(stdout.getvalue(), "hello\\n") 7007db96d56Sopenharmony_ci """ 7017db96d56Sopenharmony_ci return captured_output("stdout") 7027db96d56Sopenharmony_ci 7037db96d56Sopenharmony_cidef captured_stderr(): 7047db96d56Sopenharmony_ci """Capture the output of sys.stderr: 7057db96d56Sopenharmony_ci 7067db96d56Sopenharmony_ci with captured_stderr() as stderr: 7077db96d56Sopenharmony_ci print("hello", file=sys.stderr) 7087db96d56Sopenharmony_ci self.assertEqual(stderr.getvalue(), "hello\\n") 7097db96d56Sopenharmony_ci """ 7107db96d56Sopenharmony_ci return captured_output("stderr") 7117db96d56Sopenharmony_ci 7127db96d56Sopenharmony_cidef captured_stdin(): 7137db96d56Sopenharmony_ci """Capture the input to sys.stdin: 7147db96d56Sopenharmony_ci 7157db96d56Sopenharmony_ci with captured_stdin() as stdin: 7167db96d56Sopenharmony_ci stdin.write('hello\\n') 7177db96d56Sopenharmony_ci stdin.seek(0) 7187db96d56Sopenharmony_ci # call test code that consumes from sys.stdin 7197db96d56Sopenharmony_ci captured = input() 7207db96d56Sopenharmony_ci self.assertEqual(captured, "hello") 7217db96d56Sopenharmony_ci """ 7227db96d56Sopenharmony_ci return captured_output("stdin") 7237db96d56Sopenharmony_ci 7247db96d56Sopenharmony_ci 7257db96d56Sopenharmony_cidef gc_collect(): 7267db96d56Sopenharmony_ci """Force as many objects as possible to be collected. 7277db96d56Sopenharmony_ci 7287db96d56Sopenharmony_ci In non-CPython implementations of Python, this is needed because timely 7297db96d56Sopenharmony_ci deallocation is not guaranteed by the garbage collector. (Even in CPython 7307db96d56Sopenharmony_ci this can be the case in case of reference cycles.) This means that __del__ 7317db96d56Sopenharmony_ci methods may be called later than expected and weakrefs may remain alive for 7327db96d56Sopenharmony_ci longer than expected. This function tries its best to force all garbage 7337db96d56Sopenharmony_ci objects to disappear. 7347db96d56Sopenharmony_ci """ 7357db96d56Sopenharmony_ci import gc 7367db96d56Sopenharmony_ci gc.collect() 7377db96d56Sopenharmony_ci if is_jython: 7387db96d56Sopenharmony_ci time.sleep(0.1) 7397db96d56Sopenharmony_ci gc.collect() 7407db96d56Sopenharmony_ci gc.collect() 7417db96d56Sopenharmony_ci 7427db96d56Sopenharmony_ci@contextlib.contextmanager 7437db96d56Sopenharmony_cidef disable_gc(): 7447db96d56Sopenharmony_ci import gc 7457db96d56Sopenharmony_ci have_gc = gc.isenabled() 7467db96d56Sopenharmony_ci gc.disable() 7477db96d56Sopenharmony_ci try: 7487db96d56Sopenharmony_ci yield 7497db96d56Sopenharmony_ci finally: 7507db96d56Sopenharmony_ci if have_gc: 7517db96d56Sopenharmony_ci gc.enable() 7527db96d56Sopenharmony_ci 7537db96d56Sopenharmony_ci 7547db96d56Sopenharmony_cidef python_is_optimized(): 7557db96d56Sopenharmony_ci """Find if Python was built with optimizations.""" 7567db96d56Sopenharmony_ci cflags = sysconfig.get_config_var('PY_CFLAGS') or '' 7577db96d56Sopenharmony_ci final_opt = "" 7587db96d56Sopenharmony_ci for opt in cflags.split(): 7597db96d56Sopenharmony_ci if opt.startswith('-O'): 7607db96d56Sopenharmony_ci final_opt = opt 7617db96d56Sopenharmony_ci return final_opt not in ('', '-O0', '-Og') 7627db96d56Sopenharmony_ci 7637db96d56Sopenharmony_ci 7647db96d56Sopenharmony_ci_header = 'nP' 7657db96d56Sopenharmony_ci_align = '0n' 7667db96d56Sopenharmony_ciif hasattr(sys, "getobjects"): 7677db96d56Sopenharmony_ci _header = '2P' + _header 7687db96d56Sopenharmony_ci _align = '0P' 7697db96d56Sopenharmony_ci_vheader = _header + 'n' 7707db96d56Sopenharmony_ci 7717db96d56Sopenharmony_cidef calcobjsize(fmt): 7727db96d56Sopenharmony_ci import struct 7737db96d56Sopenharmony_ci return struct.calcsize(_header + fmt + _align) 7747db96d56Sopenharmony_ci 7757db96d56Sopenharmony_cidef calcvobjsize(fmt): 7767db96d56Sopenharmony_ci import struct 7777db96d56Sopenharmony_ci return struct.calcsize(_vheader + fmt + _align) 7787db96d56Sopenharmony_ci 7797db96d56Sopenharmony_ci 7807db96d56Sopenharmony_ci_TPFLAGS_HAVE_GC = 1<<14 7817db96d56Sopenharmony_ci_TPFLAGS_HEAPTYPE = 1<<9 7827db96d56Sopenharmony_ci 7837db96d56Sopenharmony_cidef check_sizeof(test, o, size): 7847db96d56Sopenharmony_ci try: 7857db96d56Sopenharmony_ci import _testinternalcapi 7867db96d56Sopenharmony_ci except ImportError: 7877db96d56Sopenharmony_ci raise unittest.SkipTest("_testinternalcapi required") 7887db96d56Sopenharmony_ci result = sys.getsizeof(o) 7897db96d56Sopenharmony_ci # add GC header size 7907db96d56Sopenharmony_ci if ((type(o) == type) and (o.__flags__ & _TPFLAGS_HEAPTYPE) or\ 7917db96d56Sopenharmony_ci ((type(o) != type) and (type(o).__flags__ & _TPFLAGS_HAVE_GC))): 7927db96d56Sopenharmony_ci size += _testinternalcapi.SIZEOF_PYGC_HEAD 7937db96d56Sopenharmony_ci msg = 'wrong size for %s: got %d, expected %d' \ 7947db96d56Sopenharmony_ci % (type(o), result, size) 7957db96d56Sopenharmony_ci test.assertEqual(result, size, msg) 7967db96d56Sopenharmony_ci 7977db96d56Sopenharmony_ci#======================================================================= 7987db96d56Sopenharmony_ci# Decorator for running a function in a different locale, correctly resetting 7997db96d56Sopenharmony_ci# it afterwards. 8007db96d56Sopenharmony_ci 8017db96d56Sopenharmony_ci@contextlib.contextmanager 8027db96d56Sopenharmony_cidef run_with_locale(catstr, *locales): 8037db96d56Sopenharmony_ci try: 8047db96d56Sopenharmony_ci import locale 8057db96d56Sopenharmony_ci category = getattr(locale, catstr) 8067db96d56Sopenharmony_ci orig_locale = locale.setlocale(category) 8077db96d56Sopenharmony_ci except AttributeError: 8087db96d56Sopenharmony_ci # if the test author gives us an invalid category string 8097db96d56Sopenharmony_ci raise 8107db96d56Sopenharmony_ci except: 8117db96d56Sopenharmony_ci # cannot retrieve original locale, so do nothing 8127db96d56Sopenharmony_ci locale = orig_locale = None 8137db96d56Sopenharmony_ci else: 8147db96d56Sopenharmony_ci for loc in locales: 8157db96d56Sopenharmony_ci try: 8167db96d56Sopenharmony_ci locale.setlocale(category, loc) 8177db96d56Sopenharmony_ci break 8187db96d56Sopenharmony_ci except: 8197db96d56Sopenharmony_ci pass 8207db96d56Sopenharmony_ci 8217db96d56Sopenharmony_ci try: 8227db96d56Sopenharmony_ci yield 8237db96d56Sopenharmony_ci finally: 8247db96d56Sopenharmony_ci if locale and orig_locale: 8257db96d56Sopenharmony_ci locale.setlocale(category, orig_locale) 8267db96d56Sopenharmony_ci 8277db96d56Sopenharmony_ci#======================================================================= 8287db96d56Sopenharmony_ci# Decorator for running a function in a specific timezone, correctly 8297db96d56Sopenharmony_ci# resetting it afterwards. 8307db96d56Sopenharmony_ci 8317db96d56Sopenharmony_cidef run_with_tz(tz): 8327db96d56Sopenharmony_ci def decorator(func): 8337db96d56Sopenharmony_ci def inner(*args, **kwds): 8347db96d56Sopenharmony_ci try: 8357db96d56Sopenharmony_ci tzset = time.tzset 8367db96d56Sopenharmony_ci except AttributeError: 8377db96d56Sopenharmony_ci raise unittest.SkipTest("tzset required") 8387db96d56Sopenharmony_ci if 'TZ' in os.environ: 8397db96d56Sopenharmony_ci orig_tz = os.environ['TZ'] 8407db96d56Sopenharmony_ci else: 8417db96d56Sopenharmony_ci orig_tz = None 8427db96d56Sopenharmony_ci os.environ['TZ'] = tz 8437db96d56Sopenharmony_ci tzset() 8447db96d56Sopenharmony_ci 8457db96d56Sopenharmony_ci # now run the function, resetting the tz on exceptions 8467db96d56Sopenharmony_ci try: 8477db96d56Sopenharmony_ci return func(*args, **kwds) 8487db96d56Sopenharmony_ci finally: 8497db96d56Sopenharmony_ci if orig_tz is None: 8507db96d56Sopenharmony_ci del os.environ['TZ'] 8517db96d56Sopenharmony_ci else: 8527db96d56Sopenharmony_ci os.environ['TZ'] = orig_tz 8537db96d56Sopenharmony_ci time.tzset() 8547db96d56Sopenharmony_ci 8557db96d56Sopenharmony_ci inner.__name__ = func.__name__ 8567db96d56Sopenharmony_ci inner.__doc__ = func.__doc__ 8577db96d56Sopenharmony_ci return inner 8587db96d56Sopenharmony_ci return decorator 8597db96d56Sopenharmony_ci 8607db96d56Sopenharmony_ci#======================================================================= 8617db96d56Sopenharmony_ci# Big-memory-test support. Separate from 'resources' because memory use 8627db96d56Sopenharmony_ci# should be configurable. 8637db96d56Sopenharmony_ci 8647db96d56Sopenharmony_ci# Some handy shorthands. Note that these are used for byte-limits as well 8657db96d56Sopenharmony_ci# as size-limits, in the various bigmem tests 8667db96d56Sopenharmony_ci_1M = 1024*1024 8677db96d56Sopenharmony_ci_1G = 1024 * _1M 8687db96d56Sopenharmony_ci_2G = 2 * _1G 8697db96d56Sopenharmony_ci_4G = 4 * _1G 8707db96d56Sopenharmony_ci 8717db96d56Sopenharmony_ciMAX_Py_ssize_t = sys.maxsize 8727db96d56Sopenharmony_ci 8737db96d56Sopenharmony_cidef set_memlimit(limit): 8747db96d56Sopenharmony_ci global max_memuse 8757db96d56Sopenharmony_ci global real_max_memuse 8767db96d56Sopenharmony_ci sizes = { 8777db96d56Sopenharmony_ci 'k': 1024, 8787db96d56Sopenharmony_ci 'm': _1M, 8797db96d56Sopenharmony_ci 'g': _1G, 8807db96d56Sopenharmony_ci 't': 1024*_1G, 8817db96d56Sopenharmony_ci } 8827db96d56Sopenharmony_ci m = re.match(r'(\d+(\.\d+)?) (K|M|G|T)b?$', limit, 8837db96d56Sopenharmony_ci re.IGNORECASE | re.VERBOSE) 8847db96d56Sopenharmony_ci if m is None: 8857db96d56Sopenharmony_ci raise ValueError('Invalid memory limit %r' % (limit,)) 8867db96d56Sopenharmony_ci memlimit = int(float(m.group(1)) * sizes[m.group(3).lower()]) 8877db96d56Sopenharmony_ci real_max_memuse = memlimit 8887db96d56Sopenharmony_ci if memlimit > MAX_Py_ssize_t: 8897db96d56Sopenharmony_ci memlimit = MAX_Py_ssize_t 8907db96d56Sopenharmony_ci if memlimit < _2G - 1: 8917db96d56Sopenharmony_ci raise ValueError('Memory limit %r too low to be useful' % (limit,)) 8927db96d56Sopenharmony_ci max_memuse = memlimit 8937db96d56Sopenharmony_ci 8947db96d56Sopenharmony_ciclass _MemoryWatchdog: 8957db96d56Sopenharmony_ci """An object which periodically watches the process' memory consumption 8967db96d56Sopenharmony_ci and prints it out. 8977db96d56Sopenharmony_ci """ 8987db96d56Sopenharmony_ci 8997db96d56Sopenharmony_ci def __init__(self): 9007db96d56Sopenharmony_ci self.procfile = '/proc/{pid}/statm'.format(pid=os.getpid()) 9017db96d56Sopenharmony_ci self.started = False 9027db96d56Sopenharmony_ci 9037db96d56Sopenharmony_ci def start(self): 9047db96d56Sopenharmony_ci import warnings 9057db96d56Sopenharmony_ci try: 9067db96d56Sopenharmony_ci f = open(self.procfile, 'r') 9077db96d56Sopenharmony_ci except OSError as e: 9087db96d56Sopenharmony_ci warnings.warn('/proc not available for stats: {}'.format(e), 9097db96d56Sopenharmony_ci RuntimeWarning) 9107db96d56Sopenharmony_ci sys.stderr.flush() 9117db96d56Sopenharmony_ci return 9127db96d56Sopenharmony_ci 9137db96d56Sopenharmony_ci import subprocess 9147db96d56Sopenharmony_ci with f: 9157db96d56Sopenharmony_ci watchdog_script = findfile("memory_watchdog.py") 9167db96d56Sopenharmony_ci self.mem_watchdog = subprocess.Popen([sys.executable, watchdog_script], 9177db96d56Sopenharmony_ci stdin=f, 9187db96d56Sopenharmony_ci stderr=subprocess.DEVNULL) 9197db96d56Sopenharmony_ci self.started = True 9207db96d56Sopenharmony_ci 9217db96d56Sopenharmony_ci def stop(self): 9227db96d56Sopenharmony_ci if self.started: 9237db96d56Sopenharmony_ci self.mem_watchdog.terminate() 9247db96d56Sopenharmony_ci self.mem_watchdog.wait() 9257db96d56Sopenharmony_ci 9267db96d56Sopenharmony_ci 9277db96d56Sopenharmony_cidef bigmemtest(size, memuse, dry_run=True): 9287db96d56Sopenharmony_ci """Decorator for bigmem tests. 9297db96d56Sopenharmony_ci 9307db96d56Sopenharmony_ci 'size' is a requested size for the test (in arbitrary, test-interpreted 9317db96d56Sopenharmony_ci units.) 'memuse' is the number of bytes per unit for the test, or a good 9327db96d56Sopenharmony_ci estimate of it. For example, a test that needs two byte buffers, of 4 GiB 9337db96d56Sopenharmony_ci each, could be decorated with @bigmemtest(size=_4G, memuse=2). 9347db96d56Sopenharmony_ci 9357db96d56Sopenharmony_ci The 'size' argument is normally passed to the decorated test method as an 9367db96d56Sopenharmony_ci extra argument. If 'dry_run' is true, the value passed to the test method 9377db96d56Sopenharmony_ci may be less than the requested value. If 'dry_run' is false, it means the 9387db96d56Sopenharmony_ci test doesn't support dummy runs when -M is not specified. 9397db96d56Sopenharmony_ci """ 9407db96d56Sopenharmony_ci def decorator(f): 9417db96d56Sopenharmony_ci def wrapper(self): 9427db96d56Sopenharmony_ci size = wrapper.size 9437db96d56Sopenharmony_ci memuse = wrapper.memuse 9447db96d56Sopenharmony_ci if not real_max_memuse: 9457db96d56Sopenharmony_ci maxsize = 5147 9467db96d56Sopenharmony_ci else: 9477db96d56Sopenharmony_ci maxsize = size 9487db96d56Sopenharmony_ci 9497db96d56Sopenharmony_ci if ((real_max_memuse or not dry_run) 9507db96d56Sopenharmony_ci and real_max_memuse < maxsize * memuse): 9517db96d56Sopenharmony_ci raise unittest.SkipTest( 9527db96d56Sopenharmony_ci "not enough memory: %.1fG minimum needed" 9537db96d56Sopenharmony_ci % (size * memuse / (1024 ** 3))) 9547db96d56Sopenharmony_ci 9557db96d56Sopenharmony_ci if real_max_memuse and verbose: 9567db96d56Sopenharmony_ci print() 9577db96d56Sopenharmony_ci print(" ... expected peak memory use: {peak:.1f}G" 9587db96d56Sopenharmony_ci .format(peak=size * memuse / (1024 ** 3))) 9597db96d56Sopenharmony_ci watchdog = _MemoryWatchdog() 9607db96d56Sopenharmony_ci watchdog.start() 9617db96d56Sopenharmony_ci else: 9627db96d56Sopenharmony_ci watchdog = None 9637db96d56Sopenharmony_ci 9647db96d56Sopenharmony_ci try: 9657db96d56Sopenharmony_ci return f(self, maxsize) 9667db96d56Sopenharmony_ci finally: 9677db96d56Sopenharmony_ci if watchdog: 9687db96d56Sopenharmony_ci watchdog.stop() 9697db96d56Sopenharmony_ci 9707db96d56Sopenharmony_ci wrapper.size = size 9717db96d56Sopenharmony_ci wrapper.memuse = memuse 9727db96d56Sopenharmony_ci return wrapper 9737db96d56Sopenharmony_ci return decorator 9747db96d56Sopenharmony_ci 9757db96d56Sopenharmony_cidef bigaddrspacetest(f): 9767db96d56Sopenharmony_ci """Decorator for tests that fill the address space.""" 9777db96d56Sopenharmony_ci def wrapper(self): 9787db96d56Sopenharmony_ci if max_memuse < MAX_Py_ssize_t: 9797db96d56Sopenharmony_ci if MAX_Py_ssize_t >= 2**63 - 1 and max_memuse >= 2**31: 9807db96d56Sopenharmony_ci raise unittest.SkipTest( 9817db96d56Sopenharmony_ci "not enough memory: try a 32-bit build instead") 9827db96d56Sopenharmony_ci else: 9837db96d56Sopenharmony_ci raise unittest.SkipTest( 9847db96d56Sopenharmony_ci "not enough memory: %.1fG minimum needed" 9857db96d56Sopenharmony_ci % (MAX_Py_ssize_t / (1024 ** 3))) 9867db96d56Sopenharmony_ci else: 9877db96d56Sopenharmony_ci return f(self) 9887db96d56Sopenharmony_ci return wrapper 9897db96d56Sopenharmony_ci 9907db96d56Sopenharmony_ci#======================================================================= 9917db96d56Sopenharmony_ci# unittest integration. 9927db96d56Sopenharmony_ci 9937db96d56Sopenharmony_ciclass BasicTestRunner: 9947db96d56Sopenharmony_ci def run(self, test): 9957db96d56Sopenharmony_ci result = unittest.TestResult() 9967db96d56Sopenharmony_ci test(result) 9977db96d56Sopenharmony_ci return result 9987db96d56Sopenharmony_ci 9997db96d56Sopenharmony_cidef _id(obj): 10007db96d56Sopenharmony_ci return obj 10017db96d56Sopenharmony_ci 10027db96d56Sopenharmony_cidef requires_resource(resource): 10037db96d56Sopenharmony_ci if resource == 'gui' and not _is_gui_available(): 10047db96d56Sopenharmony_ci return unittest.skip(_is_gui_available.reason) 10057db96d56Sopenharmony_ci if is_resource_enabled(resource): 10067db96d56Sopenharmony_ci return _id 10077db96d56Sopenharmony_ci else: 10087db96d56Sopenharmony_ci return unittest.skip("resource {0!r} is not enabled".format(resource)) 10097db96d56Sopenharmony_ci 10107db96d56Sopenharmony_cidef cpython_only(test): 10117db96d56Sopenharmony_ci """ 10127db96d56Sopenharmony_ci Decorator for tests only applicable on CPython. 10137db96d56Sopenharmony_ci """ 10147db96d56Sopenharmony_ci return impl_detail(cpython=True)(test) 10157db96d56Sopenharmony_ci 10167db96d56Sopenharmony_cidef impl_detail(msg=None, **guards): 10177db96d56Sopenharmony_ci if check_impl_detail(**guards): 10187db96d56Sopenharmony_ci return _id 10197db96d56Sopenharmony_ci if msg is None: 10207db96d56Sopenharmony_ci guardnames, default = _parse_guards(guards) 10217db96d56Sopenharmony_ci if default: 10227db96d56Sopenharmony_ci msg = "implementation detail not available on {0}" 10237db96d56Sopenharmony_ci else: 10247db96d56Sopenharmony_ci msg = "implementation detail specific to {0}" 10257db96d56Sopenharmony_ci guardnames = sorted(guardnames.keys()) 10267db96d56Sopenharmony_ci msg = msg.format(' or '.join(guardnames)) 10277db96d56Sopenharmony_ci return unittest.skip(msg) 10287db96d56Sopenharmony_ci 10297db96d56Sopenharmony_cidef _parse_guards(guards): 10307db96d56Sopenharmony_ci # Returns a tuple ({platform_name: run_me}, default_value) 10317db96d56Sopenharmony_ci if not guards: 10327db96d56Sopenharmony_ci return ({'cpython': True}, False) 10337db96d56Sopenharmony_ci is_true = list(guards.values())[0] 10347db96d56Sopenharmony_ci assert list(guards.values()) == [is_true] * len(guards) # all True or all False 10357db96d56Sopenharmony_ci return (guards, not is_true) 10367db96d56Sopenharmony_ci 10377db96d56Sopenharmony_ci# Use the following check to guard CPython's implementation-specific tests -- 10387db96d56Sopenharmony_ci# or to run them only on the implementation(s) guarded by the arguments. 10397db96d56Sopenharmony_cidef check_impl_detail(**guards): 10407db96d56Sopenharmony_ci """This function returns True or False depending on the host platform. 10417db96d56Sopenharmony_ci Examples: 10427db96d56Sopenharmony_ci if check_impl_detail(): # only on CPython (default) 10437db96d56Sopenharmony_ci if check_impl_detail(jython=True): # only on Jython 10447db96d56Sopenharmony_ci if check_impl_detail(cpython=False): # everywhere except on CPython 10457db96d56Sopenharmony_ci """ 10467db96d56Sopenharmony_ci guards, default = _parse_guards(guards) 10477db96d56Sopenharmony_ci return guards.get(sys.implementation.name, default) 10487db96d56Sopenharmony_ci 10497db96d56Sopenharmony_ci 10507db96d56Sopenharmony_cidef no_tracing(func): 10517db96d56Sopenharmony_ci """Decorator to temporarily turn off tracing for the duration of a test.""" 10527db96d56Sopenharmony_ci if not hasattr(sys, 'gettrace'): 10537db96d56Sopenharmony_ci return func 10547db96d56Sopenharmony_ci else: 10557db96d56Sopenharmony_ci @functools.wraps(func) 10567db96d56Sopenharmony_ci def wrapper(*args, **kwargs): 10577db96d56Sopenharmony_ci original_trace = sys.gettrace() 10587db96d56Sopenharmony_ci try: 10597db96d56Sopenharmony_ci sys.settrace(None) 10607db96d56Sopenharmony_ci return func(*args, **kwargs) 10617db96d56Sopenharmony_ci finally: 10627db96d56Sopenharmony_ci sys.settrace(original_trace) 10637db96d56Sopenharmony_ci return wrapper 10647db96d56Sopenharmony_ci 10657db96d56Sopenharmony_ci 10667db96d56Sopenharmony_cidef refcount_test(test): 10677db96d56Sopenharmony_ci """Decorator for tests which involve reference counting. 10687db96d56Sopenharmony_ci 10697db96d56Sopenharmony_ci To start, the decorator does not run the test if is not run by CPython. 10707db96d56Sopenharmony_ci After that, any trace function is unset during the test to prevent 10717db96d56Sopenharmony_ci unexpected refcounts caused by the trace function. 10727db96d56Sopenharmony_ci 10737db96d56Sopenharmony_ci """ 10747db96d56Sopenharmony_ci return no_tracing(cpython_only(test)) 10757db96d56Sopenharmony_ci 10767db96d56Sopenharmony_ci 10777db96d56Sopenharmony_cidef _filter_suite(suite, pred): 10787db96d56Sopenharmony_ci """Recursively filter test cases in a suite based on a predicate.""" 10797db96d56Sopenharmony_ci newtests = [] 10807db96d56Sopenharmony_ci for test in suite._tests: 10817db96d56Sopenharmony_ci if isinstance(test, unittest.TestSuite): 10827db96d56Sopenharmony_ci _filter_suite(test, pred) 10837db96d56Sopenharmony_ci newtests.append(test) 10847db96d56Sopenharmony_ci else: 10857db96d56Sopenharmony_ci if pred(test): 10867db96d56Sopenharmony_ci newtests.append(test) 10877db96d56Sopenharmony_ci suite._tests = newtests 10887db96d56Sopenharmony_ci 10897db96d56Sopenharmony_cidef _run_suite(suite): 10907db96d56Sopenharmony_ci """Run tests from a unittest.TestSuite-derived class.""" 10917db96d56Sopenharmony_ci runner = get_test_runner(sys.stdout, 10927db96d56Sopenharmony_ci verbosity=verbose, 10937db96d56Sopenharmony_ci capture_output=(junit_xml_list is not None)) 10947db96d56Sopenharmony_ci 10957db96d56Sopenharmony_ci result = runner.run(suite) 10967db96d56Sopenharmony_ci 10977db96d56Sopenharmony_ci if junit_xml_list is not None: 10987db96d56Sopenharmony_ci junit_xml_list.append(result.get_xml_element()) 10997db96d56Sopenharmony_ci 11007db96d56Sopenharmony_ci if not result.testsRun and not result.skipped and not result.errors: 11017db96d56Sopenharmony_ci raise TestDidNotRun 11027db96d56Sopenharmony_ci if not result.wasSuccessful(): 11037db96d56Sopenharmony_ci if len(result.errors) == 1 and not result.failures: 11047db96d56Sopenharmony_ci err = result.errors[0][1] 11057db96d56Sopenharmony_ci elif len(result.failures) == 1 and not result.errors: 11067db96d56Sopenharmony_ci err = result.failures[0][1] 11077db96d56Sopenharmony_ci else: 11087db96d56Sopenharmony_ci err = "multiple errors occurred" 11097db96d56Sopenharmony_ci if not verbose: err += "; run in verbose mode for details" 11107db96d56Sopenharmony_ci errors = [(str(tc), exc_str) for tc, exc_str in result.errors] 11117db96d56Sopenharmony_ci failures = [(str(tc), exc_str) for tc, exc_str in result.failures] 11127db96d56Sopenharmony_ci raise TestFailedWithDetails(err, errors, failures) 11137db96d56Sopenharmony_ci 11147db96d56Sopenharmony_ci 11157db96d56Sopenharmony_ci# By default, don't filter tests 11167db96d56Sopenharmony_ci_match_test_func = None 11177db96d56Sopenharmony_ci 11187db96d56Sopenharmony_ci_accept_test_patterns = None 11197db96d56Sopenharmony_ci_ignore_test_patterns = None 11207db96d56Sopenharmony_ci 11217db96d56Sopenharmony_ci 11227db96d56Sopenharmony_cidef match_test(test): 11237db96d56Sopenharmony_ci # Function used by support.run_unittest() and regrtest --list-cases 11247db96d56Sopenharmony_ci if _match_test_func is None: 11257db96d56Sopenharmony_ci return True 11267db96d56Sopenharmony_ci else: 11277db96d56Sopenharmony_ci return _match_test_func(test.id()) 11287db96d56Sopenharmony_ci 11297db96d56Sopenharmony_ci 11307db96d56Sopenharmony_cidef _is_full_match_test(pattern): 11317db96d56Sopenharmony_ci # If a pattern contains at least one dot, it's considered 11327db96d56Sopenharmony_ci # as a full test identifier. 11337db96d56Sopenharmony_ci # Example: 'test.test_os.FileTests.test_access'. 11347db96d56Sopenharmony_ci # 11357db96d56Sopenharmony_ci # ignore patterns which contain fnmatch patterns: '*', '?', '[...]' 11367db96d56Sopenharmony_ci # or '[!...]'. For example, ignore 'test_access*'. 11377db96d56Sopenharmony_ci return ('.' in pattern) and (not re.search(r'[?*\[\]]', pattern)) 11387db96d56Sopenharmony_ci 11397db96d56Sopenharmony_ci 11407db96d56Sopenharmony_cidef set_match_tests(accept_patterns=None, ignore_patterns=None): 11417db96d56Sopenharmony_ci global _match_test_func, _accept_test_patterns, _ignore_test_patterns 11427db96d56Sopenharmony_ci 11437db96d56Sopenharmony_ci 11447db96d56Sopenharmony_ci if accept_patterns is None: 11457db96d56Sopenharmony_ci accept_patterns = () 11467db96d56Sopenharmony_ci if ignore_patterns is None: 11477db96d56Sopenharmony_ci ignore_patterns = () 11487db96d56Sopenharmony_ci 11497db96d56Sopenharmony_ci accept_func = ignore_func = None 11507db96d56Sopenharmony_ci 11517db96d56Sopenharmony_ci if accept_patterns != _accept_test_patterns: 11527db96d56Sopenharmony_ci accept_patterns, accept_func = _compile_match_function(accept_patterns) 11537db96d56Sopenharmony_ci if ignore_patterns != _ignore_test_patterns: 11547db96d56Sopenharmony_ci ignore_patterns, ignore_func = _compile_match_function(ignore_patterns) 11557db96d56Sopenharmony_ci 11567db96d56Sopenharmony_ci # Create a copy since patterns can be mutable and so modified later 11577db96d56Sopenharmony_ci _accept_test_patterns = tuple(accept_patterns) 11587db96d56Sopenharmony_ci _ignore_test_patterns = tuple(ignore_patterns) 11597db96d56Sopenharmony_ci 11607db96d56Sopenharmony_ci if accept_func is not None or ignore_func is not None: 11617db96d56Sopenharmony_ci def match_function(test_id): 11627db96d56Sopenharmony_ci accept = True 11637db96d56Sopenharmony_ci ignore = False 11647db96d56Sopenharmony_ci if accept_func: 11657db96d56Sopenharmony_ci accept = accept_func(test_id) 11667db96d56Sopenharmony_ci if ignore_func: 11677db96d56Sopenharmony_ci ignore = ignore_func(test_id) 11687db96d56Sopenharmony_ci return accept and not ignore 11697db96d56Sopenharmony_ci 11707db96d56Sopenharmony_ci _match_test_func = match_function 11717db96d56Sopenharmony_ci 11727db96d56Sopenharmony_ci 11737db96d56Sopenharmony_cidef _compile_match_function(patterns): 11747db96d56Sopenharmony_ci if not patterns: 11757db96d56Sopenharmony_ci func = None 11767db96d56Sopenharmony_ci # set_match_tests(None) behaves as set_match_tests(()) 11777db96d56Sopenharmony_ci patterns = () 11787db96d56Sopenharmony_ci elif all(map(_is_full_match_test, patterns)): 11797db96d56Sopenharmony_ci # Simple case: all patterns are full test identifier. 11807db96d56Sopenharmony_ci # The test.bisect_cmd utility only uses such full test identifiers. 11817db96d56Sopenharmony_ci func = set(patterns).__contains__ 11827db96d56Sopenharmony_ci else: 11837db96d56Sopenharmony_ci import fnmatch 11847db96d56Sopenharmony_ci regex = '|'.join(map(fnmatch.translate, patterns)) 11857db96d56Sopenharmony_ci # The search *is* case sensitive on purpose: 11867db96d56Sopenharmony_ci # don't use flags=re.IGNORECASE 11877db96d56Sopenharmony_ci regex_match = re.compile(regex).match 11887db96d56Sopenharmony_ci 11897db96d56Sopenharmony_ci def match_test_regex(test_id): 11907db96d56Sopenharmony_ci if regex_match(test_id): 11917db96d56Sopenharmony_ci # The regex matches the whole identifier, for example 11927db96d56Sopenharmony_ci # 'test.test_os.FileTests.test_access'. 11937db96d56Sopenharmony_ci return True 11947db96d56Sopenharmony_ci else: 11957db96d56Sopenharmony_ci # Try to match parts of the test identifier. 11967db96d56Sopenharmony_ci # For example, split 'test.test_os.FileTests.test_access' 11977db96d56Sopenharmony_ci # into: 'test', 'test_os', 'FileTests' and 'test_access'. 11987db96d56Sopenharmony_ci return any(map(regex_match, test_id.split("."))) 11997db96d56Sopenharmony_ci 12007db96d56Sopenharmony_ci func = match_test_regex 12017db96d56Sopenharmony_ci 12027db96d56Sopenharmony_ci return patterns, func 12037db96d56Sopenharmony_ci 12047db96d56Sopenharmony_ci 12057db96d56Sopenharmony_cidef run_unittest(*classes): 12067db96d56Sopenharmony_ci """Run tests from unittest.TestCase-derived classes.""" 12077db96d56Sopenharmony_ci valid_types = (unittest.TestSuite, unittest.TestCase) 12087db96d56Sopenharmony_ci loader = unittest.TestLoader() 12097db96d56Sopenharmony_ci suite = unittest.TestSuite() 12107db96d56Sopenharmony_ci for cls in classes: 12117db96d56Sopenharmony_ci if isinstance(cls, str): 12127db96d56Sopenharmony_ci if cls in sys.modules: 12137db96d56Sopenharmony_ci suite.addTest(loader.loadTestsFromModule(sys.modules[cls])) 12147db96d56Sopenharmony_ci else: 12157db96d56Sopenharmony_ci raise ValueError("str arguments must be keys in sys.modules") 12167db96d56Sopenharmony_ci elif isinstance(cls, valid_types): 12177db96d56Sopenharmony_ci suite.addTest(cls) 12187db96d56Sopenharmony_ci else: 12197db96d56Sopenharmony_ci suite.addTest(loader.loadTestsFromTestCase(cls)) 12207db96d56Sopenharmony_ci _filter_suite(suite, match_test) 12217db96d56Sopenharmony_ci _run_suite(suite) 12227db96d56Sopenharmony_ci 12237db96d56Sopenharmony_ci#======================================================================= 12247db96d56Sopenharmony_ci# Check for the presence of docstrings. 12257db96d56Sopenharmony_ci 12267db96d56Sopenharmony_ci# Rather than trying to enumerate all the cases where docstrings may be 12277db96d56Sopenharmony_ci# disabled, we just check for that directly 12287db96d56Sopenharmony_ci 12297db96d56Sopenharmony_cidef _check_docstrings(): 12307db96d56Sopenharmony_ci """Just used to check if docstrings are enabled""" 12317db96d56Sopenharmony_ci 12327db96d56Sopenharmony_ciMISSING_C_DOCSTRINGS = (check_impl_detail() and 12337db96d56Sopenharmony_ci sys.platform != 'win32' and 12347db96d56Sopenharmony_ci not sysconfig.get_config_var('WITH_DOC_STRINGS')) 12357db96d56Sopenharmony_ci 12367db96d56Sopenharmony_ciHAVE_DOCSTRINGS = (_check_docstrings.__doc__ is not None and 12377db96d56Sopenharmony_ci not MISSING_C_DOCSTRINGS) 12387db96d56Sopenharmony_ci 12397db96d56Sopenharmony_cirequires_docstrings = unittest.skipUnless(HAVE_DOCSTRINGS, 12407db96d56Sopenharmony_ci "test requires docstrings") 12417db96d56Sopenharmony_ci 12427db96d56Sopenharmony_ci 12437db96d56Sopenharmony_ci#======================================================================= 12447db96d56Sopenharmony_ci# doctest driver. 12457db96d56Sopenharmony_ci 12467db96d56Sopenharmony_cidef run_doctest(module, verbosity=None, optionflags=0): 12477db96d56Sopenharmony_ci """Run doctest on the given module. Return (#failures, #tests). 12487db96d56Sopenharmony_ci 12497db96d56Sopenharmony_ci If optional argument verbosity is not specified (or is None), pass 12507db96d56Sopenharmony_ci support's belief about verbosity on to doctest. Else doctest's 12517db96d56Sopenharmony_ci usual behavior is used (it searches sys.argv for -v). 12527db96d56Sopenharmony_ci """ 12537db96d56Sopenharmony_ci 12547db96d56Sopenharmony_ci import doctest 12557db96d56Sopenharmony_ci 12567db96d56Sopenharmony_ci if verbosity is None: 12577db96d56Sopenharmony_ci verbosity = verbose 12587db96d56Sopenharmony_ci else: 12597db96d56Sopenharmony_ci verbosity = None 12607db96d56Sopenharmony_ci 12617db96d56Sopenharmony_ci f, t = doctest.testmod(module, verbose=verbosity, optionflags=optionflags) 12627db96d56Sopenharmony_ci if f: 12637db96d56Sopenharmony_ci raise TestFailed("%d of %d doctests failed" % (f, t)) 12647db96d56Sopenharmony_ci if verbose: 12657db96d56Sopenharmony_ci print('doctest (%s) ... %d tests with zero failures' % 12667db96d56Sopenharmony_ci (module.__name__, t)) 12677db96d56Sopenharmony_ci return f, t 12687db96d56Sopenharmony_ci 12697db96d56Sopenharmony_ci 12707db96d56Sopenharmony_ci#======================================================================= 12717db96d56Sopenharmony_ci# Support for saving and restoring the imported modules. 12727db96d56Sopenharmony_ci 12737db96d56Sopenharmony_cidef flush_std_streams(): 12747db96d56Sopenharmony_ci if sys.stdout is not None: 12757db96d56Sopenharmony_ci sys.stdout.flush() 12767db96d56Sopenharmony_ci if sys.stderr is not None: 12777db96d56Sopenharmony_ci sys.stderr.flush() 12787db96d56Sopenharmony_ci 12797db96d56Sopenharmony_ci 12807db96d56Sopenharmony_cidef print_warning(msg): 12817db96d56Sopenharmony_ci # bpo-45410: Explicitly flush stdout to keep logs in order 12827db96d56Sopenharmony_ci flush_std_streams() 12837db96d56Sopenharmony_ci stream = print_warning.orig_stderr 12847db96d56Sopenharmony_ci for line in msg.splitlines(): 12857db96d56Sopenharmony_ci print(f"Warning -- {line}", file=stream) 12867db96d56Sopenharmony_ci stream.flush() 12877db96d56Sopenharmony_ci 12887db96d56Sopenharmony_ci# bpo-39983: Store the original sys.stderr at Python startup to be able to 12897db96d56Sopenharmony_ci# log warnings even if sys.stderr is captured temporarily by a test. 12907db96d56Sopenharmony_ciprint_warning.orig_stderr = sys.stderr 12917db96d56Sopenharmony_ci 12927db96d56Sopenharmony_ci 12937db96d56Sopenharmony_ci# Flag used by saved_test_environment of test.libregrtest.save_env, 12947db96d56Sopenharmony_ci# to check if a test modified the environment. The flag should be set to False 12957db96d56Sopenharmony_ci# before running a new test. 12967db96d56Sopenharmony_ci# 12977db96d56Sopenharmony_ci# For example, threading_helper.threading_cleanup() sets the flag is the function fails 12987db96d56Sopenharmony_ci# to cleanup threads. 12997db96d56Sopenharmony_cienvironment_altered = False 13007db96d56Sopenharmony_ci 13017db96d56Sopenharmony_cidef reap_children(): 13027db96d56Sopenharmony_ci """Use this function at the end of test_main() whenever sub-processes 13037db96d56Sopenharmony_ci are started. This will help ensure that no extra children (zombies) 13047db96d56Sopenharmony_ci stick around to hog resources and create problems when looking 13057db96d56Sopenharmony_ci for refleaks. 13067db96d56Sopenharmony_ci """ 13077db96d56Sopenharmony_ci global environment_altered 13087db96d56Sopenharmony_ci 13097db96d56Sopenharmony_ci # Need os.waitpid(-1, os.WNOHANG): Windows is not supported 13107db96d56Sopenharmony_ci if not (hasattr(os, 'waitpid') and hasattr(os, 'WNOHANG')): 13117db96d56Sopenharmony_ci return 13127db96d56Sopenharmony_ci elif not has_subprocess_support: 13137db96d56Sopenharmony_ci return 13147db96d56Sopenharmony_ci 13157db96d56Sopenharmony_ci # Reap all our dead child processes so we don't leave zombies around. 13167db96d56Sopenharmony_ci # These hog resources and might be causing some of the buildbots to die. 13177db96d56Sopenharmony_ci while True: 13187db96d56Sopenharmony_ci try: 13197db96d56Sopenharmony_ci # Read the exit status of any child process which already completed 13207db96d56Sopenharmony_ci pid, status = os.waitpid(-1, os.WNOHANG) 13217db96d56Sopenharmony_ci except OSError: 13227db96d56Sopenharmony_ci break 13237db96d56Sopenharmony_ci 13247db96d56Sopenharmony_ci if pid == 0: 13257db96d56Sopenharmony_ci break 13267db96d56Sopenharmony_ci 13277db96d56Sopenharmony_ci print_warning(f"reap_children() reaped child process {pid}") 13287db96d56Sopenharmony_ci environment_altered = True 13297db96d56Sopenharmony_ci 13307db96d56Sopenharmony_ci 13317db96d56Sopenharmony_ci@contextlib.contextmanager 13327db96d56Sopenharmony_cidef swap_attr(obj, attr, new_val): 13337db96d56Sopenharmony_ci """Temporary swap out an attribute with a new object. 13347db96d56Sopenharmony_ci 13357db96d56Sopenharmony_ci Usage: 13367db96d56Sopenharmony_ci with swap_attr(obj, "attr", 5): 13377db96d56Sopenharmony_ci ... 13387db96d56Sopenharmony_ci 13397db96d56Sopenharmony_ci This will set obj.attr to 5 for the duration of the with: block, 13407db96d56Sopenharmony_ci restoring the old value at the end of the block. If `attr` doesn't 13417db96d56Sopenharmony_ci exist on `obj`, it will be created and then deleted at the end of the 13427db96d56Sopenharmony_ci block. 13437db96d56Sopenharmony_ci 13447db96d56Sopenharmony_ci The old value (or None if it doesn't exist) will be assigned to the 13457db96d56Sopenharmony_ci target of the "as" clause, if there is one. 13467db96d56Sopenharmony_ci """ 13477db96d56Sopenharmony_ci if hasattr(obj, attr): 13487db96d56Sopenharmony_ci real_val = getattr(obj, attr) 13497db96d56Sopenharmony_ci setattr(obj, attr, new_val) 13507db96d56Sopenharmony_ci try: 13517db96d56Sopenharmony_ci yield real_val 13527db96d56Sopenharmony_ci finally: 13537db96d56Sopenharmony_ci setattr(obj, attr, real_val) 13547db96d56Sopenharmony_ci else: 13557db96d56Sopenharmony_ci setattr(obj, attr, new_val) 13567db96d56Sopenharmony_ci try: 13577db96d56Sopenharmony_ci yield 13587db96d56Sopenharmony_ci finally: 13597db96d56Sopenharmony_ci if hasattr(obj, attr): 13607db96d56Sopenharmony_ci delattr(obj, attr) 13617db96d56Sopenharmony_ci 13627db96d56Sopenharmony_ci@contextlib.contextmanager 13637db96d56Sopenharmony_cidef swap_item(obj, item, new_val): 13647db96d56Sopenharmony_ci """Temporary swap out an item with a new object. 13657db96d56Sopenharmony_ci 13667db96d56Sopenharmony_ci Usage: 13677db96d56Sopenharmony_ci with swap_item(obj, "item", 5): 13687db96d56Sopenharmony_ci ... 13697db96d56Sopenharmony_ci 13707db96d56Sopenharmony_ci This will set obj["item"] to 5 for the duration of the with: block, 13717db96d56Sopenharmony_ci restoring the old value at the end of the block. If `item` doesn't 13727db96d56Sopenharmony_ci exist on `obj`, it will be created and then deleted at the end of the 13737db96d56Sopenharmony_ci block. 13747db96d56Sopenharmony_ci 13757db96d56Sopenharmony_ci The old value (or None if it doesn't exist) will be assigned to the 13767db96d56Sopenharmony_ci target of the "as" clause, if there is one. 13777db96d56Sopenharmony_ci """ 13787db96d56Sopenharmony_ci if item in obj: 13797db96d56Sopenharmony_ci real_val = obj[item] 13807db96d56Sopenharmony_ci obj[item] = new_val 13817db96d56Sopenharmony_ci try: 13827db96d56Sopenharmony_ci yield real_val 13837db96d56Sopenharmony_ci finally: 13847db96d56Sopenharmony_ci obj[item] = real_val 13857db96d56Sopenharmony_ci else: 13867db96d56Sopenharmony_ci obj[item] = new_val 13877db96d56Sopenharmony_ci try: 13887db96d56Sopenharmony_ci yield 13897db96d56Sopenharmony_ci finally: 13907db96d56Sopenharmony_ci if item in obj: 13917db96d56Sopenharmony_ci del obj[item] 13927db96d56Sopenharmony_ci 13937db96d56Sopenharmony_cidef args_from_interpreter_flags(): 13947db96d56Sopenharmony_ci """Return a list of command-line arguments reproducing the current 13957db96d56Sopenharmony_ci settings in sys.flags and sys.warnoptions.""" 13967db96d56Sopenharmony_ci import subprocess 13977db96d56Sopenharmony_ci return subprocess._args_from_interpreter_flags() 13987db96d56Sopenharmony_ci 13997db96d56Sopenharmony_cidef optim_args_from_interpreter_flags(): 14007db96d56Sopenharmony_ci """Return a list of command-line arguments reproducing the current 14017db96d56Sopenharmony_ci optimization settings in sys.flags.""" 14027db96d56Sopenharmony_ci import subprocess 14037db96d56Sopenharmony_ci return subprocess._optim_args_from_interpreter_flags() 14047db96d56Sopenharmony_ci 14057db96d56Sopenharmony_ci 14067db96d56Sopenharmony_ciclass Matcher(object): 14077db96d56Sopenharmony_ci 14087db96d56Sopenharmony_ci _partial_matches = ('msg', 'message') 14097db96d56Sopenharmony_ci 14107db96d56Sopenharmony_ci def matches(self, d, **kwargs): 14117db96d56Sopenharmony_ci """ 14127db96d56Sopenharmony_ci Try to match a single dict with the supplied arguments. 14137db96d56Sopenharmony_ci 14147db96d56Sopenharmony_ci Keys whose values are strings and which are in self._partial_matches 14157db96d56Sopenharmony_ci will be checked for partial (i.e. substring) matches. You can extend 14167db96d56Sopenharmony_ci this scheme to (for example) do regular expression matching, etc. 14177db96d56Sopenharmony_ci """ 14187db96d56Sopenharmony_ci result = True 14197db96d56Sopenharmony_ci for k in kwargs: 14207db96d56Sopenharmony_ci v = kwargs[k] 14217db96d56Sopenharmony_ci dv = d.get(k) 14227db96d56Sopenharmony_ci if not self.match_value(k, dv, v): 14237db96d56Sopenharmony_ci result = False 14247db96d56Sopenharmony_ci break 14257db96d56Sopenharmony_ci return result 14267db96d56Sopenharmony_ci 14277db96d56Sopenharmony_ci def match_value(self, k, dv, v): 14287db96d56Sopenharmony_ci """ 14297db96d56Sopenharmony_ci Try to match a single stored value (dv) with a supplied value (v). 14307db96d56Sopenharmony_ci """ 14317db96d56Sopenharmony_ci if type(v) != type(dv): 14327db96d56Sopenharmony_ci result = False 14337db96d56Sopenharmony_ci elif type(dv) is not str or k not in self._partial_matches: 14347db96d56Sopenharmony_ci result = (v == dv) 14357db96d56Sopenharmony_ci else: 14367db96d56Sopenharmony_ci result = dv.find(v) >= 0 14377db96d56Sopenharmony_ci return result 14387db96d56Sopenharmony_ci 14397db96d56Sopenharmony_ci 14407db96d56Sopenharmony_ci_buggy_ucrt = None 14417db96d56Sopenharmony_cidef skip_if_buggy_ucrt_strfptime(test): 14427db96d56Sopenharmony_ci """ 14437db96d56Sopenharmony_ci Skip decorator for tests that use buggy strptime/strftime 14447db96d56Sopenharmony_ci 14457db96d56Sopenharmony_ci If the UCRT bugs are present time.localtime().tm_zone will be 14467db96d56Sopenharmony_ci an empty string, otherwise we assume the UCRT bugs are fixed 14477db96d56Sopenharmony_ci 14487db96d56Sopenharmony_ci See bpo-37552 [Windows] strptime/strftime return invalid 14497db96d56Sopenharmony_ci results with UCRT version 17763.615 14507db96d56Sopenharmony_ci """ 14517db96d56Sopenharmony_ci import locale 14527db96d56Sopenharmony_ci global _buggy_ucrt 14537db96d56Sopenharmony_ci if _buggy_ucrt is None: 14547db96d56Sopenharmony_ci if(sys.platform == 'win32' and 14557db96d56Sopenharmony_ci locale.getencoding() == 'cp65001' and 14567db96d56Sopenharmony_ci time.localtime().tm_zone == ''): 14577db96d56Sopenharmony_ci _buggy_ucrt = True 14587db96d56Sopenharmony_ci else: 14597db96d56Sopenharmony_ci _buggy_ucrt = False 14607db96d56Sopenharmony_ci return unittest.skip("buggy MSVC UCRT strptime/strftime")(test) if _buggy_ucrt else test 14617db96d56Sopenharmony_ci 14627db96d56Sopenharmony_ciclass PythonSymlink: 14637db96d56Sopenharmony_ci """Creates a symlink for the current Python executable""" 14647db96d56Sopenharmony_ci def __init__(self, link=None): 14657db96d56Sopenharmony_ci from .os_helper import TESTFN 14667db96d56Sopenharmony_ci 14677db96d56Sopenharmony_ci self.link = link or os.path.abspath(TESTFN) 14687db96d56Sopenharmony_ci self._linked = [] 14697db96d56Sopenharmony_ci self.real = os.path.realpath(sys.executable) 14707db96d56Sopenharmony_ci self._also_link = [] 14717db96d56Sopenharmony_ci 14727db96d56Sopenharmony_ci self._env = None 14737db96d56Sopenharmony_ci 14747db96d56Sopenharmony_ci self._platform_specific() 14757db96d56Sopenharmony_ci 14767db96d56Sopenharmony_ci if sys.platform == "win32": 14777db96d56Sopenharmony_ci def _platform_specific(self): 14787db96d56Sopenharmony_ci import glob 14797db96d56Sopenharmony_ci import _winapi 14807db96d56Sopenharmony_ci 14817db96d56Sopenharmony_ci if os.path.lexists(self.real) and not os.path.exists(self.real): 14827db96d56Sopenharmony_ci # App symlink appears to not exist, but we want the 14837db96d56Sopenharmony_ci # real executable here anyway 14847db96d56Sopenharmony_ci self.real = _winapi.GetModuleFileName(0) 14857db96d56Sopenharmony_ci 14867db96d56Sopenharmony_ci dll = _winapi.GetModuleFileName(sys.dllhandle) 14877db96d56Sopenharmony_ci src_dir = os.path.dirname(dll) 14887db96d56Sopenharmony_ci dest_dir = os.path.dirname(self.link) 14897db96d56Sopenharmony_ci self._also_link.append(( 14907db96d56Sopenharmony_ci dll, 14917db96d56Sopenharmony_ci os.path.join(dest_dir, os.path.basename(dll)) 14927db96d56Sopenharmony_ci )) 14937db96d56Sopenharmony_ci for runtime in glob.glob(os.path.join(glob.escape(src_dir), "vcruntime*.dll")): 14947db96d56Sopenharmony_ci self._also_link.append(( 14957db96d56Sopenharmony_ci runtime, 14967db96d56Sopenharmony_ci os.path.join(dest_dir, os.path.basename(runtime)) 14977db96d56Sopenharmony_ci )) 14987db96d56Sopenharmony_ci 14997db96d56Sopenharmony_ci self._env = {k.upper(): os.getenv(k) for k in os.environ} 15007db96d56Sopenharmony_ci self._env["PYTHONHOME"] = os.path.dirname(self.real) 15017db96d56Sopenharmony_ci if sysconfig.is_python_build(): 15027db96d56Sopenharmony_ci self._env["PYTHONPATH"] = STDLIB_DIR 15037db96d56Sopenharmony_ci else: 15047db96d56Sopenharmony_ci def _platform_specific(self): 15057db96d56Sopenharmony_ci pass 15067db96d56Sopenharmony_ci 15077db96d56Sopenharmony_ci def __enter__(self): 15087db96d56Sopenharmony_ci os.symlink(self.real, self.link) 15097db96d56Sopenharmony_ci self._linked.append(self.link) 15107db96d56Sopenharmony_ci for real, link in self._also_link: 15117db96d56Sopenharmony_ci os.symlink(real, link) 15127db96d56Sopenharmony_ci self._linked.append(link) 15137db96d56Sopenharmony_ci return self 15147db96d56Sopenharmony_ci 15157db96d56Sopenharmony_ci def __exit__(self, exc_type, exc_value, exc_tb): 15167db96d56Sopenharmony_ci for link in self._linked: 15177db96d56Sopenharmony_ci try: 15187db96d56Sopenharmony_ci os.remove(link) 15197db96d56Sopenharmony_ci except IOError as ex: 15207db96d56Sopenharmony_ci if verbose: 15217db96d56Sopenharmony_ci print("failed to clean up {}: {}".format(link, ex)) 15227db96d56Sopenharmony_ci 15237db96d56Sopenharmony_ci def _call(self, python, args, env, returncode): 15247db96d56Sopenharmony_ci import subprocess 15257db96d56Sopenharmony_ci cmd = [python, *args] 15267db96d56Sopenharmony_ci p = subprocess.Popen(cmd, stdout=subprocess.PIPE, 15277db96d56Sopenharmony_ci stderr=subprocess.PIPE, env=env) 15287db96d56Sopenharmony_ci r = p.communicate() 15297db96d56Sopenharmony_ci if p.returncode != returncode: 15307db96d56Sopenharmony_ci if verbose: 15317db96d56Sopenharmony_ci print(repr(r[0])) 15327db96d56Sopenharmony_ci print(repr(r[1]), file=sys.stderr) 15337db96d56Sopenharmony_ci raise RuntimeError( 15347db96d56Sopenharmony_ci 'unexpected return code: {0} (0x{0:08X})'.format(p.returncode)) 15357db96d56Sopenharmony_ci return r 15367db96d56Sopenharmony_ci 15377db96d56Sopenharmony_ci def call_real(self, *args, returncode=0): 15387db96d56Sopenharmony_ci return self._call(self.real, args, None, returncode) 15397db96d56Sopenharmony_ci 15407db96d56Sopenharmony_ci def call_link(self, *args, returncode=0): 15417db96d56Sopenharmony_ci return self._call(self.link, args, self._env, returncode) 15427db96d56Sopenharmony_ci 15437db96d56Sopenharmony_ci 15447db96d56Sopenharmony_cidef skip_if_pgo_task(test): 15457db96d56Sopenharmony_ci """Skip decorator for tests not run in (non-extended) PGO task""" 15467db96d56Sopenharmony_ci ok = not PGO or PGO_EXTENDED 15477db96d56Sopenharmony_ci msg = "Not run for (non-extended) PGO task" 15487db96d56Sopenharmony_ci return test if ok else unittest.skip(msg)(test) 15497db96d56Sopenharmony_ci 15507db96d56Sopenharmony_ci 15517db96d56Sopenharmony_cidef detect_api_mismatch(ref_api, other_api, *, ignore=()): 15527db96d56Sopenharmony_ci """Returns the set of items in ref_api not in other_api, except for a 15537db96d56Sopenharmony_ci defined list of items to be ignored in this check. 15547db96d56Sopenharmony_ci 15557db96d56Sopenharmony_ci By default this skips private attributes beginning with '_' but 15567db96d56Sopenharmony_ci includes all magic methods, i.e. those starting and ending in '__'. 15577db96d56Sopenharmony_ci """ 15587db96d56Sopenharmony_ci missing_items = set(dir(ref_api)) - set(dir(other_api)) 15597db96d56Sopenharmony_ci if ignore: 15607db96d56Sopenharmony_ci missing_items -= set(ignore) 15617db96d56Sopenharmony_ci missing_items = set(m for m in missing_items 15627db96d56Sopenharmony_ci if not m.startswith('_') or m.endswith('__')) 15637db96d56Sopenharmony_ci return missing_items 15647db96d56Sopenharmony_ci 15657db96d56Sopenharmony_ci 15667db96d56Sopenharmony_cidef check__all__(test_case, module, name_of_module=None, extra=(), 15677db96d56Sopenharmony_ci not_exported=()): 15687db96d56Sopenharmony_ci """Assert that the __all__ variable of 'module' contains all public names. 15697db96d56Sopenharmony_ci 15707db96d56Sopenharmony_ci The module's public names (its API) are detected automatically based on 15717db96d56Sopenharmony_ci whether they match the public name convention and were defined in 15727db96d56Sopenharmony_ci 'module'. 15737db96d56Sopenharmony_ci 15747db96d56Sopenharmony_ci The 'name_of_module' argument can specify (as a string or tuple thereof) 15757db96d56Sopenharmony_ci what module(s) an API could be defined in in order to be detected as a 15767db96d56Sopenharmony_ci public API. One case for this is when 'module' imports part of its public 15777db96d56Sopenharmony_ci API from other modules, possibly a C backend (like 'csv' and its '_csv'). 15787db96d56Sopenharmony_ci 15797db96d56Sopenharmony_ci The 'extra' argument can be a set of names that wouldn't otherwise be 15807db96d56Sopenharmony_ci automatically detected as "public", like objects without a proper 15817db96d56Sopenharmony_ci '__module__' attribute. If provided, it will be added to the 15827db96d56Sopenharmony_ci automatically detected ones. 15837db96d56Sopenharmony_ci 15847db96d56Sopenharmony_ci The 'not_exported' argument can be a set of names that must not be treated 15857db96d56Sopenharmony_ci as part of the public API even though their names indicate otherwise. 15867db96d56Sopenharmony_ci 15877db96d56Sopenharmony_ci Usage: 15887db96d56Sopenharmony_ci import bar 15897db96d56Sopenharmony_ci import foo 15907db96d56Sopenharmony_ci import unittest 15917db96d56Sopenharmony_ci from test import support 15927db96d56Sopenharmony_ci 15937db96d56Sopenharmony_ci class MiscTestCase(unittest.TestCase): 15947db96d56Sopenharmony_ci def test__all__(self): 15957db96d56Sopenharmony_ci support.check__all__(self, foo) 15967db96d56Sopenharmony_ci 15977db96d56Sopenharmony_ci class OtherTestCase(unittest.TestCase): 15987db96d56Sopenharmony_ci def test__all__(self): 15997db96d56Sopenharmony_ci extra = {'BAR_CONST', 'FOO_CONST'} 16007db96d56Sopenharmony_ci not_exported = {'baz'} # Undocumented name. 16017db96d56Sopenharmony_ci # bar imports part of its API from _bar. 16027db96d56Sopenharmony_ci support.check__all__(self, bar, ('bar', '_bar'), 16037db96d56Sopenharmony_ci extra=extra, not_exported=not_exported) 16047db96d56Sopenharmony_ci 16057db96d56Sopenharmony_ci """ 16067db96d56Sopenharmony_ci 16077db96d56Sopenharmony_ci if name_of_module is None: 16087db96d56Sopenharmony_ci name_of_module = (module.__name__, ) 16097db96d56Sopenharmony_ci elif isinstance(name_of_module, str): 16107db96d56Sopenharmony_ci name_of_module = (name_of_module, ) 16117db96d56Sopenharmony_ci 16127db96d56Sopenharmony_ci expected = set(extra) 16137db96d56Sopenharmony_ci 16147db96d56Sopenharmony_ci for name in dir(module): 16157db96d56Sopenharmony_ci if name.startswith('_') or name in not_exported: 16167db96d56Sopenharmony_ci continue 16177db96d56Sopenharmony_ci obj = getattr(module, name) 16187db96d56Sopenharmony_ci if (getattr(obj, '__module__', None) in name_of_module or 16197db96d56Sopenharmony_ci (not hasattr(obj, '__module__') and 16207db96d56Sopenharmony_ci not isinstance(obj, types.ModuleType))): 16217db96d56Sopenharmony_ci expected.add(name) 16227db96d56Sopenharmony_ci test_case.assertCountEqual(module.__all__, expected) 16237db96d56Sopenharmony_ci 16247db96d56Sopenharmony_ci 16257db96d56Sopenharmony_cidef suppress_msvcrt_asserts(verbose=False): 16267db96d56Sopenharmony_ci try: 16277db96d56Sopenharmony_ci import msvcrt 16287db96d56Sopenharmony_ci except ImportError: 16297db96d56Sopenharmony_ci return 16307db96d56Sopenharmony_ci 16317db96d56Sopenharmony_ci msvcrt.SetErrorMode(msvcrt.SEM_FAILCRITICALERRORS 16327db96d56Sopenharmony_ci | msvcrt.SEM_NOALIGNMENTFAULTEXCEPT 16337db96d56Sopenharmony_ci | msvcrt.SEM_NOGPFAULTERRORBOX 16347db96d56Sopenharmony_ci | msvcrt.SEM_NOOPENFILEERRORBOX) 16357db96d56Sopenharmony_ci 16367db96d56Sopenharmony_ci # CrtSetReportMode() is only available in debug build 16377db96d56Sopenharmony_ci if hasattr(msvcrt, 'CrtSetReportMode'): 16387db96d56Sopenharmony_ci for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]: 16397db96d56Sopenharmony_ci if verbose: 16407db96d56Sopenharmony_ci msvcrt.CrtSetReportMode(m, msvcrt.CRTDBG_MODE_FILE) 16417db96d56Sopenharmony_ci msvcrt.CrtSetReportFile(m, msvcrt.CRTDBG_FILE_STDERR) 16427db96d56Sopenharmony_ci else: 16437db96d56Sopenharmony_ci msvcrt.CrtSetReportMode(m, 0) 16447db96d56Sopenharmony_ci 16457db96d56Sopenharmony_ci 16467db96d56Sopenharmony_ciclass SuppressCrashReport: 16477db96d56Sopenharmony_ci """Try to prevent a crash report from popping up. 16487db96d56Sopenharmony_ci 16497db96d56Sopenharmony_ci On Windows, don't display the Windows Error Reporting dialog. On UNIX, 16507db96d56Sopenharmony_ci disable the creation of coredump file. 16517db96d56Sopenharmony_ci """ 16527db96d56Sopenharmony_ci old_value = None 16537db96d56Sopenharmony_ci old_modes = None 16547db96d56Sopenharmony_ci 16557db96d56Sopenharmony_ci def __enter__(self): 16567db96d56Sopenharmony_ci """On Windows, disable Windows Error Reporting dialogs using 16577db96d56Sopenharmony_ci SetErrorMode() and CrtSetReportMode(). 16587db96d56Sopenharmony_ci 16597db96d56Sopenharmony_ci On UNIX, try to save the previous core file size limit, then set 16607db96d56Sopenharmony_ci soft limit to 0. 16617db96d56Sopenharmony_ci """ 16627db96d56Sopenharmony_ci if sys.platform.startswith('win'): 16637db96d56Sopenharmony_ci # see http://msdn.microsoft.com/en-us/library/windows/desktop/ms680621.aspx 16647db96d56Sopenharmony_ci try: 16657db96d56Sopenharmony_ci import msvcrt 16667db96d56Sopenharmony_ci except ImportError: 16677db96d56Sopenharmony_ci return 16687db96d56Sopenharmony_ci 16697db96d56Sopenharmony_ci self.old_value = msvcrt.GetErrorMode() 16707db96d56Sopenharmony_ci 16717db96d56Sopenharmony_ci msvcrt.SetErrorMode(self.old_value | msvcrt.SEM_NOGPFAULTERRORBOX) 16727db96d56Sopenharmony_ci 16737db96d56Sopenharmony_ci # bpo-23314: Suppress assert dialogs in debug builds. 16747db96d56Sopenharmony_ci # CrtSetReportMode() is only available in debug build. 16757db96d56Sopenharmony_ci if hasattr(msvcrt, 'CrtSetReportMode'): 16767db96d56Sopenharmony_ci self.old_modes = {} 16777db96d56Sopenharmony_ci for report_type in [msvcrt.CRT_WARN, 16787db96d56Sopenharmony_ci msvcrt.CRT_ERROR, 16797db96d56Sopenharmony_ci msvcrt.CRT_ASSERT]: 16807db96d56Sopenharmony_ci old_mode = msvcrt.CrtSetReportMode(report_type, 16817db96d56Sopenharmony_ci msvcrt.CRTDBG_MODE_FILE) 16827db96d56Sopenharmony_ci old_file = msvcrt.CrtSetReportFile(report_type, 16837db96d56Sopenharmony_ci msvcrt.CRTDBG_FILE_STDERR) 16847db96d56Sopenharmony_ci self.old_modes[report_type] = old_mode, old_file 16857db96d56Sopenharmony_ci 16867db96d56Sopenharmony_ci else: 16877db96d56Sopenharmony_ci try: 16887db96d56Sopenharmony_ci import resource 16897db96d56Sopenharmony_ci self.resource = resource 16907db96d56Sopenharmony_ci except ImportError: 16917db96d56Sopenharmony_ci self.resource = None 16927db96d56Sopenharmony_ci if self.resource is not None: 16937db96d56Sopenharmony_ci try: 16947db96d56Sopenharmony_ci self.old_value = self.resource.getrlimit(self.resource.RLIMIT_CORE) 16957db96d56Sopenharmony_ci self.resource.setrlimit(self.resource.RLIMIT_CORE, 16967db96d56Sopenharmony_ci (0, self.old_value[1])) 16977db96d56Sopenharmony_ci except (ValueError, OSError): 16987db96d56Sopenharmony_ci pass 16997db96d56Sopenharmony_ci 17007db96d56Sopenharmony_ci if sys.platform == 'darwin': 17017db96d56Sopenharmony_ci import subprocess 17027db96d56Sopenharmony_ci # Check if the 'Crash Reporter' on OSX was configured 17037db96d56Sopenharmony_ci # in 'Developer' mode and warn that it will get triggered 17047db96d56Sopenharmony_ci # when it is. 17057db96d56Sopenharmony_ci # 17067db96d56Sopenharmony_ci # This assumes that this context manager is used in tests 17077db96d56Sopenharmony_ci # that might trigger the next manager. 17087db96d56Sopenharmony_ci cmd = ['/usr/bin/defaults', 'read', 17097db96d56Sopenharmony_ci 'com.apple.CrashReporter', 'DialogType'] 17107db96d56Sopenharmony_ci proc = subprocess.Popen(cmd, 17117db96d56Sopenharmony_ci stdout=subprocess.PIPE, 17127db96d56Sopenharmony_ci stderr=subprocess.PIPE) 17137db96d56Sopenharmony_ci with proc: 17147db96d56Sopenharmony_ci stdout = proc.communicate()[0] 17157db96d56Sopenharmony_ci if stdout.strip() == b'developer': 17167db96d56Sopenharmony_ci print("this test triggers the Crash Reporter, " 17177db96d56Sopenharmony_ci "that is intentional", end='', flush=True) 17187db96d56Sopenharmony_ci 17197db96d56Sopenharmony_ci return self 17207db96d56Sopenharmony_ci 17217db96d56Sopenharmony_ci def __exit__(self, *ignore_exc): 17227db96d56Sopenharmony_ci """Restore Windows ErrorMode or core file behavior to initial value.""" 17237db96d56Sopenharmony_ci if self.old_value is None: 17247db96d56Sopenharmony_ci return 17257db96d56Sopenharmony_ci 17267db96d56Sopenharmony_ci if sys.platform.startswith('win'): 17277db96d56Sopenharmony_ci import msvcrt 17287db96d56Sopenharmony_ci msvcrt.SetErrorMode(self.old_value) 17297db96d56Sopenharmony_ci 17307db96d56Sopenharmony_ci if self.old_modes: 17317db96d56Sopenharmony_ci for report_type, (old_mode, old_file) in self.old_modes.items(): 17327db96d56Sopenharmony_ci msvcrt.CrtSetReportMode(report_type, old_mode) 17337db96d56Sopenharmony_ci msvcrt.CrtSetReportFile(report_type, old_file) 17347db96d56Sopenharmony_ci else: 17357db96d56Sopenharmony_ci if self.resource is not None: 17367db96d56Sopenharmony_ci try: 17377db96d56Sopenharmony_ci self.resource.setrlimit(self.resource.RLIMIT_CORE, self.old_value) 17387db96d56Sopenharmony_ci except (ValueError, OSError): 17397db96d56Sopenharmony_ci pass 17407db96d56Sopenharmony_ci 17417db96d56Sopenharmony_ci 17427db96d56Sopenharmony_cidef patch(test_instance, object_to_patch, attr_name, new_value): 17437db96d56Sopenharmony_ci """Override 'object_to_patch'.'attr_name' with 'new_value'. 17447db96d56Sopenharmony_ci 17457db96d56Sopenharmony_ci Also, add a cleanup procedure to 'test_instance' to restore 17467db96d56Sopenharmony_ci 'object_to_patch' value for 'attr_name'. 17477db96d56Sopenharmony_ci The 'attr_name' should be a valid attribute for 'object_to_patch'. 17487db96d56Sopenharmony_ci 17497db96d56Sopenharmony_ci """ 17507db96d56Sopenharmony_ci # check that 'attr_name' is a real attribute for 'object_to_patch' 17517db96d56Sopenharmony_ci # will raise AttributeError if it does not exist 17527db96d56Sopenharmony_ci getattr(object_to_patch, attr_name) 17537db96d56Sopenharmony_ci 17547db96d56Sopenharmony_ci # keep a copy of the old value 17557db96d56Sopenharmony_ci attr_is_local = False 17567db96d56Sopenharmony_ci try: 17577db96d56Sopenharmony_ci old_value = object_to_patch.__dict__[attr_name] 17587db96d56Sopenharmony_ci except (AttributeError, KeyError): 17597db96d56Sopenharmony_ci old_value = getattr(object_to_patch, attr_name, None) 17607db96d56Sopenharmony_ci else: 17617db96d56Sopenharmony_ci attr_is_local = True 17627db96d56Sopenharmony_ci 17637db96d56Sopenharmony_ci # restore the value when the test is done 17647db96d56Sopenharmony_ci def cleanup(): 17657db96d56Sopenharmony_ci if attr_is_local: 17667db96d56Sopenharmony_ci setattr(object_to_patch, attr_name, old_value) 17677db96d56Sopenharmony_ci else: 17687db96d56Sopenharmony_ci delattr(object_to_patch, attr_name) 17697db96d56Sopenharmony_ci 17707db96d56Sopenharmony_ci test_instance.addCleanup(cleanup) 17717db96d56Sopenharmony_ci 17727db96d56Sopenharmony_ci # actually override the attribute 17737db96d56Sopenharmony_ci setattr(object_to_patch, attr_name, new_value) 17747db96d56Sopenharmony_ci 17757db96d56Sopenharmony_ci 17767db96d56Sopenharmony_ci@contextlib.contextmanager 17777db96d56Sopenharmony_cidef patch_list(orig): 17787db96d56Sopenharmony_ci """Like unittest.mock.patch.dict, but for lists.""" 17797db96d56Sopenharmony_ci try: 17807db96d56Sopenharmony_ci saved = orig[:] 17817db96d56Sopenharmony_ci yield 17827db96d56Sopenharmony_ci finally: 17837db96d56Sopenharmony_ci orig[:] = saved 17847db96d56Sopenharmony_ci 17857db96d56Sopenharmony_ci 17867db96d56Sopenharmony_cidef run_in_subinterp(code): 17877db96d56Sopenharmony_ci """ 17887db96d56Sopenharmony_ci Run code in a subinterpreter. Raise unittest.SkipTest if the tracemalloc 17897db96d56Sopenharmony_ci module is enabled. 17907db96d56Sopenharmony_ci """ 17917db96d56Sopenharmony_ci # Issue #10915, #15751: PyGILState_*() functions don't work with 17927db96d56Sopenharmony_ci # sub-interpreters, the tracemalloc module uses these functions internally 17937db96d56Sopenharmony_ci try: 17947db96d56Sopenharmony_ci import tracemalloc 17957db96d56Sopenharmony_ci except ImportError: 17967db96d56Sopenharmony_ci pass 17977db96d56Sopenharmony_ci else: 17987db96d56Sopenharmony_ci if tracemalloc.is_tracing(): 17997db96d56Sopenharmony_ci raise unittest.SkipTest("run_in_subinterp() cannot be used " 18007db96d56Sopenharmony_ci "if tracemalloc module is tracing " 18017db96d56Sopenharmony_ci "memory allocations") 18027db96d56Sopenharmony_ci import _testcapi 18037db96d56Sopenharmony_ci return _testcapi.run_in_subinterp(code) 18047db96d56Sopenharmony_ci 18057db96d56Sopenharmony_ci 18067db96d56Sopenharmony_cidef check_free_after_iterating(test, iter, cls, args=()): 18077db96d56Sopenharmony_ci class A(cls): 18087db96d56Sopenharmony_ci def __del__(self): 18097db96d56Sopenharmony_ci nonlocal done 18107db96d56Sopenharmony_ci done = True 18117db96d56Sopenharmony_ci try: 18127db96d56Sopenharmony_ci next(it) 18137db96d56Sopenharmony_ci except StopIteration: 18147db96d56Sopenharmony_ci pass 18157db96d56Sopenharmony_ci 18167db96d56Sopenharmony_ci done = False 18177db96d56Sopenharmony_ci it = iter(A(*args)) 18187db96d56Sopenharmony_ci # Issue 26494: Shouldn't crash 18197db96d56Sopenharmony_ci test.assertRaises(StopIteration, next, it) 18207db96d56Sopenharmony_ci # The sequence should be deallocated just after the end of iterating 18217db96d56Sopenharmony_ci gc_collect() 18227db96d56Sopenharmony_ci test.assertTrue(done) 18237db96d56Sopenharmony_ci 18247db96d56Sopenharmony_ci 18257db96d56Sopenharmony_cidef missing_compiler_executable(cmd_names=[]): 18267db96d56Sopenharmony_ci """Check if the compiler components used to build the interpreter exist. 18277db96d56Sopenharmony_ci 18287db96d56Sopenharmony_ci Check for the existence of the compiler executables whose names are listed 18297db96d56Sopenharmony_ci in 'cmd_names' or all the compiler executables when 'cmd_names' is empty 18307db96d56Sopenharmony_ci and return the first missing executable or None when none is found 18317db96d56Sopenharmony_ci missing. 18327db96d56Sopenharmony_ci 18337db96d56Sopenharmony_ci """ 18347db96d56Sopenharmony_ci # TODO (PEP 632): alternate check without using distutils 18357db96d56Sopenharmony_ci from distutils import ccompiler, sysconfig, spawn, errors 18367db96d56Sopenharmony_ci compiler = ccompiler.new_compiler() 18377db96d56Sopenharmony_ci sysconfig.customize_compiler(compiler) 18387db96d56Sopenharmony_ci if compiler.compiler_type == "msvc": 18397db96d56Sopenharmony_ci # MSVC has no executables, so check whether initialization succeeds 18407db96d56Sopenharmony_ci try: 18417db96d56Sopenharmony_ci compiler.initialize() 18427db96d56Sopenharmony_ci except errors.DistutilsPlatformError: 18437db96d56Sopenharmony_ci return "msvc" 18447db96d56Sopenharmony_ci for name in compiler.executables: 18457db96d56Sopenharmony_ci if cmd_names and name not in cmd_names: 18467db96d56Sopenharmony_ci continue 18477db96d56Sopenharmony_ci cmd = getattr(compiler, name) 18487db96d56Sopenharmony_ci if cmd_names: 18497db96d56Sopenharmony_ci assert cmd is not None, \ 18507db96d56Sopenharmony_ci "the '%s' executable is not configured" % name 18517db96d56Sopenharmony_ci elif not cmd: 18527db96d56Sopenharmony_ci continue 18537db96d56Sopenharmony_ci if spawn.find_executable(cmd[0]) is None: 18547db96d56Sopenharmony_ci return cmd[0] 18557db96d56Sopenharmony_ci 18567db96d56Sopenharmony_ci 18577db96d56Sopenharmony_ci_is_android_emulator = None 18587db96d56Sopenharmony_cidef setswitchinterval(interval): 18597db96d56Sopenharmony_ci # Setting a very low gil interval on the Android emulator causes python 18607db96d56Sopenharmony_ci # to hang (issue #26939). 18617db96d56Sopenharmony_ci minimum_interval = 1e-5 18627db96d56Sopenharmony_ci if is_android and interval < minimum_interval: 18637db96d56Sopenharmony_ci global _is_android_emulator 18647db96d56Sopenharmony_ci if _is_android_emulator is None: 18657db96d56Sopenharmony_ci import subprocess 18667db96d56Sopenharmony_ci _is_android_emulator = (subprocess.check_output( 18677db96d56Sopenharmony_ci ['getprop', 'ro.kernel.qemu']).strip() == b'1') 18687db96d56Sopenharmony_ci if _is_android_emulator: 18697db96d56Sopenharmony_ci interval = minimum_interval 18707db96d56Sopenharmony_ci return sys.setswitchinterval(interval) 18717db96d56Sopenharmony_ci 18727db96d56Sopenharmony_ci 18737db96d56Sopenharmony_ci@contextlib.contextmanager 18747db96d56Sopenharmony_cidef disable_faulthandler(): 18757db96d56Sopenharmony_ci import faulthandler 18767db96d56Sopenharmony_ci 18777db96d56Sopenharmony_ci # use sys.__stderr__ instead of sys.stderr, since regrtest replaces 18787db96d56Sopenharmony_ci # sys.stderr with a StringIO which has no file descriptor when a test 18797db96d56Sopenharmony_ci # is run with -W/--verbose3. 18807db96d56Sopenharmony_ci fd = sys.__stderr__.fileno() 18817db96d56Sopenharmony_ci 18827db96d56Sopenharmony_ci is_enabled = faulthandler.is_enabled() 18837db96d56Sopenharmony_ci try: 18847db96d56Sopenharmony_ci faulthandler.disable() 18857db96d56Sopenharmony_ci yield 18867db96d56Sopenharmony_ci finally: 18877db96d56Sopenharmony_ci if is_enabled: 18887db96d56Sopenharmony_ci faulthandler.enable(file=fd, all_threads=True) 18897db96d56Sopenharmony_ci 18907db96d56Sopenharmony_ci 18917db96d56Sopenharmony_ciclass SaveSignals: 18927db96d56Sopenharmony_ci """ 18937db96d56Sopenharmony_ci Save and restore signal handlers. 18947db96d56Sopenharmony_ci 18957db96d56Sopenharmony_ci This class is only able to save/restore signal handlers registered 18967db96d56Sopenharmony_ci by the Python signal module: see bpo-13285 for "external" signal 18977db96d56Sopenharmony_ci handlers. 18987db96d56Sopenharmony_ci """ 18997db96d56Sopenharmony_ci 19007db96d56Sopenharmony_ci def __init__(self): 19017db96d56Sopenharmony_ci import signal 19027db96d56Sopenharmony_ci self.signal = signal 19037db96d56Sopenharmony_ci self.signals = signal.valid_signals() 19047db96d56Sopenharmony_ci # SIGKILL and SIGSTOP signals cannot be ignored nor caught 19057db96d56Sopenharmony_ci for signame in ('SIGKILL', 'SIGSTOP'): 19067db96d56Sopenharmony_ci try: 19077db96d56Sopenharmony_ci signum = getattr(signal, signame) 19087db96d56Sopenharmony_ci except AttributeError: 19097db96d56Sopenharmony_ci continue 19107db96d56Sopenharmony_ci self.signals.remove(signum) 19117db96d56Sopenharmony_ci self.handlers = {} 19127db96d56Sopenharmony_ci 19137db96d56Sopenharmony_ci def save(self): 19147db96d56Sopenharmony_ci for signum in self.signals: 19157db96d56Sopenharmony_ci handler = self.signal.getsignal(signum) 19167db96d56Sopenharmony_ci if handler is None: 19177db96d56Sopenharmony_ci # getsignal() returns None if a signal handler was not 19187db96d56Sopenharmony_ci # registered by the Python signal module, 19197db96d56Sopenharmony_ci # and the handler is not SIG_DFL nor SIG_IGN. 19207db96d56Sopenharmony_ci # 19217db96d56Sopenharmony_ci # Ignore the signal: we cannot restore the handler. 19227db96d56Sopenharmony_ci continue 19237db96d56Sopenharmony_ci self.handlers[signum] = handler 19247db96d56Sopenharmony_ci 19257db96d56Sopenharmony_ci def restore(self): 19267db96d56Sopenharmony_ci for signum, handler in self.handlers.items(): 19277db96d56Sopenharmony_ci self.signal.signal(signum, handler) 19287db96d56Sopenharmony_ci 19297db96d56Sopenharmony_ci 19307db96d56Sopenharmony_cidef with_pymalloc(): 19317db96d56Sopenharmony_ci import _testcapi 19327db96d56Sopenharmony_ci return _testcapi.WITH_PYMALLOC 19337db96d56Sopenharmony_ci 19347db96d56Sopenharmony_ci 19357db96d56Sopenharmony_ciclass _ALWAYS_EQ: 19367db96d56Sopenharmony_ci """ 19377db96d56Sopenharmony_ci Object that is equal to anything. 19387db96d56Sopenharmony_ci """ 19397db96d56Sopenharmony_ci def __eq__(self, other): 19407db96d56Sopenharmony_ci return True 19417db96d56Sopenharmony_ci def __ne__(self, other): 19427db96d56Sopenharmony_ci return False 19437db96d56Sopenharmony_ci 19447db96d56Sopenharmony_ciALWAYS_EQ = _ALWAYS_EQ() 19457db96d56Sopenharmony_ci 19467db96d56Sopenharmony_ciclass _NEVER_EQ: 19477db96d56Sopenharmony_ci """ 19487db96d56Sopenharmony_ci Object that is not equal to anything. 19497db96d56Sopenharmony_ci """ 19507db96d56Sopenharmony_ci def __eq__(self, other): 19517db96d56Sopenharmony_ci return False 19527db96d56Sopenharmony_ci def __ne__(self, other): 19537db96d56Sopenharmony_ci return True 19547db96d56Sopenharmony_ci def __hash__(self): 19557db96d56Sopenharmony_ci return 1 19567db96d56Sopenharmony_ci 19577db96d56Sopenharmony_ciNEVER_EQ = _NEVER_EQ() 19587db96d56Sopenharmony_ci 19597db96d56Sopenharmony_ci@functools.total_ordering 19607db96d56Sopenharmony_ciclass _LARGEST: 19617db96d56Sopenharmony_ci """ 19627db96d56Sopenharmony_ci Object that is greater than anything (except itself). 19637db96d56Sopenharmony_ci """ 19647db96d56Sopenharmony_ci def __eq__(self, other): 19657db96d56Sopenharmony_ci return isinstance(other, _LARGEST) 19667db96d56Sopenharmony_ci def __lt__(self, other): 19677db96d56Sopenharmony_ci return False 19687db96d56Sopenharmony_ci 19697db96d56Sopenharmony_ciLARGEST = _LARGEST() 19707db96d56Sopenharmony_ci 19717db96d56Sopenharmony_ci@functools.total_ordering 19727db96d56Sopenharmony_ciclass _SMALLEST: 19737db96d56Sopenharmony_ci """ 19747db96d56Sopenharmony_ci Object that is less than anything (except itself). 19757db96d56Sopenharmony_ci """ 19767db96d56Sopenharmony_ci def __eq__(self, other): 19777db96d56Sopenharmony_ci return isinstance(other, _SMALLEST) 19787db96d56Sopenharmony_ci def __gt__(self, other): 19797db96d56Sopenharmony_ci return False 19807db96d56Sopenharmony_ci 19817db96d56Sopenharmony_ciSMALLEST = _SMALLEST() 19827db96d56Sopenharmony_ci 19837db96d56Sopenharmony_cidef maybe_get_event_loop_policy(): 19847db96d56Sopenharmony_ci """Return the global event loop policy if one is set, else return None.""" 19857db96d56Sopenharmony_ci import asyncio.events 19867db96d56Sopenharmony_ci return asyncio.events._event_loop_policy 19877db96d56Sopenharmony_ci 19887db96d56Sopenharmony_ci# Helpers for testing hashing. 19897db96d56Sopenharmony_ciNHASHBITS = sys.hash_info.width # number of bits in hash() result 19907db96d56Sopenharmony_ciassert NHASHBITS in (32, 64) 19917db96d56Sopenharmony_ci 19927db96d56Sopenharmony_ci# Return mean and sdev of number of collisions when tossing nballs balls 19937db96d56Sopenharmony_ci# uniformly at random into nbins bins. By definition, the number of 19947db96d56Sopenharmony_ci# collisions is the number of balls minus the number of occupied bins at 19957db96d56Sopenharmony_ci# the end. 19967db96d56Sopenharmony_cidef collision_stats(nbins, nballs): 19977db96d56Sopenharmony_ci n, k = nbins, nballs 19987db96d56Sopenharmony_ci # prob a bin empty after k trials = (1 - 1/n)**k 19997db96d56Sopenharmony_ci # mean # empty is then n * (1 - 1/n)**k 20007db96d56Sopenharmony_ci # so mean # occupied is n - n * (1 - 1/n)**k 20017db96d56Sopenharmony_ci # so collisions = k - (n - n*(1 - 1/n)**k) 20027db96d56Sopenharmony_ci # 20037db96d56Sopenharmony_ci # For the variance: 20047db96d56Sopenharmony_ci # n*(n-1)*(1-2/n)**k + meanempty - meanempty**2 = 20057db96d56Sopenharmony_ci # n*(n-1)*(1-2/n)**k + meanempty * (1 - meanempty) 20067db96d56Sopenharmony_ci # 20077db96d56Sopenharmony_ci # Massive cancellation occurs, and, e.g., for a 64-bit hash code 20087db96d56Sopenharmony_ci # 1-1/2**64 rounds uselessly to 1.0. Rather than make heroic (and 20097db96d56Sopenharmony_ci # error-prone) efforts to rework the naive formulas to avoid those, 20107db96d56Sopenharmony_ci # we use the `decimal` module to get plenty of extra precision. 20117db96d56Sopenharmony_ci # 20127db96d56Sopenharmony_ci # Note: the exact values are straightforward to compute with 20137db96d56Sopenharmony_ci # rationals, but in context that's unbearably slow, requiring 20147db96d56Sopenharmony_ci # multi-million bit arithmetic. 20157db96d56Sopenharmony_ci import decimal 20167db96d56Sopenharmony_ci with decimal.localcontext() as ctx: 20177db96d56Sopenharmony_ci bits = n.bit_length() * 2 # bits in n**2 20187db96d56Sopenharmony_ci # At least that many bits will likely cancel out. 20197db96d56Sopenharmony_ci # Use that many decimal digits instead. 20207db96d56Sopenharmony_ci ctx.prec = max(bits, 30) 20217db96d56Sopenharmony_ci dn = decimal.Decimal(n) 20227db96d56Sopenharmony_ci p1empty = ((dn - 1) / dn) ** k 20237db96d56Sopenharmony_ci meanempty = n * p1empty 20247db96d56Sopenharmony_ci occupied = n - meanempty 20257db96d56Sopenharmony_ci collisions = k - occupied 20267db96d56Sopenharmony_ci var = dn*(dn-1)*((dn-2)/dn)**k + meanempty * (1 - meanempty) 20277db96d56Sopenharmony_ci return float(collisions), float(var.sqrt()) 20287db96d56Sopenharmony_ci 20297db96d56Sopenharmony_ci 20307db96d56Sopenharmony_ciclass catch_unraisable_exception: 20317db96d56Sopenharmony_ci """ 20327db96d56Sopenharmony_ci Context manager catching unraisable exception using sys.unraisablehook. 20337db96d56Sopenharmony_ci 20347db96d56Sopenharmony_ci Storing the exception value (cm.unraisable.exc_value) creates a reference 20357db96d56Sopenharmony_ci cycle. The reference cycle is broken explicitly when the context manager 20367db96d56Sopenharmony_ci exits. 20377db96d56Sopenharmony_ci 20387db96d56Sopenharmony_ci Storing the object (cm.unraisable.object) can resurrect it if it is set to 20397db96d56Sopenharmony_ci an object which is being finalized. Exiting the context manager clears the 20407db96d56Sopenharmony_ci stored object. 20417db96d56Sopenharmony_ci 20427db96d56Sopenharmony_ci Usage: 20437db96d56Sopenharmony_ci 20447db96d56Sopenharmony_ci with support.catch_unraisable_exception() as cm: 20457db96d56Sopenharmony_ci # code creating an "unraisable exception" 20467db96d56Sopenharmony_ci ... 20477db96d56Sopenharmony_ci 20487db96d56Sopenharmony_ci # check the unraisable exception: use cm.unraisable 20497db96d56Sopenharmony_ci ... 20507db96d56Sopenharmony_ci 20517db96d56Sopenharmony_ci # cm.unraisable attribute no longer exists at this point 20527db96d56Sopenharmony_ci # (to break a reference cycle) 20537db96d56Sopenharmony_ci """ 20547db96d56Sopenharmony_ci 20557db96d56Sopenharmony_ci def __init__(self): 20567db96d56Sopenharmony_ci self.unraisable = None 20577db96d56Sopenharmony_ci self._old_hook = None 20587db96d56Sopenharmony_ci 20597db96d56Sopenharmony_ci def _hook(self, unraisable): 20607db96d56Sopenharmony_ci # Storing unraisable.object can resurrect an object which is being 20617db96d56Sopenharmony_ci # finalized. Storing unraisable.exc_value creates a reference cycle. 20627db96d56Sopenharmony_ci self.unraisable = unraisable 20637db96d56Sopenharmony_ci 20647db96d56Sopenharmony_ci def __enter__(self): 20657db96d56Sopenharmony_ci self._old_hook = sys.unraisablehook 20667db96d56Sopenharmony_ci sys.unraisablehook = self._hook 20677db96d56Sopenharmony_ci return self 20687db96d56Sopenharmony_ci 20697db96d56Sopenharmony_ci def __exit__(self, *exc_info): 20707db96d56Sopenharmony_ci sys.unraisablehook = self._old_hook 20717db96d56Sopenharmony_ci del self.unraisable 20727db96d56Sopenharmony_ci 20737db96d56Sopenharmony_ci 20747db96d56Sopenharmony_cidef wait_process(pid, *, exitcode, timeout=None): 20757db96d56Sopenharmony_ci """ 20767db96d56Sopenharmony_ci Wait until process pid completes and check that the process exit code is 20777db96d56Sopenharmony_ci exitcode. 20787db96d56Sopenharmony_ci 20797db96d56Sopenharmony_ci Raise an AssertionError if the process exit code is not equal to exitcode. 20807db96d56Sopenharmony_ci 20817db96d56Sopenharmony_ci If the process runs longer than timeout seconds (LONG_TIMEOUT by default), 20827db96d56Sopenharmony_ci kill the process (if signal.SIGKILL is available) and raise an 20837db96d56Sopenharmony_ci AssertionError. The timeout feature is not available on Windows. 20847db96d56Sopenharmony_ci """ 20857db96d56Sopenharmony_ci if os.name != "nt": 20867db96d56Sopenharmony_ci import signal 20877db96d56Sopenharmony_ci 20887db96d56Sopenharmony_ci if timeout is None: 20897db96d56Sopenharmony_ci timeout = LONG_TIMEOUT 20907db96d56Sopenharmony_ci t0 = time.monotonic() 20917db96d56Sopenharmony_ci sleep = 0.001 20927db96d56Sopenharmony_ci max_sleep = 0.1 20937db96d56Sopenharmony_ci while True: 20947db96d56Sopenharmony_ci pid2, status = os.waitpid(pid, os.WNOHANG) 20957db96d56Sopenharmony_ci if pid2 != 0: 20967db96d56Sopenharmony_ci break 20977db96d56Sopenharmony_ci # process is still running 20987db96d56Sopenharmony_ci 20997db96d56Sopenharmony_ci dt = time.monotonic() - t0 21007db96d56Sopenharmony_ci if dt > timeout: 21017db96d56Sopenharmony_ci try: 21027db96d56Sopenharmony_ci os.kill(pid, signal.SIGKILL) 21037db96d56Sopenharmony_ci os.waitpid(pid, 0) 21047db96d56Sopenharmony_ci except OSError: 21057db96d56Sopenharmony_ci # Ignore errors like ChildProcessError or PermissionError 21067db96d56Sopenharmony_ci pass 21077db96d56Sopenharmony_ci 21087db96d56Sopenharmony_ci raise AssertionError(f"process {pid} is still running " 21097db96d56Sopenharmony_ci f"after {dt:.1f} seconds") 21107db96d56Sopenharmony_ci 21117db96d56Sopenharmony_ci sleep = min(sleep * 2, max_sleep) 21127db96d56Sopenharmony_ci time.sleep(sleep) 21137db96d56Sopenharmony_ci else: 21147db96d56Sopenharmony_ci # Windows implementation 21157db96d56Sopenharmony_ci pid2, status = os.waitpid(pid, 0) 21167db96d56Sopenharmony_ci 21177db96d56Sopenharmony_ci exitcode2 = os.waitstatus_to_exitcode(status) 21187db96d56Sopenharmony_ci if exitcode2 != exitcode: 21197db96d56Sopenharmony_ci raise AssertionError(f"process {pid} exited with code {exitcode2}, " 21207db96d56Sopenharmony_ci f"but exit code {exitcode} is expected") 21217db96d56Sopenharmony_ci 21227db96d56Sopenharmony_ci # sanity check: it should not fail in practice 21237db96d56Sopenharmony_ci if pid2 != pid: 21247db96d56Sopenharmony_ci raise AssertionError(f"pid {pid2} != pid {pid}") 21257db96d56Sopenharmony_ci 21267db96d56Sopenharmony_cidef skip_if_broken_multiprocessing_synchronize(): 21277db96d56Sopenharmony_ci """ 21287db96d56Sopenharmony_ci Skip tests if the multiprocessing.synchronize module is missing, if there 21297db96d56Sopenharmony_ci is no available semaphore implementation, or if creating a lock raises an 21307db96d56Sopenharmony_ci OSError (on Linux only). 21317db96d56Sopenharmony_ci """ 21327db96d56Sopenharmony_ci from .import_helper import import_module 21337db96d56Sopenharmony_ci 21347db96d56Sopenharmony_ci # Skip tests if the _multiprocessing extension is missing. 21357db96d56Sopenharmony_ci import_module('_multiprocessing') 21367db96d56Sopenharmony_ci 21377db96d56Sopenharmony_ci # Skip tests if there is no available semaphore implementation: 21387db96d56Sopenharmony_ci # multiprocessing.synchronize requires _multiprocessing.SemLock. 21397db96d56Sopenharmony_ci synchronize = import_module('multiprocessing.synchronize') 21407db96d56Sopenharmony_ci 21417db96d56Sopenharmony_ci if sys.platform == "linux": 21427db96d56Sopenharmony_ci try: 21437db96d56Sopenharmony_ci # bpo-38377: On Linux, creating a semaphore fails with OSError 21447db96d56Sopenharmony_ci # if the current user does not have the permission to create 21457db96d56Sopenharmony_ci # a file in /dev/shm/ directory. 21467db96d56Sopenharmony_ci synchronize.Lock(ctx=None) 21477db96d56Sopenharmony_ci except OSError as exc: 21487db96d56Sopenharmony_ci raise unittest.SkipTest(f"broken multiprocessing SemLock: {exc!r}") 21497db96d56Sopenharmony_ci 21507db96d56Sopenharmony_ci 21517db96d56Sopenharmony_cidef check_disallow_instantiation(testcase, tp, *args, **kwds): 21527db96d56Sopenharmony_ci """ 21537db96d56Sopenharmony_ci Check that given type cannot be instantiated using *args and **kwds. 21547db96d56Sopenharmony_ci 21557db96d56Sopenharmony_ci See bpo-43916: Add Py_TPFLAGS_DISALLOW_INSTANTIATION type flag. 21567db96d56Sopenharmony_ci """ 21577db96d56Sopenharmony_ci mod = tp.__module__ 21587db96d56Sopenharmony_ci name = tp.__name__ 21597db96d56Sopenharmony_ci if mod != 'builtins': 21607db96d56Sopenharmony_ci qualname = f"{mod}.{name}" 21617db96d56Sopenharmony_ci else: 21627db96d56Sopenharmony_ci qualname = f"{name}" 21637db96d56Sopenharmony_ci msg = f"cannot create '{re.escape(qualname)}' instances" 21647db96d56Sopenharmony_ci testcase.assertRaisesRegex(TypeError, msg, tp, *args, **kwds) 21657db96d56Sopenharmony_ci 21667db96d56Sopenharmony_ci@contextlib.contextmanager 21677db96d56Sopenharmony_cidef infinite_recursion(max_depth=75): 21687db96d56Sopenharmony_ci """Set a lower limit for tests that interact with infinite recursions 21697db96d56Sopenharmony_ci (e.g test_ast.ASTHelpers_Test.test_recursion_direct) since on some 21707db96d56Sopenharmony_ci debug windows builds, due to not enough functions being inlined the 21717db96d56Sopenharmony_ci stack size might not handle the default recursion limit (1000). See 21727db96d56Sopenharmony_ci bpo-11105 for details.""" 21737db96d56Sopenharmony_ci 21747db96d56Sopenharmony_ci original_depth = sys.getrecursionlimit() 21757db96d56Sopenharmony_ci try: 21767db96d56Sopenharmony_ci sys.setrecursionlimit(max_depth) 21777db96d56Sopenharmony_ci yield 21787db96d56Sopenharmony_ci finally: 21797db96d56Sopenharmony_ci sys.setrecursionlimit(original_depth) 21807db96d56Sopenharmony_ci 21817db96d56Sopenharmony_cidef ignore_deprecations_from(module: str, *, like: str) -> object: 21827db96d56Sopenharmony_ci token = object() 21837db96d56Sopenharmony_ci warnings.filterwarnings( 21847db96d56Sopenharmony_ci "ignore", 21857db96d56Sopenharmony_ci category=DeprecationWarning, 21867db96d56Sopenharmony_ci module=module, 21877db96d56Sopenharmony_ci message=like + fr"(?#support{id(token)})", 21887db96d56Sopenharmony_ci ) 21897db96d56Sopenharmony_ci return token 21907db96d56Sopenharmony_ci 21917db96d56Sopenharmony_cidef clear_ignored_deprecations(*tokens: object) -> None: 21927db96d56Sopenharmony_ci if not tokens: 21937db96d56Sopenharmony_ci raise ValueError("Provide token or tokens returned by ignore_deprecations_from") 21947db96d56Sopenharmony_ci 21957db96d56Sopenharmony_ci new_filters = [] 21967db96d56Sopenharmony_ci endswith = tuple(rf"(?#support{id(token)})" for token in tokens) 21977db96d56Sopenharmony_ci for action, message, category, module, lineno in warnings.filters: 21987db96d56Sopenharmony_ci if action == "ignore" and category is DeprecationWarning: 21997db96d56Sopenharmony_ci if isinstance(message, re.Pattern): 22007db96d56Sopenharmony_ci msg = message.pattern 22017db96d56Sopenharmony_ci else: 22027db96d56Sopenharmony_ci msg = message or "" 22037db96d56Sopenharmony_ci if msg.endswith(endswith): 22047db96d56Sopenharmony_ci continue 22057db96d56Sopenharmony_ci new_filters.append((action, message, category, module, lineno)) 22067db96d56Sopenharmony_ci if warnings.filters != new_filters: 22077db96d56Sopenharmony_ci warnings.filters[:] = new_filters 22087db96d56Sopenharmony_ci warnings._filters_mutated() 22097db96d56Sopenharmony_ci 22107db96d56Sopenharmony_ci 22117db96d56Sopenharmony_ci# Skip a test if venv with pip is known to not work. 22127db96d56Sopenharmony_cidef requires_venv_with_pip(): 22137db96d56Sopenharmony_ci # ensurepip requires zlib to open ZIP archives (.whl binary wheel packages) 22147db96d56Sopenharmony_ci try: 22157db96d56Sopenharmony_ci import zlib 22167db96d56Sopenharmony_ci except ImportError: 22177db96d56Sopenharmony_ci return unittest.skipIf(True, "venv: ensurepip requires zlib") 22187db96d56Sopenharmony_ci 22197db96d56Sopenharmony_ci # bpo-26610: pip/pep425tags.py requires ctypes. 22207db96d56Sopenharmony_ci # gh-92820: setuptools/windows_support.py uses ctypes (setuptools 58.1). 22217db96d56Sopenharmony_ci try: 22227db96d56Sopenharmony_ci import ctypes 22237db96d56Sopenharmony_ci except ImportError: 22247db96d56Sopenharmony_ci ctypes = None 22257db96d56Sopenharmony_ci return unittest.skipUnless(ctypes, 'venv: pip requires ctypes') 22267db96d56Sopenharmony_ci 22277db96d56Sopenharmony_ci 22287db96d56Sopenharmony_ci@contextlib.contextmanager 22297db96d56Sopenharmony_cidef adjust_int_max_str_digits(max_digits): 22307db96d56Sopenharmony_ci """Temporarily change the integer string conversion length limit.""" 22317db96d56Sopenharmony_ci current = sys.get_int_max_str_digits() 22327db96d56Sopenharmony_ci try: 22337db96d56Sopenharmony_ci sys.set_int_max_str_digits(max_digits) 22347db96d56Sopenharmony_ci yield 22357db96d56Sopenharmony_ci finally: 22367db96d56Sopenharmony_ci sys.set_int_max_str_digits(current) 2237