import contextlib
import errno
import importlib
import itertools
import inspect
import io
import logging
import os
import shutil
import signal
import socket
import stat
import subprocess
import sys
import sysconfig
import tempfile
import textwrap
import unittest
import warnings

from test import support
from test.support import hashlib_helper
from test.support import import_helper
from test.support import os_helper
from test.support import script_helper
from test.support import socket_helper
from test.support import warnings_helper

TESTFN = os_helper.TESTFN


class LogCaptureHandler(logging.StreamHandler):
    # Inspired by pytest's caplog
    def __init__(self):
        super().__init__(io.StringIO())
        self.records = []

    def emit(self, record) -> None:
        self.records.append(record)
        super().emit(record)

    def handleError(self, record):
        raise


@contextlib.contextmanager
def _caplog():
    handler = LogCaptureHandler()
    root_logger = logging.getLogger()
    root_logger.addHandler(handler)
    try:
        yield handler
    finally:
        root_logger.removeHandler(handler)


class TestSupport(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        orig_filter_len = len(warnings._get_filters())
        cls._warnings_helper_token = support.ignore_deprecations_from(
            "test.support.warnings_helper", like=".*used in test_support.*"
        )
        cls._test_support_token = support.ignore_deprecations_from(
            __name__, like=".*You should NOT be seeing this.*"
        )
        assert len(warnings._get_filters()) == orig_filter_len + 2

    @classmethod
    def tearDownClass(cls):
        orig_filter_len = len(warnings._get_filters())
        support.clear_ignored_deprecations(
            cls._warnings_helper_token,
            cls._test_support_token,
        )
        assert len(warnings._get_filters()) == orig_filter_len - 2

    def test_ignored_deprecations_are_silent(self):
        """Test support.ignore_deprecations_from() silences warnings"""
        with warnings.catch_warnings(record=True) as warning_objs:
            warnings_helper._warn_about_deprecation()
            warnings.warn("You should NOT be seeing this.", DeprecationWarning)
            messages = [str(w.message) for w in warning_objs]
        self.assertEqual(len(messages), 0, messages)

    def test_import_module(self):
        import_helper.import_module("ftplib")
        self.assertRaises(unittest.SkipTest,
                          import_helper.import_module, "foo")

    def test_import_fresh_module(self):
        import_helper.import_fresh_module("ftplib")

    def test_get_attribute(self):
        self.assertEqual(support.get_attribute(self, "test_get_attribute"),
                        self.test_get_attribute)
        self.assertRaises(unittest.SkipTest, support.get_attribute, self, "foo")

    @unittest.skipIf(support.is_android or support.is_apple_mobile,
                     'Mobile platforms redirect stdout to system log')
    def test_get_original_stdout(self):
        if isinstance(sys.stdout, io.StringIO):
            # gh-55258: When --junit-xml is used, stdout is a StringIO:
            # use sys.__stdout__ in this case.
            self.assertEqual(support.get_original_stdout(), sys.__stdout__)
        else:
            self.assertEqual(support.get_original_stdout(), sys.stdout)

    def test_unload(self):
        import sched  # noqa: F401
        self.assertIn("sched", sys.modules)
        import_helper.unload("sched")
        self.assertNotIn("sched", sys.modules)

    def test_unlink(self):
        with open(TESTFN, "w", encoding="utf-8") as f:
            pass
        os_helper.unlink(TESTFN)
        self.assertFalse(os.path.exists(TESTFN))
        os_helper.unlink(TESTFN)

    def test_rmtree(self):
        dirpath = os_helper.TESTFN + 'd'
        subdirpath = os.path.join(dirpath, 'subdir')
        os.mkdir(dirpath)
        os.mkdir(subdirpath)
        os_helper.rmtree(dirpath)
        self.assertFalse(os.path.exists(dirpath))
        with support.swap_attr(support, 'verbose', 0):
            os_helper.rmtree(dirpath)

        os.mkdir(dirpath)
        os.mkdir(subdirpath)
        os.chmod(dirpath, stat.S_IRUSR|stat.S_IXUSR)
        with support.swap_attr(support, 'verbose', 0):
            os_helper.rmtree(dirpath)
        self.assertFalse(os.path.exists(dirpath))

        os.mkdir(dirpath)
        os.mkdir(subdirpath)
        os.chmod(dirpath, 0)
        with support.swap_attr(support, 'verbose', 0):
            os_helper.rmtree(dirpath)
        self.assertFalse(os.path.exists(dirpath))

    def test_forget(self):
        mod_filename = TESTFN + '.py'
        with open(mod_filename, 'w', encoding="utf-8") as f:
            print('foo = 1', file=f)
        sys.path.insert(0, os.curdir)
        importlib.invalidate_caches()
        try:
            mod = __import__(TESTFN)
            self.assertIn(TESTFN, sys.modules)

            import_helper.forget(TESTFN)
            self.assertNotIn(TESTFN, sys.modules)
        finally:
            del sys.path[0]
            os_helper.unlink(mod_filename)
            os_helper.rmtree('__pycache__')

    @support.requires_working_socket()
    def test_HOST(self):
        s = socket.create_server((socket_helper.HOST, 0))
        s.close()

    @support.requires_working_socket()
    def test_find_unused_port(self):
        port = socket_helper.find_unused_port()
        s = socket.create_server((socket_helper.HOST, port))
        s.close()

    @support.requires_working_socket()
    def test_bind_port(self):
        s = socket.socket()
        socket_helper.bind_port(s)
        s.listen()
        s.close()

    # Tests for temp_dir()

    def test_temp_dir(self):
        """Test that temp_dir() creates and destroys its directory."""
        parent_dir = tempfile.mkdtemp()
        parent_dir = os.path.realpath(parent_dir)

        try:
            path = os.path.join(parent_dir, 'temp')
            self.assertFalse(os.path.isdir(path))
            with os_helper.temp_dir(path) as temp_path:
                self.assertEqual(temp_path, path)
                self.assertTrue(os.path.isdir(path))
            self.assertFalse(os.path.isdir(path))
        finally:
            os_helper.rmtree(parent_dir)

    def test_temp_dir__path_none(self):
        """Test passing no path."""
        with os_helper.temp_dir() as temp_path:
            self.assertTrue(os.path.isdir(temp_path))
        self.assertFalse(os.path.isdir(temp_path))

    def test_temp_dir__existing_dir__quiet_default(self):
        """Test passing a directory that already exists."""
        def call_temp_dir(path):
            with os_helper.temp_dir(path) as temp_path:
                raise Exception("should not get here")

        path = tempfile.mkdtemp()
        path = os.path.realpath(path)
        try:
            self.assertTrue(os.path.isdir(path))
            self.assertRaises(FileExistsError, call_temp_dir, path)
            # Make sure temp_dir did not delete the original directory.
            self.assertTrue(os.path.isdir(path))
        finally:
            shutil.rmtree(path)

    def test_temp_dir__existing_dir__quiet_true(self):
        """Test passing a directory that already exists with quiet=True."""
        path = tempfile.mkdtemp()
        path = os.path.realpath(path)

        try:
            with warnings_helper.check_warnings() as recorder, _caplog() as caplog:
                with os_helper.temp_dir(path, quiet=True) as temp_path:
                    self.assertEqual(path, temp_path)
                warnings = [str(w.message) for w in recorder.warnings]
            # Make sure temp_dir did not delete the original directory.
            self.assertTrue(os.path.isdir(path))
        finally:
            shutil.rmtree(path)

        self.assertListEqual(warnings, [])
        self.assertEqual(len(caplog.records), 1)
        record = caplog.records[0]
        self.assertStartsWith(
            record.getMessage(),
            f'tests may fail, unable to create '
            f'temporary directory {path!r}: '
        )

    @support.requires_fork()
    def test_temp_dir__forked_child(self):
        """Test that a forked child process does not remove the directory."""
        # See bpo-30028 for details.
        # Run the test as an external script, because it uses fork.
        script_helper.assert_python_ok("-c", textwrap.dedent("""
            import os
            from test import support
            from test.support import os_helper
            with os_helper.temp_cwd() as temp_path:
                pid = os.fork()
                if pid != 0:
                    # parent process

                    # wait for the child to terminate
                    support.wait_process(pid, exitcode=0)

                    # Make sure that temp_path is still present. When the child
                    # process leaves the 'temp_cwd'-context, the __exit__()-
                    # method of the context must not remove the temporary
                    # directory.
                    if not os.path.isdir(temp_path):
                        raise AssertionError("Child removed temp_path.")
        """))

    # Tests for change_cwd()

    def test_change_cwd(self):
        original_cwd = os.getcwd()

        with os_helper.temp_dir() as temp_path:
            with os_helper.change_cwd(temp_path) as new_cwd:
                self.assertEqual(new_cwd, temp_path)
                self.assertEqual(os.getcwd(), new_cwd)

        self.assertEqual(os.getcwd(), original_cwd)

    def test_change_cwd__non_existent_dir(self):
        """Test passing a non-existent directory."""
        original_cwd = os.getcwd()

        def call_change_cwd(path):
            with os_helper.change_cwd(path) as new_cwd:
                raise Exception("should not get here")

        with os_helper.temp_dir() as parent_dir:
            non_existent_dir = os.path.join(parent_dir, 'does_not_exist')
            self.assertRaises(FileNotFoundError, call_change_cwd,
                              non_existent_dir)

        self.assertEqual(os.getcwd(), original_cwd)

    def test_change_cwd__non_existent_dir__quiet_true(self):
        """Test passing a non-existent directory with quiet=True."""
        original_cwd = os.getcwd()

        with os_helper.temp_dir() as parent_dir:
            bad_dir = os.path.join(parent_dir, 'does_not_exist')
            with warnings_helper.check_warnings() as recorder, _caplog() as caplog:
                with os_helper.change_cwd(bad_dir, quiet=True) as new_cwd:
                    self.assertEqual(new_cwd, original_cwd)
                    self.assertEqual(os.getcwd(), new_cwd)
                warnings = [str(w.message) for w in recorder.warnings]

        self.assertListEqual(warnings, [])
        self.assertEqual(len(caplog.records), 1)
        record = caplog.records[0]
        self.assertStartsWith(
            record.getMessage(),
            f'tests may fail, unable to change '
            f'the current working directory '
            f'to {bad_dir!r}: '
        )

    # Tests for change_cwd()

    def test_change_cwd__chdir_warning(self):
        """Check the warning message when os.chdir() fails."""
        path = TESTFN + '_does_not_exist'
        with warnings_helper.check_warnings() as recorder, _caplog() as caplog:
            with os_helper.change_cwd(path=path, quiet=True):
                pass
            messages = [str(w.message) for w in recorder.warnings]

        self.assertListEqual(messages, [])
        self.assertEqual(len(caplog.records), 1)
        record = caplog.records[0]
        self.assertStartsWith(
            record.getMessage(),
            f'tests may fail, unable to change '
            f'the current working directory '
            f'to {path!r}: ',
        )

    # Tests for temp_cwd()

    def test_temp_cwd(self):
        here = os.getcwd()
        with os_helper.temp_cwd(name=TESTFN):
            self.assertEqual(os.path.basename(os.getcwd()), TESTFN)
        self.assertFalse(os.path.exists(TESTFN))
        self.assertEqual(os.getcwd(), here)


    def test_temp_cwd__name_none(self):
        """Test passing None to temp_cwd()."""
        original_cwd = os.getcwd()
        with os_helper.temp_cwd(name=None) as new_cwd:
            self.assertNotEqual(new_cwd, original_cwd)
            self.assertTrue(os.path.isdir(new_cwd))
            self.assertEqual(os.getcwd(), new_cwd)
        self.assertEqual(os.getcwd(), original_cwd)

    def test_sortdict(self):
        self.assertEqual(support.sortdict({3:3, 2:2, 1:1}), "{1: 1, 2: 2, 3: 3}")

    def test_make_bad_fd(self):
        fd = os_helper.make_bad_fd()
        with self.assertRaises(OSError) as cm:
            os.write(fd, b"foo")
        self.assertEqual(cm.exception.errno, errno.EBADF)

    def test_check_syntax_error(self):
        support.check_syntax_error(self, "def class", lineno=1, offset=5)
        with self.assertRaises(AssertionError):
            support.check_syntax_error(self, "x=1")

    def test_CleanImport(self):
        import importlib
        with import_helper.CleanImport("pprint"):
            importlib.import_module("pprint")

    def test_DirsOnSysPath(self):
        with import_helper.DirsOnSysPath('foo', 'bar'):
            self.assertIn("foo", sys.path)
            self.assertIn("bar", sys.path)
        self.assertNotIn("foo", sys.path)
        self.assertNotIn("bar", sys.path)

    def test_captured_stdout(self):
        with support.captured_stdout() as stdout:
            print("hello")
        self.assertEqual(stdout.getvalue(), "hello\n")

    def test_captured_stderr(self):
        with support.captured_stderr() as stderr:
            print("hello", file=sys.stderr)
        self.assertEqual(stderr.getvalue(), "hello\n")

    def test_captured_stdin(self):
        with support.captured_stdin() as stdin:
            stdin.write('hello\n')
            stdin.seek(0)
            # call test code that consumes from sys.stdin
            captured = input()
        self.assertEqual(captured, "hello")

    def test_gc_collect(self):
        support.gc_collect()

    def test_python_is_optimized(self):
        self.assertIsInstance(support.python_is_optimized(), bool)

    def test_swap_attr(self):
        class Obj:
            pass
        obj = Obj()
        obj.x = 1
        with support.swap_attr(obj, "x", 5) as x:
            self.assertEqual(obj.x, 5)
            self.assertEqual(x, 1)
        self.assertEqual(obj.x, 1)
        with support.swap_attr(obj, "y", 5) as y:
            self.assertEqual(obj.y, 5)
            self.assertIsNone(y)
        self.assertNotHasAttr(obj, 'y')
        with support.swap_attr(obj, "y", 5):
            del obj.y
        self.assertNotHasAttr(obj, 'y')

    def test_swap_item(self):
        D = {"x":1}
        with support.swap_item(D, "x", 5) as x:
            self.assertEqual(D["x"], 5)
            self.assertEqual(x, 1)
        self.assertEqual(D["x"], 1)
        with support.swap_item(D, "y", 5) as y:
            self.assertEqual(D["y"], 5)
            self.assertIsNone(y)
        self.assertNotIn("y", D)
        with support.swap_item(D, "y", 5):
            del D["y"]
        self.assertNotIn("y", D)

    class RefClass:
        attribute1 = None
        attribute2 = None
        _hidden_attribute1 = None
        __magic_1__ = None

    class OtherClass:
        attribute2 = None
        attribute3 = None
        __magic_1__ = None
        __magic_2__ = None

    def test_detect_api_mismatch(self):
        missing_items = support.detect_api_mismatch(self.RefClass,
                                                    self.OtherClass)
        self.assertEqual({'attribute1'}, missing_items)

        missing_items = support.detect_api_mismatch(self.OtherClass,
                                                    self.RefClass)
        self.assertEqual({'attribute3', '__magic_2__'}, missing_items)

    def test_detect_api_mismatch__ignore(self):
        ignore = ['attribute1', 'attribute3', '__magic_2__', 'not_in_either']

        missing_items = support.detect_api_mismatch(
                self.RefClass, self.OtherClass, ignore=ignore)
        self.assertEqual(set(), missing_items)

        missing_items = support.detect_api_mismatch(
                self.OtherClass, self.RefClass, ignore=ignore)
        self.assertEqual(set(), missing_items)

    def test_check__all__(self):
        extra = {'tempdir'}
        not_exported = {'template'}
        support.check__all__(self,
                             tempfile,
                             extra=extra,
                             not_exported=not_exported)

        extra = {
            'TextTestResult',
            'installHandler',
        }
        not_exported = {'load_tests', "TestProgram", "BaseTestSuite"}
        support.check__all__(self,
                             unittest,
                             ("unittest.result", "unittest.case",
                              "unittest.suite", "unittest.loader",
                              "unittest.main", "unittest.runner",
                              "unittest.signals", "unittest.async_case"),
                             extra=extra,
                             not_exported=not_exported)

        self.assertRaises(AssertionError, support.check__all__, self, unittest)

    @warnings_helper.ignore_fork_in_thread_deprecation_warnings()
    @unittest.skipUnless(hasattr(os, 'waitpid') and hasattr(os, 'WNOHANG'),
                         'need os.waitpid() and os.WNOHANG')
    @support.requires_fork()
    def test_reap_children(self):
        # Make sure that there is no other pending child process
        support.reap_children()

        # Create a child process
        pid = os.fork()
        if pid == 0:
            # child process: do nothing, just exit
            os._exit(0)

        was_altered = support.environment_altered
        try:
            support.environment_altered = False
            stderr = io.StringIO()

            for _ in support.sleeping_retry(support.SHORT_TIMEOUT):
                with support.swap_attr(support.print_warning, 'orig_stderr', stderr):
                    support.reap_children()

                # Use environment_altered to check if reap_children() found
                # the child process
                if support.environment_altered:
                    break

            msg = "Warning -- reap_children() reaped child process %s" % pid
            self.assertIn(msg, stderr.getvalue())
            self.assertTrue(support.environment_altered)
        finally:
            support.environment_altered = was_altered

        # Just in case, check again that there is no other
        # pending child process
        support.reap_children()

    @support.requires_subprocess()
    def check_options(self, args, func, expected=None):
        code = f'from test.support import {func}; print(repr({func}()))'
        cmd = [sys.executable, *args, '-c', code]
        env = {key: value for key, value in os.environ.items()
               if not key.startswith('PYTHON')}
        proc = subprocess.run(cmd,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.DEVNULL,
                              universal_newlines=True,
                              env=env)
        if expected is None:
            expected = args
        self.assertEqual(proc.stdout.rstrip(), repr(expected))
        self.assertEqual(proc.returncode, 0)

    @support.requires_resource('cpu')
    def test_args_from_interpreter_flags(self):
        # Test test.support.args_from_interpreter_flags()
        for opts in (
            # no option
            [],
            # single option
            ['-B'],
            ['-s'],
            ['-S'],
            ['-E'],
            ['-v'],
            ['-b'],
            ['-P'],
            ['-q'],
            ['-I'],
            # same option multiple times
            ['-bb'],
            ['-vvv'],
            # -W options
            ['-Wignore'],
            # -X options
            ['-X', 'dev'],
            ['-Wignore', '-X', 'dev'],
            ['-X', 'faulthandler'],
            ['-X', 'importtime'],
            ['-X', 'importtime=2'],
            ['-X', 'showrefcount'],
            ['-X', 'tracemalloc'],
            ['-X', 'tracemalloc=3'],
        ):
            with self.subTest(opts=opts):
                self.check_options(opts, 'args_from_interpreter_flags')

        self.check_options(['-I', '-E', '-s', '-P'],
                           'args_from_interpreter_flags',
                           ['-I'])

    def test_optim_args_from_interpreter_flags(self):
        # Test test.support.optim_args_from_interpreter_flags()
        for opts in (
            # no option
            [],
            ['-O'],
            ['-OO'],
            ['-OOOO'],
        ):
            with self.subTest(opts=opts):
                self.check_options(opts, 'optim_args_from_interpreter_flags')

    @unittest.skipIf(support.is_apple_mobile, "Unstable on Apple Mobile")
    @unittest.skipIf(support.is_wasi, "Unavailable on WASI")
    def test_fd_count(self):
        # We cannot test the absolute value of fd_count(): on old Linux kernel
        # or glibc versions, os.urandom() keeps a FD open on /dev/urandom
        # device and Python has 4 FD opens instead of 3. Test is unstable on
        # Emscripten and Apple Mobile platforms; these platforms start and stop
        # background threads that use pipes and epoll fds.
        start = os_helper.fd_count()
        fd = os.open(__file__, os.O_RDONLY)
        try:
            more = os_helper.fd_count()
        finally:
            os.close(fd)
        self.assertEqual(more - start, 1)

    def check_print_warning(self, msg, expected):
        stderr = io.StringIO()
        with support.swap_attr(support.print_warning, 'orig_stderr', stderr):
            support.print_warning(msg)
        self.assertEqual(stderr.getvalue(), expected)

    def test_print_warning(self):
        self.check_print_warning("msg",
                                 "Warning -- msg\n")
        self.check_print_warning("a\nb",
                                 'Warning -- a\nWarning -- b\n')

    def test_has_strftime_extensions(self):
        if sys.platform == "win32":
            self.assertFalse(support.has_strftime_extensions)
        else:
            self.assertTrue(support.has_strftime_extensions)

    def test_get_recursion_depth(self):
        # test support.get_recursion_depth()
        code = textwrap.dedent("""
            from test import support
            import sys

            def check(cond):
                if not cond:
                    raise AssertionError("test failed")

            # depth 1
            check(support.get_recursion_depth() == 1)

            # depth 2
            def test_func():
                check(support.get_recursion_depth() == 2)
            test_func()

            def test_recursive(depth, limit):
                if depth >= limit:
                    # cannot call get_recursion_depth() at this depth,
                    # it can raise RecursionError
                    return
                get_depth = support.get_recursion_depth()
                print(f"test_recursive: {depth}/{limit}: "
                      f"get_recursion_depth() says {get_depth}")
                check(get_depth == depth)
                test_recursive(depth + 1, limit)

            # depth up to 25
            with support.infinite_recursion(max_depth=25):
                limit = sys.getrecursionlimit()
                print(f"test with sys.getrecursionlimit()={limit}")
                test_recursive(2, limit)

            # depth up to 500
            with support.infinite_recursion(max_depth=500):
                limit = sys.getrecursionlimit()
                print(f"test with sys.getrecursionlimit()={limit}")
                test_recursive(2, limit)
        """)
        script_helper.assert_python_ok("-c", code)

    def test_recursion(self):
        # Test infinite_recursion() and get_recursion_available() functions.
        def recursive_function(depth):
            if depth:
                recursive_function(depth - 1)

        for max_depth in (5, 25, 250, 2500):
            with support.infinite_recursion(max_depth):
                available = support.get_recursion_available()

                # Recursion up to 'available' additional frames should be OK.
                recursive_function(available)

                # Recursion up to 'available+1' additional frames must raise
                # RecursionError. Avoid self.assertRaises(RecursionError) which
                # can consume more than 3 frames and so raises RecursionError.
                try:
                    recursive_function(available + 1)
                except RecursionError:
                    pass
                else:
                    self.fail("RecursionError was not raised")

        # Test the bare minimumum: max_depth=3
        with support.infinite_recursion(3):
            try:
                recursive_function(3)
            except RecursionError:
                pass
            else:
                self.fail("RecursionError was not raised")

    def test_parse_memlimit(self):
        parse = support._parse_memlimit
        KiB = 1024
        MiB = KiB * 1024
        GiB = MiB * 1024
        TiB = GiB * 1024
        self.assertEqual(parse('0k'), 0)
        self.assertEqual(parse('3k'), 3 * KiB)
        self.assertEqual(parse('2.4m'), int(2.4 * MiB))
        self.assertEqual(parse('4g'), int(4 * GiB))
        self.assertEqual(parse('1t'), TiB)

        for limit in ('', '3', '3.5.10k', '10x'):
            with self.subTest(limit=limit):
                with self.assertRaises(ValueError):
                    parse(limit)

    def test_set_memlimit(self):
        _4GiB = 4 * 1024 ** 3
        TiB = 1024 ** 4
        old_max_memuse = support.max_memuse
        old_real_max_memuse = support.real_max_memuse
        try:
            if sys.maxsize > 2**32:
                support.set_memlimit('4g')
                self.assertEqual(support.max_memuse, _4GiB)
                self.assertEqual(support.real_max_memuse, _4GiB)

                big = 2**100 // TiB
                support.set_memlimit(f'{big}t')
                self.assertEqual(support.max_memuse, sys.maxsize)
                self.assertEqual(support.real_max_memuse, big * TiB)
            else:
                support.set_memlimit('4g')
                self.assertEqual(support.max_memuse, sys.maxsize)
                self.assertEqual(support.real_max_memuse, _4GiB)
        finally:
            support.max_memuse = old_max_memuse
            support.real_max_memuse = old_real_max_memuse

    def test_copy_python_src_ignore(self):
        # Get source directory
        src_dir = sysconfig.get_config_var('abs_srcdir')
        if not src_dir:
            src_dir = sysconfig.get_config_var('srcdir')
        src_dir = os.path.abspath(src_dir)

        # Check that the source code is available
        if not os.path.exists(src_dir):
            self.skipTest(f"cannot access Python source code directory:"
                          f" {src_dir!r}")
        # Check that the landmark copy_python_src_ignore() expects is available
        # (Previously we looked for 'Lib\os.py', which is always present on Windows.)
        landmark = os.path.join(src_dir, 'Modules')
        if not os.path.exists(landmark):
            self.skipTest(f"cannot access Python source code directory:"
                          f" {landmark!r} landmark is missing")

        # Test support.copy_python_src_ignore()

        # Source code directory
        ignored = {'.git', '__pycache__'}
        names = os.listdir(src_dir)
        self.assertEqual(support.copy_python_src_ignore(src_dir, names),
                         ignored | {'build'})

        # Doc/ directory
        path = os.path.join(src_dir, 'Doc')
        self.assertEqual(support.copy_python_src_ignore(path, os.listdir(path)),
                         ignored | {'build', 'venv'})

        # Another directory
        path = os.path.join(src_dir, 'Objects')
        self.assertEqual(support.copy_python_src_ignore(path, os.listdir(path)),
                         ignored)

    def test_get_signal_name(self):
        for exitcode, expected in (
            (-int(signal.SIGINT), 'SIGINT'),
            (-int(signal.SIGSEGV), 'SIGSEGV'),
            (128 + int(signal.SIGABRT), 'SIGABRT'),
            (3221225477, "STATUS_ACCESS_VIOLATION"),
            (0xC00000FD, "STATUS_STACK_OVERFLOW"),
        ):
            self.assertEqual(support.get_signal_name(exitcode), expected,
                             exitcode)

    def test_linked_to_musl(self):
        linked = support.linked_to_musl()
        self.assertIsNotNone(linked)
        if support.is_wasm32:
            self.assertTrue(linked)
        # The value is cached, so make sure it returns the same value again.
        self.assertIs(linked, support.linked_to_musl())
        # The musl version is either triple or just a major version number.
        if linked:
            self.assertIsInstance(linked, tuple)
            self.assertIn(len(linked), (1, 3))
            for v in linked:
                self.assertIsInstance(v, int)


    # XXX -follows a list of untested API
    # make_legacy_pyc
    # is_resource_enabled
    # requires
    # fcmp
    # umaks
    # findfile
    # check_warnings
    # EnvironmentVarGuard
    # transient_internet
    # run_with_locale
    # bigmemtest
    # precisionbigmemtest
    # bigaddrspacetest
    # requires_resource
    # threading_cleanup
    # reap_threads
    # can_symlink
    # skip_unless_symlink
    # SuppressCrashReport


@hashlib_helper.requires_builtin_hashes()
class TestHashlibSupport(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.hashlib = import_helper.import_module("hashlib")
        cls.hmac = import_helper.import_module("hmac")

        # All C extension modules must be present since blocking
        # the built-in implementation while allowing OpenSSL or vice-versa
        # may result in failures depending on the exposed built-in hashes.
        cls._hashlib = import_helper.import_module("_hashlib")
        cls._hmac = import_helper.import_module("_hmac")
        cls._md5 = import_helper.import_module("_md5")

    def skip_if_fips_mode(self):
        if self._hashlib.get_fips_mode():
            self.skipTest("disabled in FIPS mode")

    def skip_if_not_fips_mode(self):
        if not self._hashlib.get_fips_mode():
            self.skipTest("requires FIPS mode")

    def check_context(self, disabled=True):
        if disabled:
            return self.assertRaises(ValueError)
        return contextlib.nullcontext()

    def try_import_attribute(self, fullname, default=None):
        if fullname is None:
            return default
        assert fullname.count('.') == 1, fullname
        module_name, attribute = fullname.split('.', maxsplit=1)
        try:
            module = importlib.import_module(module_name)
        except ImportError:
            return default
        try:
            return getattr(module, attribute, default)
        except TypeError:
            return default

    def fetch_hash_function(self, name, implementation):
        info = hashlib_helper.get_hash_func_info(name)
        match hashlib_helper.Implementation(implementation):
            case hashlib_helper.Implementation.hashlib:
                method_name = info.hashlib.member_name
                assert isinstance(method_name, str), method_name
                return getattr(self.hashlib, method_name)
            case hashlib_helper.Implementation.openssl:
                method_name = info.openssl.member_name
                assert isinstance(method_name, str | None), method_name
                return getattr(self._hashlib, method_name or "", None)
        fullname = info[implementation].fullname
        return self.try_import_attribute(fullname)

    def fetch_hmac_function(self, name):
        target = hashlib_helper.get_hmac_item_info(name)
        return target.import_member()

    def check_openssl_hash(self, name, *, disabled=True):
        """Check that OpenSSL HASH interface is enabled/disabled."""
        with self.check_context(disabled):
            _ = self._hashlib.new(name)
        if do_hash := self.fetch_hash_function(name, "openssl"):
            self.assertStartsWith(do_hash.__name__, 'openssl_')
            with self.check_context(disabled):
                _ = do_hash(b"")

    def check_openssl_hmac(self, name, *, disabled=True):
        """Check that OpenSSL HMAC interface is enabled/disabled."""
        if name in hashlib_helper.NON_HMAC_DIGEST_NAMES:
            # HMAC-BLAKE and HMAC-SHAKE raise a ValueError as they are not
            # supported at all (they do not make any sense in practice).
            with self.assertRaises(ValueError):
                self._hashlib.hmac_digest(b"", b"", name)
        else:
            with self.check_context(disabled):
                _ = self._hashlib.hmac_digest(b"", b"", name)
        # OpenSSL does not provide one-shot explicit HMAC functions

    def check_builtin_hash(self, name, *, disabled=True):
        """Check that HACL* HASH interface is enabled/disabled."""
        if do_hash := self.fetch_hash_function(name, "builtin"):
            self.assertEqual(do_hash.__name__, name)
            with self.check_context(disabled):
                _ = do_hash(b"")

    def check_builtin_hmac(self, name, *, disabled=True):
        """Check that HACL* HMAC interface is enabled/disabled."""
        if name in hashlib_helper.NON_HMAC_DIGEST_NAMES:
            # HMAC-BLAKE and HMAC-SHAKE raise a ValueError as they are not
            # supported at all (they do not make any sense in practice).
            with self.assertRaises(ValueError):
                self._hmac.compute_digest(b"", b"", name)
        else:
            with self.check_context(disabled):
                _ = self._hmac.compute_digest(b"", b"", name)

        with self.check_context(disabled):
            _ = self._hmac.new(b"", b"", name)

        if do_hmac := self.fetch_hmac_function(name):
            self.assertStartsWith(do_hmac.__name__, 'compute_')
            with self.check_context(disabled):
                _ = do_hmac(b"", b"")
        else:
            self.assertIn(name, hashlib_helper.NON_HMAC_DIGEST_NAMES)

    @support.subTests(
        ('name', 'allow_openssl', 'allow_builtin'),
        itertools.product(
            hashlib_helper.CANONICAL_DIGEST_NAMES,
            [True, False],
            [True, False],
        )
    )
    def test_disable_hash(self, name, allow_openssl, allow_builtin):
        # In FIPS mode, the function may be available but would still need
        # to raise a ValueError, so we will test the helper separately.
        self.skip_if_fips_mode()
        flags = dict(allow_openssl=allow_openssl, allow_builtin=allow_builtin)
        is_fully_disabled = not allow_builtin and not allow_openssl

        with hashlib_helper.block_algorithm(name, **flags):
            # OpenSSL's blake2s and blake2b are unknown names
            # when only the OpenSSL interface is available.
            if allow_openssl and not allow_builtin:
                aliases = {'blake2s': 'blake2s256', 'blake2b': 'blake2b512'}
                name_for_hashlib_new = aliases.get(name, name)
            else:
                name_for_hashlib_new = name

            with self.check_context(is_fully_disabled):
                _ = self.hashlib.new(name_for_hashlib_new)

            # Since _hashlib is present, explicit blake2b/blake2s constructors
            # use the built-in implementation, while others (since we are not
            # in FIPS mode and since _hashlib exists) use the OpenSSL function.
            with self.check_context(is_fully_disabled):
                _ = getattr(self.hashlib, name)()

            self.check_openssl_hash(name, disabled=not allow_openssl)
            self.check_builtin_hash(name, disabled=not allow_builtin)

            if name not in hashlib_helper.NON_HMAC_DIGEST_NAMES:
                with self.check_context(is_fully_disabled):
                    _ = self.hmac.new(b"", b"", name)
                with self.check_context(is_fully_disabled):
                    _ = self.hmac.HMAC(b"", b"", name)
                with self.check_context(is_fully_disabled):
                    _ = self.hmac.digest(b"", b"", name)

                self.check_openssl_hmac(name, disabled=not allow_openssl)
                self.check_builtin_hmac(name, disabled=not allow_builtin)

    @hashlib_helper.block_algorithm("md5")
    def test_disable_hash_md5_in_fips_mode(self):
        self.skip_if_not_fips_mode()

        self.assertRaises(ValueError, self.hashlib.new, "md5")
        self.assertRaises(ValueError, self._hashlib.new, "md5")
        self.assertRaises(ValueError, self.hashlib.md5)
        self.assertRaises(ValueError, self._hashlib.openssl_md5)

        kwargs = dict(usedforsecurity=True)
        self.assertRaises(ValueError, self.hashlib.new, "md5", **kwargs)
        self.assertRaises(ValueError, self._hashlib.new, "md5", **kwargs)
        self.assertRaises(ValueError, self.hashlib.md5, **kwargs)
        self.assertRaises(ValueError, self._hashlib.openssl_md5, **kwargs)

    @hashlib_helper.block_algorithm("md5", allow_openssl=True)
    def test_disable_hash_md5_in_fips_mode_allow_openssl(self):
        self.skip_if_not_fips_mode()
        # Allow the OpenSSL interface to be used but not the HACL* one.
        # hashlib.new("md5") is dispatched to hashlib.openssl_md5()
        self.assertRaises(ValueError, self.hashlib.new, "md5")
        # dispatched to hashlib.openssl_md5() in FIPS mode
        h2 = self.hashlib.new("md5", usedforsecurity=False)
        self.assertIsInstance(h2, self._hashlib.HASH)

        # block_algorithm() does not mock hashlib.md5 and _hashlib.openssl_md5
        self.assertNotHasAttr(self.hashlib.md5, "__wrapped__")
        self.assertNotHasAttr(self._hashlib.openssl_md5, "__wrapped__")

        hashlib_md5 = inspect.unwrap(self.hashlib.md5)
        self.assertIs(hashlib_md5, self._hashlib.openssl_md5)
        self.assertRaises(ValueError, self.hashlib.md5)
        # allow MD5 to be used in FIPS mode if usedforsecurity=False
        h3 = self.hashlib.md5(usedforsecurity=False)
        self.assertIsInstance(h3, self._hashlib.HASH)

    @hashlib_helper.block_algorithm("md5", allow_builtin=True)
    def test_disable_hash_md5_in_fips_mode_allow_builtin(self):
        self.skip_if_not_fips_mode()
        # Allow the HACL* interface to be used but not the OpenSSL one.
        h1 = self.hashlib.new("md5")  # dispatched to _md5.md5()
        self.assertNotIsInstance(h1, self._hashlib.HASH)
        h2 = self.hashlib.new("md5", usedforsecurity=False)
        self.assertIsInstance(h2, type(h1))

        # block_algorithm() mocks hashlib.md5 and _hashlib.openssl_md5
        self.assertHasAttr(self.hashlib.md5, "__wrapped__")
        self.assertHasAttr(self._hashlib.openssl_md5, "__wrapped__")

        hashlib_md5 = inspect.unwrap(self.hashlib.md5)
        openssl_md5 = inspect.unwrap(self._hashlib.openssl_md5)
        self.assertIs(hashlib_md5, openssl_md5)
        self.assertRaises(ValueError, self.hashlib.md5)
        self.assertRaises(ValueError, self.hashlib.md5,
                          usedforsecurity=False)

    @hashlib_helper.block_algorithm("md5",
                                    allow_openssl=True,
                                    allow_builtin=True)
    def test_disable_hash_md5_in_fips_mode_allow_all(self):
        self.skip_if_not_fips_mode()
        # hashlib.new() isn't blocked as it falls back to _md5.md5
        self.assertIsInstance(self.hashlib.new("md5"), self._md5.MD5Type)
        self.assertRaises(ValueError, self._hashlib.new, "md5")
        h = self._hashlib.new("md5", usedforsecurity=False)
        self.assertIsInstance(h, self._hashlib.HASH)

        self.assertNotHasAttr(self.hashlib.md5, "__wrapped__")
        self.assertNotHasAttr(self._hashlib.openssl_md5, "__wrapped__")

        self.assertIs(self.hashlib.md5, self._hashlib.openssl_md5)
        self.assertRaises(ValueError, self.hashlib.md5)
        h = self.hashlib.md5(usedforsecurity=False)
        self.assertIsInstance(h, self._hashlib.HASH)


if __name__ == '__main__':
    unittest.main()
