# Test the runpy module
import contextlib
import importlib.machinery, importlib.util
import os.path
import pathlib
import py_compile
import re
import signal
import subprocess
import sys
import tempfile
import textwrap
import unittest
import warnings
from test.support import (
    force_not_colorized_test_class,
    infinite_recursion,
    no_tracing,
    requires_resource,
    requires_subprocess,
    verbose,
)
from test import support
from test.support.import_helper import forget, make_legacy_pyc, unload
from test.support.os_helper import create_empty_file, temp_dir, FakePath
from test.support.script_helper import make_script, make_zip_script
from test.test_importlib.util import temporary_pycache_prefix


import runpy
from runpy import _run_code, _run_module_code, run_module, run_path
# Note: This module can't safely test _run_module_as_main as it
# runs its tests in the current process, which would mess with the
# real __main__ module (usually test.regrtest)
# See test_cmd_line_script for a test that executes that code path


# Set up the test code and expected results
example_source = """\
# Check basic code execution
result = ['Top level assignment']
def f():
    result.append('Lower level reference')
f()
del f
# Check the sys module
import sys
run_argv0 = sys.argv[0]
run_name_in_sys_modules = __name__ in sys.modules
module_in_sys_modules = (run_name_in_sys_modules and
                         globals() is sys.modules[__name__].__dict__)
# Check nested operation
import runpy
nested = runpy._run_module_code('x=1\\n', mod_name='<run>')
"""

implicit_namespace = {
    "__name__": None,
    "__file__": None,
    "__package__": None,
    "__doc__": None,
    "__spec__": None
}
example_namespace =  {
    "sys": sys,
    "runpy": runpy,
    "result": ["Top level assignment", "Lower level reference"],
    "run_argv0": sys.argv[0],
    "run_name_in_sys_modules": False,
    "module_in_sys_modules": False,
    "nested": dict(implicit_namespace,
                   x=1, __name__="<run>", __loader__=None),
}
example_namespace.update(implicit_namespace)

class CodeExecutionMixin:
    # Issue #15230 (run_path not handling run_name correctly) highlighted a
    # problem with the way arguments were being passed from higher level APIs
    # down to lower level code. This mixin makes it easier to ensure full
    # testing occurs at those upper layers as well, not just at the utility
    # layer

    # Figuring out the loader details in advance is hard to do, so we skip
    # checking the full details of loader and loader_state
    CHECKED_SPEC_ATTRIBUTES = ["name", "parent", "origin", "cached",
                               "has_location", "submodule_search_locations"]

    def assertNamespaceMatches(self, result_ns, expected_ns):
        """Check two namespaces match.

           Ignores any unspecified interpreter created names
        """
        # Avoid side effects
        result_ns = result_ns.copy()
        expected_ns = expected_ns.copy()
        # Impls are permitted to add extra names, so filter them out
        for k in list(result_ns):
            if k.startswith("__") and k.endswith("__"):
                if k not in expected_ns:
                    result_ns.pop(k)
                if k not in expected_ns["nested"]:
                    result_ns["nested"].pop(k)
        # Spec equality includes the loader, so we take the spec out of the
        # result namespace and check that separately
        result_spec = result_ns.pop("__spec__")
        expected_spec = expected_ns.pop("__spec__")
        if expected_spec is None:
            self.assertIsNone(result_spec)
        else:
            # If an expected loader is set, we just check we got the right
            # type, rather than checking for full equality
            if expected_spec.loader is not None:
                self.assertEqual(type(result_spec.loader),
                                 type(expected_spec.loader))
            for attr in self.CHECKED_SPEC_ATTRIBUTES:
                k = "__spec__." + attr
                actual = (k, getattr(result_spec, attr))
                expected = (k, getattr(expected_spec, attr))
                self.assertEqual(actual, expected)
        # For the rest, we still don't use direct dict comparison on the
        # namespace, as the diffs are too hard to debug if anything breaks
        self.assertEqual(set(result_ns), set(expected_ns))
        for k in result_ns:
            actual = (k, result_ns[k])
            expected = (k, expected_ns[k])
            self.assertEqual(actual, expected)

    def check_code_execution(self, create_namespace, expected_namespace):
        """Check that an interface runs the example code correctly

           First argument is a callable accepting the initial globals and
           using them to create the actual namespace
           Second argument is the expected result
        """
        sentinel = object()
        expected_ns = expected_namespace.copy()
        run_name = expected_ns["__name__"]
        saved_argv0 = sys.argv[0]
        saved_mod = sys.modules.get(run_name, sentinel)
        # Check without initial globals
        result_ns = create_namespace(None)
        self.assertNamespaceMatches(result_ns, expected_ns)
        self.assertIs(sys.argv[0], saved_argv0)
        self.assertIs(sys.modules.get(run_name, sentinel), saved_mod)
        # And then with initial globals
        initial_ns = {"sentinel": sentinel}
        expected_ns["sentinel"] = sentinel
        result_ns = create_namespace(initial_ns)
        self.assertIsNot(result_ns, initial_ns)
        self.assertNamespaceMatches(result_ns, expected_ns)
        self.assertIs(sys.argv[0], saved_argv0)
        self.assertIs(sys.modules.get(run_name, sentinel), saved_mod)


