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