Commits

Vinay Sajip committed 5ce2d79 Draft

Updated wheel code to respect arguments in prebuilt script shebang lines.

  • Participants
  • Parent commits 6ecb268

Comments (0)

Files changed (4)

File distlib/wheel.py

 ''', re.IGNORECASE | re.VERBOSE)
 
 SHEBANG_RE = re.compile(br'\s*#![^\r\n]*')
+SHEBANG_DETAIL_RE = re.compile(br'(\s*#!("[^"]+"|[\w/\\:.]+))\s+(.*)$')
+SHEBANG_PYTHON = b'#!python'
 
 if os.sep == '/':
     to_posix = lambda o: o
     def process_shebang(self, data):
         m = SHEBANG_RE.match(data)
         if m:
-            data = b'#!python' + data[m.end():]
+            end = m.end()
+            shebang, data_after_shebang = data[:end], data[end:]
+            # Preserve any arguments after the interpreter
+            m = SHEBANG_DETAIL_RE.match(shebang)
+            if m:
+                args = b' ' + m.groups()[-1]
+            else:
+                args = b''
+            shebang = SHEBANG_PYTHON + args
+            data = shebang + data_after_shebang
         else:
             cr = data.find(b'\r')
             lf = data.find(b'\n')
                     term = b'\r\n'
                 else:
                     term = b'\r'
-            data = b'#!python' + term + data
+            data = SHEBANG_PYTHON + term + data
         return data
 
     def get_hash(self, data, hash_kind=None):

File tests/dummy-0.1-py27-none-any.whl

Binary file modified.

File tests/test_scripts.py

 
     def test_args_on_copy(self):
         self.maker.variants = set([''])
+        self.maker.executable = 'mypython'
         files = self.maker.make('script5.py')
         with open(files[0]) as f:
             actual = f.readline().strip()
-        expected = '#!%s -mzippy.activate' % sys.executable
-        self.assertEqual(actual, expected)
+        self.assertEqual(actual, '#!mypython -mzippy.activate')
 
 if __name__ == '__main__':  # pragma: no cover
     unittest.main()

File tests/test_wheel.py

         self.assertFalse(hasattr(warner, 'wheel_version'))
         self.assertFalse(hasattr(warner, 'file_version'))
 
+    def test_custom_executable(self):
+        fn = os.path.join(HERE, 'dummy-0.1-py27-none-any.whl')
+        dstdir = tempfile.mkdtemp()
+        self.addCleanup(shutil.rmtree, dstdir)
+        w = Wheel(fn)
+        paths = {'prefix': dstdir}
+        for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'):
+            paths[key] = os.path.join(dstdir, key)
+        maker = ScriptMaker(None, None)
+        maker.executable = 'mypython'
+        w.install(paths, maker)
+        p = os.path.join(paths['scripts'], 'dummy.py')
+        with open(p) as f:
+            line = f.readline().strip()
+        self.assertEqual(line, '#!mypython -E')
+
     def test_verify(self):
         fn = os.path.join(HERE, 'dummy-0.1-py27-none-any.whl')
         w = Wheel(fn)