class ExecutionLayerTestCase(unittest.TestCase, CodeExecutionMixin):
    """Unit tests for runpy._run_code and runpy._run_module_code"""

    def test_run_code(self):
        expected_ns = example_namespace.copy()
        expected_ns.update({
            "__loader__": None,
        })
        def create_ns(init_globals):
            return _run_code(example_source, {}, init_globals)
        self.check_code_execution(create_ns, expected_ns)

    def test_run_module_code(self):
        mod_name = "<Nonsense>"
        mod_fname = "Some other nonsense"
        mod_loader = "Now you're just being silly"
        mod_package = '' # Treat as a top level module
        mod_spec = importlib.machinery.ModuleSpec(mod_name,
                                                  origin=mod_fname,
                                                  loader=mod_loader)
        expected_ns = example_namespace.copy()
        expected_ns.update({
            "__name__": mod_name,
            "__file__": mod_fname,
            "__loader__": mod_loader,
            "__package__": mod_package,
            "__spec__": mod_spec,
            "run_argv0": mod_fname,
            "run_name_in_sys_modules": True,
            "module_in_sys_modules": True,
        })
        def create_ns(init_globals):
            return _run_module_code(example_source,
                                    init_globals,
                                    mod_name,
                                    mod_spec)
        self.check_code_execution(create_ns, expected_ns)

