1import os 2import subprocess 3import sys 4import unittest 5from test import support 6from test.test_tools import import_tool, scriptsdir, skip_if_missing 7 8 9# need Tools/script/ directory: skip if run on Python installed on the system 10skip_if_missing() 11 12 13class TestPathfixFunctional(unittest.TestCase): 14 script = os.path.join(scriptsdir, 'pathfix.py') 15 16 def setUp(self): 17 self.addCleanup(support.unlink, support.TESTFN) 18 19 def pathfix(self, shebang, pathfix_flags, exitcode=0, stdout='', stderr='', 20 directory=''): 21 if directory: 22 # bpo-38347: Test filename should contain lowercase, uppercase, 23 # "-", "_" and digits. 24 filename = os.path.join(directory, 'script-A_1.py') 25 pathfix_arg = directory 26 else: 27 filename = support.TESTFN 28 pathfix_arg = filename 29 30 with open(filename, 'w', encoding='utf8') as f: 31 f.write(f'{shebang}\n' + 'print("Hello world")\n') 32 33 proc = subprocess.run( 34 [sys.executable, self.script, 35 *pathfix_flags, '-n', pathfix_arg], 36 capture_output=True, text=1) 37 38 if stdout == '' and proc.returncode == 0: 39 stdout = f'{filename}: updating\n' 40 self.assertEqual(proc.returncode, exitcode, proc) 41 self.assertEqual(proc.stdout, stdout, proc) 42 self.assertEqual(proc.stderr, stderr, proc) 43 44 with open(filename, 'r', encoding='utf8') as f: 45 output = f.read() 46 47 lines = output.split('\n') 48 self.assertEqual(lines[1:], ['print("Hello world")', '']) 49 new_shebang = lines[0] 50 51 if proc.returncode != 0: 52 self.assertEqual(shebang, new_shebang) 53 54 return new_shebang 55 56 def test_recursive(self): 57 tmpdir = support.TESTFN + '.d' 58 self.addCleanup(support.rmtree, tmpdir) 59 os.mkdir(tmpdir) 60 expected_stderr = f"recursedown('{os.path.basename(tmpdir)}')\n" 61 self.assertEqual( 62 self.pathfix( 63 '#! /usr/bin/env python', 64 ['-i', '/usr/bin/python3'], 65 directory=tmpdir, 66 stderr=expected_stderr), 67 '#! /usr/bin/python3') 68 69 def test_pathfix(self): 70 self.assertEqual( 71 self.pathfix( 72 '#! /usr/bin/env python', 73 ['-i', '/usr/bin/python3']), 74 '#! /usr/bin/python3') 75 self.assertEqual( 76 self.pathfix( 77 '#! /usr/bin/env python -R', 78 ['-i', '/usr/bin/python3']), 79 '#! /usr/bin/python3') 80 81 def test_pathfix_keeping_flags(self): 82 self.assertEqual( 83 self.pathfix( 84 '#! /usr/bin/env python -R', 85 ['-i', '/usr/bin/python3', '-k']), 86 '#! /usr/bin/python3 -R') 87 self.assertEqual( 88 self.pathfix( 89 '#! /usr/bin/env python', 90 ['-i', '/usr/bin/python3', '-k']), 91 '#! /usr/bin/python3') 92 93 def test_pathfix_adding_flag(self): 94 self.assertEqual( 95 self.pathfix( 96 '#! /usr/bin/env python', 97 ['-i', '/usr/bin/python3', '-a', 's']), 98 '#! /usr/bin/python3 -s') 99 self.assertEqual( 100 self.pathfix( 101 '#! /usr/bin/env python -S', 102 ['-i', '/usr/bin/python3', '-a', 's']), 103 '#! /usr/bin/python3 -s') 104 self.assertEqual( 105 self.pathfix( 106 '#! /usr/bin/env python -V', 107 ['-i', '/usr/bin/python3', '-a', 'v', '-k']), 108 '#! /usr/bin/python3 -vV') 109 self.assertEqual( 110 self.pathfix( 111 '#! /usr/bin/env python', 112 ['-i', '/usr/bin/python3', '-a', 'Rs']), 113 '#! /usr/bin/python3 -Rs') 114 self.assertEqual( 115 self.pathfix( 116 '#! /usr/bin/env python -W default', 117 ['-i', '/usr/bin/python3', '-a', 's', '-k']), 118 '#! /usr/bin/python3 -sW default') 119 120 def test_pathfix_adding_errors(self): 121 self.pathfix( 122 '#! /usr/bin/env python -E', 123 ['-i', '/usr/bin/python3', '-a', 'W default', '-k'], 124 exitcode=2, 125 stderr="-a option doesn't support whitespaces") 126 127 128if __name__ == '__main__': 129 unittest.main() 130