Home | History | Annotate | Download | only in test
      1 # tests command line execution of scripts
      2 
      3 import contextlib
      4 import importlib
      5 import importlib.machinery
      6 import zipimport
      7 import unittest
      8 import sys
      9 import os
     10 import os.path
     11 import py_compile
     12 import subprocess
     13 import io
     14 
     15 import textwrap
     16 from test import support
     17 from test.support.script_helper import (
     18     make_pkg, make_script, make_zip_pkg, make_zip_script,
     19     assert_python_ok, assert_python_failure, spawn_python, kill_python)
     20 
     21 verbose = support.verbose
     22 
     23 example_args = ['test1', 'test2', 'test3']
     24 
     25 test_source = """\
     26 # Script may be run with optimisation enabled, so don't rely on assert
     27 # statements being executed
     28 def assertEqual(lhs, rhs):
     29     if lhs != rhs:
     30         raise AssertionError('%r != %r' % (lhs, rhs))
     31 def assertIdentical(lhs, rhs):
     32     if lhs is not rhs:
     33         raise AssertionError('%r is not %r' % (lhs, rhs))
     34 # Check basic code execution
     35 result = ['Top level assignment']
     36 def f():
     37     result.append('Lower level reference')
     38 f()
     39 assertEqual(result, ['Top level assignment', 'Lower level reference'])
     40 # Check population of magic variables
     41 assertEqual(__name__, '__main__')
     42 from importlib.machinery import BuiltinImporter
     43 _loader = __loader__ if __loader__ is BuiltinImporter else type(__loader__)
     44 print('__loader__==%a' % _loader)
     45 print('__file__==%a' % __file__)
     46 print('__cached__==%a' % __cached__)
     47 print('__package__==%r' % __package__)
     48 # Check PEP 451 details
     49 import os.path
     50 if __package__ is not None:
     51     print('__main__ was located through the import system')
     52     assertIdentical(__spec__.loader, __loader__)
     53     expected_spec_name = os.path.splitext(os.path.basename(__file__))[0]
     54     if __package__:
     55         expected_spec_name = __package__ + "." + expected_spec_name
     56     assertEqual(__spec__.name, expected_spec_name)
     57     assertEqual(__spec__.parent, __package__)
     58     assertIdentical(__spec__.submodule_search_locations, None)
     59     assertEqual(__spec__.origin, __file__)
     60     if __spec__.cached is not None:
     61         assertEqual(__spec__.cached, __cached__)
     62 # Check the sys module
     63 import sys
     64 assertIdentical(globals(), sys.modules[__name__].__dict__)
     65 if __spec__ is not None:
     66     # XXX: We're not currently making __main__ available under its real name
     67     pass # assertIdentical(globals(), sys.modules[__spec__.name].__dict__)
     68 from test import test_cmd_line_script
     69 example_args_list = test_cmd_line_script.example_args
     70 assertEqual(sys.argv[1:], example_args_list)
     71 print('sys.argv[0]==%a' % sys.argv[0])
     72 print('sys.path[0]==%a' % sys.path[0])
     73 # Check the working directory
     74 import os
     75 print('cwd==%a' % os.getcwd())
     76 """
     77 
     78 def _make_test_script(script_dir, script_basename, source=test_source):
     79     to_return = make_script(script_dir, script_basename, source)
     80     importlib.invalidate_caches()
     81     return to_return
     82 
     83 def _make_test_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename,
     84                        source=test_source, depth=1):
     85     to_return = make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename,
     86                              source, depth)
     87     importlib.invalidate_caches()
     88     return to_return
     89 
     90 # There's no easy way to pass the script directory in to get
     91 # -m to work (avoiding that is the whole point of making
     92 # directories and zipfiles executable!)
     93 # So we fake it for testing purposes with a custom launch script
     94 launch_source = """\
     95 import sys, os.path, runpy
     96 sys.path.insert(0, %s)
     97 runpy._run_module_as_main(%r)
     98 """
     99 
    100 def _make_launch_script(script_dir, script_basename, module_name, path=None):
    101     if path is None:
    102         path = "os.path.dirname(__file__)"
    103     else:
    104         path = repr(path)
    105     source = launch_source % (path, module_name)
    106     to_return = make_script(script_dir, script_basename, source)
    107     importlib.invalidate_caches()
    108     return to_return
    109 
    110 class CmdLineTest(unittest.TestCase):
    111     def _check_output(self, script_name, exit_code, data,
    112                              expected_file, expected_argv0,
    113                              expected_path0, expected_package,
    114                              expected_loader):
    115         if verbose > 1:
    116             print("Output from test script %r:" % script_name)
    117             print(repr(data))
    118         self.assertEqual(exit_code, 0)
    119         printed_loader = '__loader__==%a' % expected_loader
    120         printed_file = '__file__==%a' % expected_file
    121         printed_package = '__package__==%r' % expected_package
    122         printed_argv0 = 'sys.argv[0]==%a' % expected_argv0
    123         printed_path0 = 'sys.path[0]==%a' % expected_path0
    124         printed_cwd = 'cwd==%a' % os.getcwd()
    125         if verbose > 1:
    126             print('Expected output:')
    127             print(printed_file)
    128             print(printed_package)
    129             print(printed_argv0)
    130             print(printed_cwd)
    131         self.assertIn(printed_loader.encode('utf-8'), data)
    132         self.assertIn(printed_file.encode('utf-8'), data)
    133         self.assertIn(printed_package.encode('utf-8'), data)
    134         self.assertIn(printed_argv0.encode('utf-8'), data)
    135         self.assertIn(printed_path0.encode('utf-8'), data)
    136         self.assertIn(printed_cwd.encode('utf-8'), data)
    137 
    138     def _check_script(self, script_name, expected_file,
    139                             expected_argv0, expected_path0,
    140                             expected_package, expected_loader,
    141                             *cmd_line_switches):
    142         run_args = [*support.optim_args_from_interpreter_flags(),
    143                     *cmd_line_switches, script_name, *example_args]
    144         rc, out, err = assert_python_ok(*run_args, __isolated=False)
    145         self._check_output(script_name, rc, out + err, expected_file,
    146                            expected_argv0, expected_path0,
    147                            expected_package, expected_loader)
    148 
    149     def _check_import_error(self, script_name, expected_msg,
    150                             *cmd_line_switches):
    151         run_args = cmd_line_switches + (script_name,)
    152         rc, out, err = assert_python_failure(*run_args)
    153         if verbose > 1:
    154             print('Output from test script %r:' % script_name)
    155             print(repr(err))
    156             print('Expected output: %r' % expected_msg)
    157         self.assertIn(expected_msg.encode('utf-8'), err)
    158 
    159     def test_dash_c_loader(self):
    160         rc, out, err = assert_python_ok("-c", "print(__loader__)")
    161         expected = repr(importlib.machinery.BuiltinImporter).encode("utf-8")
    162         self.assertIn(expected, out)
    163 
    164     def test_stdin_loader(self):
    165         # Unfortunately, there's no way to automatically test the fully
    166         # interactive REPL, since that code path only gets executed when
    167         # stdin is an interactive tty.
    168         p = spawn_python()
    169         try:
    170             p.stdin.write(b"print(__loader__)\n")
    171             p.stdin.flush()
    172         finally:
    173             out = kill_python(p)
    174         expected = repr(importlib.machinery.BuiltinImporter).encode("utf-8")
    175         self.assertIn(expected, out)
    176 
    177     @contextlib.contextmanager
    178     def interactive_python(self, separate_stderr=False):
    179         if separate_stderr:
    180             p = spawn_python('-i', bufsize=1, stderr=subprocess.PIPE)
    181             stderr = p.stderr
    182         else:
    183             p = spawn_python('-i', bufsize=1, stderr=subprocess.STDOUT)
    184             stderr = p.stdout
    185         try:
    186             # Drain stderr until prompt
    187             while True:
    188                 data = stderr.read(4)
    189                 if data == b">>> ":
    190                     break
    191                 stderr.readline()
    192             yield p
    193         finally:
    194             kill_python(p)
    195             stderr.close()
    196 
    197     def check_repl_stdout_flush(self, separate_stderr=False):
    198         with self.interactive_python(separate_stderr) as p:
    199             p.stdin.write(b"print('foo')\n")
    200             p.stdin.flush()
    201             self.assertEqual(b'foo', p.stdout.readline().strip())
    202 
    203     def check_repl_stderr_flush(self, separate_stderr=False):
    204         with self.interactive_python(separate_stderr) as p:
    205             p.stdin.write(b"1/0\n")
    206             p.stdin.flush()
    207             stderr = p.stderr if separate_stderr else p.stdout
    208             self.assertIn(b'Traceback ', stderr.readline())
    209             self.assertIn(b'File "<stdin>"', stderr.readline())
    210             self.assertIn(b'ZeroDivisionError', stderr.readline())
    211 
    212     def test_repl_stdout_flush(self):
    213         self.check_repl_stdout_flush()
    214 
    215     def test_repl_stdout_flush_separate_stderr(self):
    216         self.check_repl_stdout_flush(True)
    217 
    218     def test_repl_stderr_flush(self):
    219         self.check_repl_stderr_flush()
    220 
    221     def test_repl_stderr_flush_separate_stderr(self):
    222         self.check_repl_stderr_flush(True)
    223 
    224     def test_basic_script(self):
    225         with support.temp_dir() as script_dir:
    226             script_name = _make_test_script(script_dir, 'script')
    227             self._check_script(script_name, script_name, script_name,
    228                                script_dir, None,
    229                                importlib.machinery.SourceFileLoader)
    230 
    231     def test_script_compiled(self):
    232         with support.temp_dir() as script_dir:
    233             script_name = _make_test_script(script_dir, 'script')
    234             py_compile.compile(script_name, doraise=True)
    235             os.remove(script_name)
    236             pyc_file = support.make_legacy_pyc(script_name)
    237             self._check_script(pyc_file, pyc_file,
    238                                pyc_file, script_dir, None,
    239                                importlib.machinery.SourcelessFileLoader)
    240 
    241     def test_directory(self):
    242         with support.temp_dir() as script_dir:
    243             script_name = _make_test_script(script_dir, '__main__')
    244             self._check_script(script_dir, script_name, script_dir,
    245                                script_dir, '',
    246                                importlib.machinery.SourceFileLoader)
    247 
    248     def test_directory_compiled(self):
    249         with support.temp_dir() as script_dir:
    250             script_name = _make_test_script(script_dir, '__main__')
    251             py_compile.compile(script_name, doraise=True)
    252             os.remove(script_name)
    253             pyc_file = support.make_legacy_pyc(script_name)
    254             self._check_script(script_dir, pyc_file, script_dir,
    255                                script_dir, '',
    256                                importlib.machinery.SourcelessFileLoader)
    257 
    258     def test_directory_error(self):
    259         with support.temp_dir() as script_dir:
    260             msg = "can't find '__main__' module in %r" % script_dir
    261             self._check_import_error(script_dir, msg)
    262 
    263     def test_zipfile(self):
    264         with support.temp_dir() as script_dir:
    265             script_name = _make_test_script(script_dir, '__main__')
    266             zip_name, run_name = make_zip_script(script_dir, 'test_zip', script_name)
    267             self._check_script(zip_name, run_name, zip_name, zip_name, '',
    268                                zipimport.zipimporter)
    269 
    270     def test_zipfile_compiled(self):
    271         with support.temp_dir() as script_dir:
    272             script_name = _make_test_script(script_dir, '__main__')
    273             compiled_name = py_compile.compile(script_name, doraise=True)
    274             zip_name, run_name = make_zip_script(script_dir, 'test_zip', compiled_name)
    275             self._check_script(zip_name, run_name, zip_name, zip_name, '',
    276                                zipimport.zipimporter)
    277 
    278     def test_zipfile_error(self):
    279         with support.temp_dir() as script_dir:
    280             script_name = _make_test_script(script_dir, 'not_main')
    281             zip_name, run_name = make_zip_script(script_dir, 'test_zip', script_name)
    282             msg = "can't find '__main__' module in %r" % zip_name
    283             self._check_import_error(zip_name, msg)
    284 
    285     def test_module_in_package(self):
    286         with support.temp_dir() as script_dir:
    287             pkg_dir = os.path.join(script_dir, 'test_pkg')
    288             make_pkg(pkg_dir)
    289             script_name = _make_test_script(pkg_dir, 'script')
    290             launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.script')
    291             self._check_script(launch_name, script_name, script_name,
    292                                script_dir, 'test_pkg',
    293                                importlib.machinery.SourceFileLoader)
    294 
    295     def test_module_in_package_in_zipfile(self):
    296         with support.temp_dir() as script_dir:
    297             zip_name, run_name = _make_test_zip_pkg(script_dir, 'test_zip', 'test_pkg', 'script')
    298             launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.script', zip_name)
    299             self._check_script(launch_name, run_name, run_name,
    300                                zip_name, 'test_pkg', zipimport.zipimporter)
    301 
    302     def test_module_in_subpackage_in_zipfile(self):
    303         with support.temp_dir() as script_dir:
    304             zip_name, run_name = _make_test_zip_pkg(script_dir, 'test_zip', 'test_pkg', 'script', depth=2)
    305             launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.test_pkg.script', zip_name)
    306             self._check_script(launch_name, run_name, run_name,
    307                                zip_name, 'test_pkg.test_pkg',
    308                                zipimport.zipimporter)
    309 
    310     def test_package(self):
    311         with support.temp_dir() as script_dir:
    312             pkg_dir = os.path.join(script_dir, 'test_pkg')
    313             make_pkg(pkg_dir)
    314             script_name = _make_test_script(pkg_dir, '__main__')
    315             launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg')
    316             self._check_script(launch_name, script_name,
    317                                script_name, script_dir, 'test_pkg',
    318                                importlib.machinery.SourceFileLoader)
    319 
    320     def test_package_compiled(self):
    321         with support.temp_dir() as script_dir:
    322             pkg_dir = os.path.join(script_dir, 'test_pkg')
    323             make_pkg(pkg_dir)
    324             script_name = _make_test_script(pkg_dir, '__main__')
    325             compiled_name = py_compile.compile(script_name, doraise=True)
    326             os.remove(script_name)
    327             pyc_file = support.make_legacy_pyc(script_name)
    328             launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg')
    329             self._check_script(launch_name, pyc_file,
    330                                pyc_file, script_dir, 'test_pkg',
    331                                importlib.machinery.SourcelessFileLoader)
    332 
    333     def test_package_error(self):
    334         with support.temp_dir() as script_dir:
    335             pkg_dir = os.path.join(script_dir, 'test_pkg')
    336             make_pkg(pkg_dir)
    337             msg = ("'test_pkg' is a package and cannot "
    338                    "be directly executed")
    339             launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg')
    340             self._check_import_error(launch_name, msg)
    341 
    342     def test_package_recursion(self):
    343         with support.temp_dir() as script_dir:
    344             pkg_dir = os.path.join(script_dir, 'test_pkg')
    345             make_pkg(pkg_dir)
    346             main_dir = os.path.join(pkg_dir, '__main__')
    347             make_pkg(main_dir)
    348             msg = ("Cannot use package as __main__ module; "
    349                    "'test_pkg' is a package and cannot "
    350                    "be directly executed")
    351             launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg')
    352             self._check_import_error(launch_name, msg)
    353 
    354     def test_issue8202(self):
    355         # Make sure package __init__ modules see "-m" in sys.argv0 while
    356         # searching for the module to execute
    357         with support.temp_dir() as script_dir:
    358             with support.change_cwd(path=script_dir):
    359                 pkg_dir = os.path.join(script_dir, 'test_pkg')
    360                 make_pkg(pkg_dir, "import sys; print('init_argv0==%r' % sys.argv[0])")
    361                 script_name = _make_test_script(pkg_dir, 'script')
    362                 rc, out, err = assert_python_ok('-m', 'test_pkg.script', *example_args, __isolated=False)
    363                 if verbose > 1:
    364                     print(repr(out))
    365                 expected = "init_argv0==%r" % '-m'
    366                 self.assertIn(expected.encode('utf-8'), out)
    367                 self._check_output(script_name, rc, out,
    368                                    script_name, script_name, '', 'test_pkg',
    369                                    importlib.machinery.SourceFileLoader)
    370 
    371     def test_issue8202_dash_c_file_ignored(self):
    372         # Make sure a "-c" file in the current directory
    373         # does not alter the value of sys.path[0]
    374         with support.temp_dir() as script_dir:
    375             with support.change_cwd(path=script_dir):
    376                 with open("-c", "w") as f:
    377                     f.write("data")
    378                     rc, out, err = assert_python_ok('-c',
    379                         'import sys; print("sys.path[0]==%r" % sys.path[0])',
    380                         __isolated=False)
    381                     if verbose > 1:
    382                         print(repr(out))
    383                     expected = "sys.path[0]==%r" % ''
    384                     self.assertIn(expected.encode('utf-8'), out)
    385 
    386     def test_issue8202_dash_m_file_ignored(self):
    387         # Make sure a "-m" file in the current directory
    388         # does not alter the value of sys.path[0]
    389         with support.temp_dir() as script_dir:
    390             script_name = _make_test_script(script_dir, 'other')
    391             with support.change_cwd(path=script_dir):
    392                 with open("-m", "w") as f:
    393                     f.write("data")
    394                     rc, out, err = assert_python_ok('-m', 'other', *example_args,
    395                                                     __isolated=False)
    396                     self._check_output(script_name, rc, out,
    397                                       script_name, script_name, '', '',
    398                                       importlib.machinery.SourceFileLoader)
    399 
    400     @contextlib.contextmanager
    401     def setup_test_pkg(self, *args):
    402         with support.temp_dir() as script_dir, \
    403                 support.change_cwd(path=script_dir):
    404             pkg_dir = os.path.join(script_dir, 'test_pkg')
    405             make_pkg(pkg_dir, *args)
    406             yield pkg_dir
    407 
    408     def check_dash_m_failure(self, *args):
    409         rc, out, err = assert_python_failure('-m', *args, __isolated=False)
    410         if verbose > 1:
    411             print(repr(out))
    412         self.assertEqual(rc, 1)
    413         return err
    414 
    415     def test_dash_m_error_code_is_one(self):
    416         # If a module is invoked with the -m command line flag
    417         # and results in an error that the return code to the
    418         # shell is '1'
    419         with self.setup_test_pkg() as pkg_dir:
    420             script_name = _make_test_script(pkg_dir, 'other',
    421                                             "if __name__ == '__main__': raise ValueError")
    422             err = self.check_dash_m_failure('test_pkg.other', *example_args)
    423             self.assertIn(b'ValueError', err)
    424 
    425     def test_dash_m_errors(self):
    426         # Exercise error reporting for various invalid package executions
    427         tests = (
    428             ('builtins', br'No code object available'),
    429             ('builtins.x', br'Error while finding module specification.*'
    430                 br'AttributeError'),
    431             ('builtins.x.y', br'Error while finding module specification.*'
    432                 br'ModuleNotFoundError.*No module named.*not a package'),
    433             ('os.path', br'loader.*cannot handle'),
    434             ('importlib', br'No module named.*'
    435                 br'is a package and cannot be directly executed'),
    436             ('importlib.nonexistant', br'No module named'),
    437             ('.unittest', br'Relative module names not supported'),
    438         )
    439         for name, regex in tests:
    440             with self.subTest(name):
    441                 rc, _, err = assert_python_failure('-m', name)
    442                 self.assertEqual(rc, 1)
    443                 self.assertRegex(err, regex)
    444                 self.assertNotIn(b'Traceback', err)
    445 
    446     def test_dash_m_bad_pyc(self):
    447         with support.temp_dir() as script_dir, \
    448                 support.change_cwd(path=script_dir):
    449             os.mkdir('test_pkg')
    450             # Create invalid *.pyc as empty file
    451             with open('test_pkg/__init__.pyc', 'wb'):
    452                 pass
    453             err = self.check_dash_m_failure('test_pkg')
    454             self.assertRegex(err,
    455                 br'Error while finding module specification.*'
    456                 br'ImportError.*bad magic number')
    457             self.assertNotIn(b'is a package', err)
    458             self.assertNotIn(b'Traceback', err)
    459 
    460     def test_dash_m_init_traceback(self):
    461         # These were wrapped in an ImportError and tracebacks were
    462         # suppressed; see Issue 14285
    463         exceptions = (ImportError, AttributeError, TypeError, ValueError)
    464         for exception in exceptions:
    465             exception = exception.__name__
    466             init = "raise {0}('Exception in __init__.py')".format(exception)
    467             with self.subTest(exception), \
    468                     self.setup_test_pkg(init) as pkg_dir:
    469                 err = self.check_dash_m_failure('test_pkg')
    470                 self.assertIn(exception.encode('ascii'), err)
    471                 self.assertIn(b'Exception in __init__.py', err)
    472                 self.assertIn(b'Traceback', err)
    473 
    474     def test_dash_m_main_traceback(self):
    475         # Ensure that an ImportError's traceback is reported
    476         with self.setup_test_pkg() as pkg_dir:
    477             main = "raise ImportError('Exception in __main__ module')"
    478             _make_test_script(pkg_dir, '__main__', main)
    479             err = self.check_dash_m_failure('test_pkg')
    480             self.assertIn(b'ImportError', err)
    481             self.assertIn(b'Exception in __main__ module', err)
    482             self.assertIn(b'Traceback', err)
    483 
    484     def test_pep_409_verbiage(self):
    485         # Make sure PEP 409 syntax properly suppresses
    486         # the context of an exception
    487         script = textwrap.dedent("""\
    488             try:
    489                 raise ValueError
    490             except:
    491                 raise NameError from None
    492             """)
    493         with support.temp_dir() as script_dir:
    494             script_name = _make_test_script(script_dir, 'script', script)
    495             exitcode, stdout, stderr = assert_python_failure(script_name)
    496             text = stderr.decode('ascii').split('\n')
    497             self.assertEqual(len(text), 4)
    498             self.assertTrue(text[0].startswith('Traceback'))
    499             self.assertTrue(text[1].startswith('  File '))
    500             self.assertTrue(text[3].startswith('NameError'))
    501 
    502     def test_non_ascii(self):
    503         # Mac OS X denies the creation of a file with an invalid UTF-8 name.
    504         # Windows allows creating a name with an arbitrary bytes name, but
    505         # Python cannot a undecodable bytes argument to a subprocess.
    506         if (support.TESTFN_UNDECODABLE
    507         and sys.platform not in ('win32', 'darwin')):
    508             name = os.fsdecode(support.TESTFN_UNDECODABLE)
    509         elif support.TESTFN_NONASCII:
    510             name = support.TESTFN_NONASCII
    511         else:
    512             self.skipTest("need support.TESTFN_NONASCII")
    513 
    514         # Issue #16218
    515         source = 'print(ascii(__file__))\n'
    516         script_name = _make_test_script(os.curdir, name, source)
    517         self.addCleanup(support.unlink, script_name)
    518         rc, stdout, stderr = assert_python_ok(script_name)
    519         self.assertEqual(
    520             ascii(script_name),
    521             stdout.rstrip().decode('ascii'),
    522             'stdout=%r stderr=%r' % (stdout, stderr))
    523         self.assertEqual(0, rc)
    524 
    525     def test_issue20500_exit_with_exception_value(self):
    526         script = textwrap.dedent("""\
    527             import sys
    528             error = None
    529             try:
    530                 raise ValueError('some text')
    531             except ValueError as err:
    532                 error = err
    533 
    534             if error:
    535                 sys.exit(error)
    536             """)
    537         with support.temp_dir() as script_dir:
    538             script_name = _make_test_script(script_dir, 'script', script)
    539             exitcode, stdout, stderr = assert_python_failure(script_name)
    540             text = stderr.decode('ascii')
    541             self.assertEqual(text, "some text")
    542 
    543     def test_syntaxerror_unindented_caret_position(self):
    544         script = "1 + 1 = 2\n"
    545         with support.temp_dir() as script_dir:
    546             script_name = _make_test_script(script_dir, 'script', script)
    547             exitcode, stdout, stderr = assert_python_failure(script_name)
    548             text = io.TextIOWrapper(io.BytesIO(stderr), 'ascii').read()
    549             # Confirm that the caret is located under the first 1 character
    550             self.assertIn("\n    1 + 1 = 2\n    ^", text)
    551 
    552     def test_syntaxerror_indented_caret_position(self):
    553         script = textwrap.dedent("""\
    554             if True:
    555                 1 + 1 = 2
    556             """)
    557         with support.temp_dir() as script_dir:
    558             script_name = _make_test_script(script_dir, 'script', script)
    559             exitcode, stdout, stderr = assert_python_failure(script_name)
    560             text = io.TextIOWrapper(io.BytesIO(stderr), 'ascii').read()
    561             # Confirm that the caret is located under the first 1 character
    562             self.assertIn("\n    1 + 1 = 2\n    ^", text)
    563 
    564             # Try the same with a form feed at the start of the indented line
    565             script = (
    566                 "if True:\n"
    567                 "\f    1 + 1 = 2\n"
    568             )
    569             script_name = _make_test_script(script_dir, "script", script)
    570             exitcode, stdout, stderr = assert_python_failure(script_name)
    571             text = io.TextIOWrapper(io.BytesIO(stderr), "ascii").read()
    572             self.assertNotIn("\f", text)
    573             self.assertIn("\n    1 + 1 = 2\n    ^", text)
    574 
    575     def test_consistent_sys_path_for_direct_execution(self):
    576         # This test case ensures that the following all give the same
    577         # sys.path configuration:
    578         #
    579         #    ./python -s script_dir/__main__.py
    580         #    ./python -s script_dir
    581         #    ./python -I script_dir
    582         script = textwrap.dedent("""\
    583             import sys
    584             for entry in sys.path:
    585                 print(entry)
    586             """)
    587         # Always show full path diffs on errors
    588         self.maxDiff = None
    589         with support.temp_dir() as work_dir, support.temp_dir() as script_dir:
    590             script_name = _make_test_script(script_dir, '__main__', script)
    591             # Reference output comes from directly executing __main__.py
    592             # We omit PYTHONPATH and user site to align with isolated mode
    593             p = spawn_python("-Es", script_name, cwd=work_dir)
    594             out_by_name = kill_python(p).decode().splitlines()
    595             self.assertEqual(out_by_name[0], script_dir)
    596             self.assertNotIn(work_dir, out_by_name)
    597             # Directory execution should give the same output
    598             p = spawn_python("-Es", script_dir, cwd=work_dir)
    599             out_by_dir = kill_python(p).decode().splitlines()
    600             self.assertEqual(out_by_dir, out_by_name)
    601             # As should directory execution in isolated mode
    602             p = spawn_python("-I", script_dir, cwd=work_dir)
    603             out_by_dir_isolated = kill_python(p).decode().splitlines()
    604             self.assertEqual(out_by_dir_isolated, out_by_dir, out_by_name)
    605 
    606     def test_consistent_sys_path_for_module_execution(self):
    607         # This test case ensures that the following both give the same
    608         # sys.path configuration:
    609         #    ./python -sm script_pkg.__main__
    610         #    ./python -sm script_pkg
    611         #
    612         # And that this fails as unable to find the package:
    613         #    ./python -Im script_pkg
    614         script = textwrap.dedent("""\
    615             import sys
    616             for entry in sys.path:
    617                 print(entry)
    618             """)
    619         # Always show full path diffs on errors
    620         self.maxDiff = None
    621         with support.temp_dir() as work_dir:
    622             script_dir = os.path.join(work_dir, "script_pkg")
    623             os.mkdir(script_dir)
    624             script_name = _make_test_script(script_dir, '__main__', script)
    625             # Reference output comes from `-m script_pkg.__main__`
    626             # We omit PYTHONPATH and user site to better align with the
    627             # direct execution test cases
    628             p = spawn_python("-sm", "script_pkg.__main__", cwd=work_dir)
    629             out_by_module = kill_python(p).decode().splitlines()
    630             self.assertEqual(out_by_module[0], '')
    631             self.assertNotIn(script_dir, out_by_module)
    632             # Package execution should give the same output
    633             p = spawn_python("-sm", "script_pkg", cwd=work_dir)
    634             out_by_package = kill_python(p).decode().splitlines()
    635             self.assertEqual(out_by_package, out_by_module)
    636             # Isolated mode should fail with an import error
    637             exitcode, stdout, stderr = assert_python_failure(
    638                 "-Im", "script_pkg", cwd=work_dir
    639             )
    640             traceback_lines = stderr.decode().splitlines()
    641             self.assertIn("No module named script_pkg", traceback_lines[-1])
    642 
    643 def test_main():
    644     support.run_unittest(CmdLineTest)
    645     support.reap_children()
    646 
    647 if __name__ == '__main__':
    648     test_main()
    649