# TODO: Use self.addCleanup to get rid of a lot of try-finally blocks
class RunModuleTestCase(unittest.TestCase, CodeExecutionMixin):
    """Unit tests for runpy.run_module"""

    def expect_import_error(self, mod_name):
        try:
            run_module(mod_name)
        except ImportError:
            pass
        else:
            self.fail("Expected import error for " + mod_name)

    def test_invalid_names(self):
        # Builtin module
        self.expect_import_error("sys")
        # Non-existent modules
        self.expect_import_error("sys.imp.eric")
        self.expect_import_error("os.path.half")
        self.expect_import_error("a.bee")
        # Relative names not allowed
        self.expect_import_error(".howard")
        self.expect_import_error("..eaten")
        self.expect_import_error(".test_runpy")
        self.expect_import_error(".unittest")
        # Package without __main__.py
        self.expect_import_error("multiprocessing")

    def test_library_module(self):
        self.assertEqual(run_module("runpy")["__name__"], "runpy")

    def _add_pkg_dir(self, pkg_dir, namespace=False):
        os.mkdir(pkg_dir)
        if namespace:
            return None
        pkg_fname = os.path.join(pkg_dir, "__init__.py")
        create_empty_file(pkg_fname)
        return pkg_fname

    def _make_pkg(self, source, depth, mod_base="runpy_test",
                     *, namespace=False, parent_namespaces=False):
        # Enforce a couple of internal sanity checks on test cases
        if (namespace or parent_namespaces) and not depth:
            raise RuntimeError("Can't mark top level module as a "
                               "namespace package")
        pkg_name = "__runpy_pkg__"
        test_fname = mod_base+os.extsep+"py"
        pkg_dir = sub_dir = os.path.realpath(tempfile.mkdtemp())
        if verbose > 1: print("  Package tree in:", sub_dir)
        sys.path.insert(0, pkg_dir)
        if verbose > 1: print("  Updated sys.path:", sys.path[0])
        if depth:
            namespace_flags = [parent_namespaces] * depth
            namespace_flags[-1] = namespace
            for namespace_flag in namespace_flags:
                sub_dir = os.path.join(sub_dir, pkg_name)
                pkg_fname = self._add_pkg_dir(sub_dir, namespace_flag)
                if verbose > 1: print("  Next level in:", sub_dir)
                if verbose > 1: print("  Created:", pkg_fname)
        mod_fname = os.path.join(sub_dir, test_fname)
        with open(mod_fname, "w") as mod_file:
            mod_file.write(source)
        if verbose > 1: print("  Created:", mod_fname)
        mod_name = (pkg_name+".")*depth + mod_base
        mod_spec = importlib.util.spec_from_file_location(mod_name,
                                                          mod_fname)
        return pkg_dir, mod_fname, mod_name, mod_spec

    def _del_pkg(self, top):
        for entry in list(sys.modules):
            if entry.startswith("__runpy_pkg__"):
                del sys.modules[entry]
        if verbose > 1: print("  Removed sys.modules entries")
        del sys.path[0]
        if verbose > 1: print("  Removed sys.path entry")
        for root, dirs, files in os.walk(top, topdown=False):
            for name in files:
                try:
                    os.remove(os.path.join(root, name))
                except OSError as ex:
                    if verbose > 1: print(ex) # Persist with cleaning up
            for name in dirs:
                fullname = os.path.join(root, name)
                try:
                    os.rmdir(fullname)
                except OSError as ex:
                    if verbose > 1: print(ex) # Persist with cleaning up
        try:
            os.rmdir(top)
            if verbose > 1: print("  Removed package tree")
        except OSError as ex:
            if verbose > 1: print(ex) # Persist with cleaning up

    def _fix_ns_for_legacy_pyc(self, ns, alter_sys):
        char_to_add = "c"
        ns["__file__"] += char_to_add
        spec = ns["__spec__"]
        new_spec = importlib.util.spec_from_file_location(spec.name,
                                                          ns["__file__"])
        ns["__spec__"] = new_spec
        if alter_sys:
            ns["run_argv0"] += char_to_add


    def _check_module(self, depth, alter_sys=False,
                         *, namespace=False, parent_namespaces=False):
        pkg_dir, mod_fname, mod_name, mod_spec = (
               self._make_pkg(example_source, depth,
                              namespace=namespace,
                              parent_namespaces=parent_namespaces))
        forget(mod_name)
        expected_ns = example_namespace.copy()
        expected_ns.update({
            "__name__": mod_name,
            "__file__": mod_fname,
            "__package__": mod_name.rpartition(".")[0],
            "__spec__": mod_spec,
        })
        if alter_sys:
            expected_ns.update({
                "run_argv0": mod_fname,
                "run_name_in_sys_modules": True,
                "module_in_sys_modules": True,
            })
        def create_ns(init_globals):
            return run_module(mod_name, init_globals, alter_sys=alter_sys)
        try:
            if verbose > 1: print("Running from source:", mod_name)
            self.check_code_execution(create_ns, expected_ns)
            importlib.invalidate_caches()
            __import__(mod_name)
            if not sys.dont_write_bytecode:
                make_legacy_pyc(mod_fname, allow_compile=True)
                unload(mod_name)  # In case loader caches paths
                os.remove(mod_fname)
                importlib.invalidate_caches()
                if verbose > 1: print("Running from compiled:", mod_name)
                self._fix_ns_for_legacy_pyc(expected_ns, alter_sys)
                self.check_code_execution(create_ns, expected_ns)
            else:
                os.remove(mod_fname)
        finally:
            self._del_pkg(pkg_dir)
        if verbose > 1: print("Module executed successfully")

    def _check_package(self, depth, alter_sys=False,
                          *, namespace=False, parent_namespaces=False):
        pkg_dir, mod_fname, mod_name, mod_spec = (
               self._make_pkg(example_source, depth, "__main__",
                              namespace=namespace,
                              parent_namespaces=parent_namespaces))
        pkg_name = mod_name.rpartition(".")[0]
        forget(mod_name)
        expected_ns = example_namespace.copy()
        expected_ns.update({
            "__name__": mod_name,
            "__file__": mod_fname,
            "__package__": pkg_name,
            "__spec__": mod_spec,
        })
        if alter_sys:
            expected_ns.update({
                "run_argv0": mod_fname,
                "run_name_in_sys_modules": True,
                "module_in_sys_modules": True,
            })
        def create_ns(init_globals):
            return run_module(pkg_name, init_globals, alter_sys=alter_sys)
        try:
            if verbose > 1: print("Running from source:", pkg_name)
            self.check_code_execution(create_ns, expected_ns)
            importlib.invalidate_caches()
            __import__(mod_name)
            if not sys.dont_write_bytecode:
                make_legacy_pyc(mod_fname, allow_compile=True)
                unload(mod_name)  # In case loader caches paths
                os.remove(mod_fname)
                if verbose > 1: print("Running from compiled:", pkg_name)
                importlib.invalidate_caches()
                self._fix_ns_for_legacy_pyc(expected_ns, alter_sys)
                self.check_code_execution(create_ns, expected_ns)
            else:
                os.remove(mod_fname)
        finally:
            self._del_pkg(pkg_dir)
        if verbose > 1: print("Package executed successfully")

    def _add_relative_modules(self, base_dir, source, depth):
        if depth <= 1:
            raise ValueError("Relative module test needs depth > 1")
        pkg_name = "__runpy_pkg__"
        module_dir = base_dir
        for i in range(depth):
            parent_dir = module_dir
            module_dir = os.path.join(module_dir, pkg_name)
        # Add sibling module
        sibling_fname = os.path.join(module_dir, "sibling.py")
        create_empty_file(sibling_fname)
        if verbose > 1: print("  Added sibling module:", sibling_fname)
        # Add nephew module
        uncle_dir = os.path.join(parent_dir, "uncle")
        self._add_pkg_dir(uncle_dir)
        if verbose > 1: print("  Added uncle package:", uncle_dir)
        cousin_dir = os.path.join(uncle_dir, "cousin")
        self._add_pkg_dir(cousin_dir)
        if verbose > 1: print("  Added cousin package:", cousin_dir)
        nephew_fname = os.path.join(cousin_dir, "nephew.py")
        create_empty_file(nephew_fname)
        if verbose > 1: print("  Added nephew module:", nephew_fname)

    def _check_relative_imports(self, depth, run_name=None):
        contents = r"""\
from __future__ import absolute_import
from . import sibling
from ..uncle.cousin import nephew
"""
        pkg_dir, mod_fname, mod_name, mod_spec = (
               self._make_pkg(contents, depth))
        if run_name is None:
            expected_name = mod_name
        else:
            expected_name = run_name
        try:
            self._add_relative_modules(pkg_dir, contents, depth)
            pkg_name = mod_name.rpartition('.')[0]
            if verbose > 1: print("Running from source:", mod_name)
            d1 = run_module(mod_name, run_name=run_name) # Read from source
            self.assertEqual(d1["__name__"], expected_name)
            self.assertEqual(d1["__package__"], pkg_name)
            self.assertIn("sibling", d1)
            self.assertIn("nephew", d1)
            del d1 # Ensure __loader__ entry doesn't keep file open
            importlib.invalidate_caches()
            __import__(mod_name)
            os.remove(mod_fname)
            if not sys.dont_write_bytecode and sys.implementation.cache_tag:
                make_legacy_pyc(mod_fname)
                unload(mod_name)  # In case the loader caches paths
                if verbose > 1: print("Running from compiled:", mod_name)
                importlib.invalidate_caches()
                d2 = run_module(mod_name, run_name=run_name) # Read from bytecode
                self.assertEqual(d2["__name__"], expected_name)
                self.assertEqual(d2["__package__"], pkg_name)
                self.assertIn("sibling", d2)
                self.assertIn("nephew", d2)
                del d2 # Ensure __loader__ entry doesn't keep file open
        finally:
            self._del_pkg(pkg_dir)
        if verbose > 1: print("Module executed successfully")

    def test_run_module(self):
        for depth in range(4):
            if verbose > 1: print("Testing package depth:", depth)
            self._check_module(depth)

    def test_run_module_in_namespace_package(self):
        for depth in range(1, 4):
            if verbose > 1: print("Testing package depth:", depth)
            self._check_module(depth, namespace=True, parent_namespaces=True)

    def test_run_package(self):
        for depth in range(1, 4):
            if verbose > 1: print("Testing package depth:", depth)
            self._check_package(depth)

    def test_run_package_init_exceptions(self):
        # These were previously wrapped in an ImportError; see Issue 14285
        result = self._make_pkg("", 1, "__main__")
        pkg_dir, _, mod_name, _ = result
        mod_name = mod_name.replace(".__main__", "")
        self.addCleanup(self._del_pkg, pkg_dir)
        init = os.path.join(pkg_dir, "__runpy_pkg__", "__init__.py")

        exceptions = (ImportError, AttributeError, TypeError, ValueError)
        for exception in exceptions:
            name = exception.__name__
            with self.subTest(name):
                source = "raise {0}('{0} in __init__.py.')".format(name)
                with open(init, "wt", encoding="ascii") as mod_file:
                    mod_file.write(source)
                try:
                    run_module(mod_name)
                except exception as err:
                    self.assertNotIn("finding spec", format(err))
                else:
                    self.fail("Nothing raised; expected {}".format(name))
                try:
                    run_module(mod_name + ".submodule")
                except exception as err:
                    self.assertNotIn("finding spec", format(err))
                else:
                    self.fail("Nothing raised; expected {}".format(name))

    def test_submodule_imported_warning(self):
        pkg_dir, _, mod_name, _ = self._make_pkg("", 1)
        try:
            __import__(mod_name)
            with self.assertWarnsRegex(RuntimeWarning,
                    r"found in sys\.modules"):
                run_module(mod_name)
        finally:
            self._del_pkg(pkg_dir)

    def test_package_imported_no_warning(self):
        pkg_dir, _, mod_name, _ = self._make_pkg("", 1, "__main__")
        self.addCleanup(self._del_pkg, pkg_dir)
        package = mod_name.replace(".__main__", "")
        # No warning should occur if we only imported the parent package
        __import__(package)
        self.assertIn(package, sys.modules)
        with warnings.catch_warnings():
            warnings.simplefilter("error", RuntimeWarning)
            run_module(package)
        # But the warning should occur if we imported the __main__ submodule
        __import__(mod_name)
        with self.assertWarnsRegex(RuntimeWarning, r"found in sys\.modules"):
            run_module(package)

    def test_run_package_in_namespace_package(self):
        for depth in range(1, 4):
            if verbose > 1: print("Testing package depth:", depth)
            self._check_package(depth, parent_namespaces=True)

    def test_run_namespace_package(self):
        for depth in range(1, 4):
            if verbose > 1: print("Testing package depth:", depth)
            self._check_package(depth, namespace=True)

    def test_run_namespace_package_in_namespace_package(self):
        for depth in range(1, 4):
            if verbose > 1: print("Testing package depth:", depth)
            self._check_package(depth, namespace=True, parent_namespaces=True)

    def test_run_module_alter_sys(self):
        for depth in range(4):
            if verbose > 1: print("Testing package depth:", depth)
            self._check_module(depth, alter_sys=True)

    def test_run_package_alter_sys(self):
        for depth in range(1, 4):
            if verbose > 1: print("Testing package depth:", depth)
            self._check_package(depth, alter_sys=True)

    def test_explicit_relative_import(self):
        for depth in range(2, 5):
            if verbose > 1: print("Testing relative imports at depth:", depth)
            self._check_relative_imports(depth)

    def test_main_relative_import(self):
        for depth in range(2, 5):
            if verbose > 1: print("Testing main relative imports at depth:", depth)
            self._check_relative_imports(depth, "__main__")

    def test_run_name(self):
        depth = 1
        run_name = "And now for something completely different"
        pkg_dir, mod_fname, mod_name, mod_spec = (
               self._make_pkg(example_source, depth))
        forget(mod_name)
        expected_ns = example_namespace.copy()
        expected_ns.update({
            "__name__": run_name,
            "__file__": mod_fname,
            "__package__": mod_name.rpartition(".")[0],
            "__spec__": mod_spec,
        })
        def create_ns(init_globals):
            return run_module(mod_name, init_globals, run_name)
        try:
            self.check_code_execution(create_ns, expected_ns)
        finally:
            self._del_pkg(pkg_dir)

    def test_pkgutil_walk_packages(self):
        # This is a dodgy hack to use the test_runpy infrastructure to test
        # issue #15343. Issue #15348 declares this is indeed a dodgy hack ;)
        import pkgutil
        max_depth = 4
        base_name = "__runpy_pkg__"
        package_suffixes = ["uncle", "uncle.cousin"]
        module_suffixes = ["uncle.cousin.nephew", base_name + ".sibling"]
        expected_packages = set()
        expected_modules = set()
        for depth in range(1, max_depth):
            pkg_name = ".".join([base_name] * depth)
            expected_packages.add(pkg_name)
            for name in package_suffixes:
                expected_packages.add(pkg_name + "." + name)
            for name in module_suffixes:
                expected_modules.add(pkg_name + "." + name)
        pkg_name = ".".join([base_name] * max_depth)
        expected_packages.add(pkg_name)
        expected_modules.add(pkg_name + ".runpy_test")
        pkg_dir, mod_fname, mod_name, mod_spec = (
               self._make_pkg("", max_depth))
        self.addCleanup(self._del_pkg, pkg_dir)
        for depth in range(2, max_depth+1):
            self._add_relative_modules(pkg_dir, "", depth)
        for moduleinfo in pkgutil.walk_packages([pkg_dir]):
            self.assertIsInstance(moduleinfo, pkgutil.ModuleInfo)
            self.assertIsInstance(moduleinfo.module_finder,
                                  importlib.machinery.FileFinder)
            if moduleinfo.ispkg:
                expected_packages.remove(moduleinfo.name)
            else:
                expected_modules.remove(moduleinfo.name)
        self.assertEqual(len(expected_packages), 0, expected_packages)
        self.assertEqual(len(expected_modules), 0, expected_modules)

class RunPathTestCase(unittest.TestCase, CodeExecutionMixin):
    """Unit tests for runpy.run_path"""

    def _make_test_script(self, script_dir, script_basename,
                          source=None, omit_suffix=False):
        if source is None:
            source = example_source
        return make_script(script_dir, script_basename,
                           source, omit_suffix)

    def _check_script(self, script_name, expected_name, expected_file,
                            expected_argv0, mod_name=None,
                            expect_spec=True, check_loader=True):
        # First check is without run_name
        def create_ns(init_globals):
            return run_path(script_name, init_globals)
        expected_ns = example_namespace.copy()
        if mod_name is None:
            spec_name = expected_name
        else:
            spec_name = mod_name
        if expect_spec:
            mod_spec = importlib.util.spec_from_file_location(spec_name,
                                                              expected_file)
            mod_cached = mod_spec.cached
            if not check_loader:
                mod_spec.loader = None
        else:
            mod_spec = mod_cached = None

        expected_ns.update({
            "__name__": expected_name,
            "__file__": expected_file,
            "__package__": "",
            "__spec__": mod_spec,
            "run_argv0": expected_argv0,
            "run_name_in_sys_modules": True,
            "module_in_sys_modules": True,
        })
        self.check_code_execution(create_ns, expected_ns)
        # Second check makes sure run_name works in all cases
        run_name = "prove.issue15230.is.fixed"
        def create_ns(init_globals):
            return run_path(script_name, init_globals, run_name)
        if expect_spec and mod_name is None:
            mod_spec = importlib.util.spec_from_file_location(run_name,
                                                              expected_file)
            if not check_loader:
                mod_spec.loader = None
            expected_ns["__spec__"] = mod_spec
        expected_ns["__name__"] = run_name
        expected_ns["__package__"] = run_name.rpartition(".")[0]
        self.check_code_execution(create_ns, expected_ns)

    def _check_import_error(self, script_name, msg):
        msg = re.escape(msg)
        self.assertRaisesRegex(ImportError, msg, run_path, script_name)

    def test_basic_script(self):
        with temp_dir() as script_dir:
            mod_name = 'script'
            script_name = self._make_test_script(script_dir, mod_name)
            self._check_script(script_name, "<run_path>", script_name,
                               script_name, expect_spec=False)

    def test_basic_script_with_pathlike_object(self):
        with temp_dir() as script_dir:
            mod_name = 'script'
            script_name = self._make_test_script(script_dir, mod_name)
            self._check_script(FakePath(script_name), "<run_path>",
                               script_name,
                               script_name,
                               expect_spec=False)

    def test_basic_script_no_suffix(self):
        with temp_dir() as script_dir:
            mod_name = 'script'
            script_name = self._make_test_script(script_dir, mod_name,
                                                 omit_suffix=True)
            self._check_script(script_name, "<run_path>", script_name,
                               script_name, expect_spec=False)

    @unittest.skipIf(sys.implementation.cache_tag is None,
                     'requires sys.implementation.cache_tag')
    def test_script_compiled(self):
        with temp_dir() as script_dir:
            mod_name = 'script'
            script_name = self._make_test_script(script_dir, mod_name)
            compiled_name = py_compile.compile(script_name, doraise=True)
            os.remove(script_name)
            self._check_script(compiled_name, "<run_path>", compiled_name,
                               compiled_name, expect_spec=False)

    def test_directory(self):
        with temp_dir() as script_dir:
            mod_name = '__main__'
            script_name = self._make_test_script(script_dir, mod_name)
            self._check_script(script_dir, "<run_path>", script_name,
                               script_dir, mod_name=mod_name)

    def test_directory_compiled(self):
        with temp_dir() as script_dir:
            mod_name = '__main__'
            script_name = self._make_test_script(script_dir, mod_name)
            legacy_pyc = make_legacy_pyc(script_name, allow_compile=True)
            os.remove(script_name)
            self._check_script(script_dir, "<run_path>", legacy_pyc,
                               script_dir, mod_name=mod_name)

    def test_directory_error(self):
        with temp_dir() as script_dir:
            mod_name = 'not_main'
            script_name = self._make_test_script(script_dir, mod_name)
            msg = "can't find '__main__' module in %r" % script_dir
            self._check_import_error(script_dir, msg)

    def test_zipfile(self):
        with temp_dir() as script_dir:
            mod_name = '__main__'
            script_name = self._make_test_script(script_dir, mod_name)
            zip_name, fname = make_zip_script(script_dir, 'test_zip', script_name)
            self._check_script(zip_name, "<run_path>", fname, zip_name,
                               mod_name=mod_name, check_loader=False)

    def test_zipfile_compiled(self):
        with temp_dir() as script_dir:
            mod_name = '__main__'
            script_name = self._make_test_script(script_dir, mod_name)
            compiled_name = script_name + 'c'
            py_compile.compile(script_name, compiled_name, doraise=True)
            zip_name, fname = make_zip_script(script_dir, 'test_zip',
                                              compiled_name)
            self._check_script(zip_name, "<run_path>", fname, zip_name,
                               mod_name=mod_name, check_loader=False)

    def test_zipfile_error(self):
        with temp_dir() as script_dir:
            mod_name = 'not_main'
            script_name = self._make_test_script(script_dir, mod_name)
            zip_name, fname = make_zip_script(script_dir, 'test_zip', script_name)
            msg = "can't find '__main__' module in %r" % zip_name
            self._check_import_error(zip_name, msg)

    @no_tracing
    @requires_resource('cpu')
    def test_main_recursion_error(self):
        with temp_dir() as script_dir, temp_dir() as dummy_dir:
            mod_name = '__main__'
            source = ("import runpy\n"
                      "runpy.run_path(%r)\n") % dummy_dir
            script_name = self._make_test_script(script_dir, mod_name, source)
            zip_name, fname = make_zip_script(script_dir, 'test_zip', script_name)
            with infinite_recursion(25):
                self.assertRaises(RecursionError, run_path, zip_name)

    def test_encoding(self):
        with temp_dir() as script_dir:
            filename = os.path.join(script_dir, 'script.py')
            with open(filename, 'w', encoding='latin1') as f:
                f.write("""
#coding:latin1
s = "non-ASCII: h\xe9"
""")
            result = run_path(filename)
            self.assertEqual(result['s'], "non-ASCII: h\xe9")

    def test_run_module_filter_syntax_warnings_by_module(self):
        module_re = r'test\.test_import\.data\.syntax_warnings\z'
        with (temp_dir() as tmpdir,
              temporary_pycache_prefix(tmpdir),
              warnings.catch_warnings(record=True) as wlog):
            warnings.simplefilter('error')
            warnings.filterwarnings('always', module=module_re)
            warnings.filterwarnings('error', module='syntax_warnings')
            ns = run_module('test.test_import.data.syntax_warnings')
        self.assertEqual(sorted(wm.lineno for wm in wlog), [4, 7, 10, 13, 14, 21])
        filename = ns['__file__']
        for wm in wlog:
            self.assertEqual(wm.filename, filename)
            self.assertIs(wm.category, SyntaxWarning)

    def test_run_path_filter_syntax_warnings_by_module(self):
        filename = support.findfile('test_import/data/syntax_warnings.py')
        with warnings.catch_warnings(record=True) as wlog:
            warnings.simplefilter('error')
            warnings.filterwarnings('always', module=r'<run_path>\z')
            warnings.filterwarnings('error', module='test')
            warnings.filterwarnings('error', module='syntax_warnings')
            warnings.filterwarnings('error',
                    module=r'test\.test_import\.data\.syntax_warnings')
            run_path(filename)
        self.assertEqual(sorted(wm.lineno for wm in wlog), [4, 7, 10, 13, 14, 21])
        for wm in wlog:
            self.assertEqual(wm.filename, filename)
            self.assertIs(wm.category, SyntaxWarning)

        with warnings.catch_warnings(record=True) as wlog:
            warnings.simplefilter('error')
            warnings.filterwarnings('always', module=r'package\.script\z')
            warnings.filterwarnings('error', module='<run_path>')
            warnings.filterwarnings('error', module='test')
            warnings.filterwarnings('error', module='syntax_warnings')
            warnings.filterwarnings('error',
                    module=r'test\.test_import\.data\.syntax_warnings')
            run_path(filename, run_name='package.script')
        self.assertEqual(sorted(wm.lineno for wm in wlog), [4, 7, 10, 13, 14, 21])


@force_not_colorized_test_class
class TestExit(unittest.TestCase):
    STATUS_CONTROL_C_EXIT = 0xC000013A
    EXPECTED_CODE = (
        STATUS_CONTROL_C_EXIT
        if sys.platform == "win32"
        else -signal.SIGINT
    )
    @staticmethod
    @contextlib.contextmanager
    def tmp_path(*args, **kwargs):
        with temp_dir() as tmp_fn:
            yield pathlib.Path(tmp_fn)


    def run(self, *args, **kwargs):
        with self.tmp_path() as tmp:
            self.ham = ham = tmp / "ham.py"
            ham.write_text(
                textwrap.dedent(
                    """\
                    raise KeyboardInterrupt
                    """
                )
            )
            super().run(*args, **kwargs)

    @requires_subprocess()
    def assertSigInt(self, cmd, *args, **kwargs):
        # Use -E to ignore PYTHONSAFEPATH
        cmd = [sys.executable, '-E', *cmd]
        proc = subprocess.run(cmd, *args, **kwargs, text=True, stderr=subprocess.PIPE)
        self.assertEndsWith(proc.stderr, "\nKeyboardInterrupt\n")
        self.assertEqual(proc.returncode, self.EXPECTED_CODE)

    def test_pymain_run_file(self):
        self.assertSigInt([self.ham])

    def test_pymain_run_file_runpy_run_module(self):
        tmp = self.ham.parent
        run_module = tmp / "run_module.py"
        run_module.write_text(
            textwrap.dedent(
                """\
                import runpy
                runpy.run_module("ham")
                """
            )
        )
        self.assertSigInt([run_module], cwd=tmp)

    def test_pymain_run_file_runpy_run_module_as_main(self):
        tmp = self.ham.parent
        run_module_as_main = tmp / "run_module_as_main.py"
        run_module_as_main.write_text(
            textwrap.dedent(
                """\
                import runpy
                runpy._run_module_as_main("ham")
                """
            )
        )
        self.assertSigInt([run_module_as_main], cwd=tmp)

    def test_pymain_run_command_run_module(self):
        self.assertSigInt(
            ["-c", "import runpy; runpy.run_module('ham')"],
            cwd=self.ham.parent,
        )

    def test_pymain_run_command(self):
        self.assertSigInt(["-c", "import ham"], cwd=self.ham.parent)

    def test_pymain_run_stdin(self):
        self.assertSigInt([], input="import ham", cwd=self.ham.parent)

    def test_pymain_run_module(self):
        ham = self.ham
        self.assertSigInt(["-m", ham.stem], cwd=ham.parent)


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