Commit 7375959b authored by PJ Eby's avatar PJ Eby

Backport fix for http://bugs.python.org/setuptools/issue27

--HG--
branch : setuptools-0.6
extra : convert_revision : svn%3A6015fed2-1504-0410-9fe1-9d1591cc4771/sandbox/branches/setuptools-0.6%4066597
parent fda8b67a
......@@ -1415,8 +1415,7 @@ def get_script_header(script_text, executable=sys_executable, wininst=False):
options = ''
if match:
options = match.group(1) or ''
if options:
options = ' '+options
if options: options = ' '+options
if wininst:
executable = "python.exe"
else:
......@@ -1430,7 +1429,8 @@ def get_script_header(script_text, executable=sys_executable, wininst=False):
# else: punt, we can't do it, let the warning happen anyway
else:
options = ' -x'
hdr = "#!%(executable)s%(options)s\n" % locals()
executable = fix_jython_executable(executable, options)
hdr = "#!%(executable)s%(options)s\n" % locals()
return hdr
def auto_chmod(func, arg, exc):
......@@ -1465,14 +1465,14 @@ def is_python(text, filename='<string>'):
else:
return True
def is_sh(executable):
"""Determine if the specified executable is a .sh (contains a #! line)"""
try:
fp = open(executable)
magic = fp.read(2)
fp.close()
except (OSError,IOError): return executable
return magic == '#!'
def nt_quote_arg(arg):
"""Quote a command line argument according to Windows parsing rules"""
......@@ -1520,10 +1520,8 @@ def is_python_script(script_text, filename):
"""
if filename.endswith('.py') or filename.endswith('.pyw'):
return True # extension says it's Python
if is_python(script_text, filename):
return True # it's syntactically valid Python
if script_text.startswith('#!'):
# It begins with a '#!' line, so check if 'python' is in it somewhere
return 'python' in script_text.splitlines()[0].lower()
......@@ -1543,17 +1541,19 @@ def chmod(path, mode):
except os.error, e:
log.debug("chmod failed: %s", e)
def fix_jython_executable(executable, options):
if sys.platform.startswith('java') and is_sh(executable):
# Workaround Jython's sys.executable being a .sh (an invalid
# shebang line interpreter)
if options:
# Can't apply the workaround, leave it broken
log.warn("WARNING: Unable to adapt shebang line for Jython,"
" the following script is NOT executable\n"
" see http://bugs.jython.org/issue1112 for"
" more information.")
else:
return '/usr/bin/env %s' % executable
return executable
def get_script_args(dist, executable=sys_executable, wininst=False):
......
from unittest import TestCase, makeSuite
from pkg_resources import *
import pkg_resources, sys
try:
frozenset
#!/usr/bin/python
# -*- coding: utf-8 -*-
# NOTE: the shebang and encoding lines are for ScriptHeaderTests; do not remove
from unittest import TestCase, makeSuite; from pkg_resources import *
from setuptools.command.easy_install import get_script_header, is_sh
import os, pkg_resources, sys, StringIO
try: frozenset
except NameError:
from sets import ImmutableSet as frozenset
......@@ -28,14 +30,12 @@ class DistroTests(TestCase):
ad = Environment([], platform=None, python=None)
self.assertEqual(list(ad), [])
self.assertEqual(ad['FooPkg'],[])
ad.add(Distribution.from_filename("FooPkg-1.3_1.egg"))
ad.add(Distribution.from_filename("FooPkg-1.4-py2.4-win32.egg"))
ad.add(Distribution.from_filename("FooPkg-1.2-py2.4.egg"))
# Name is in there now
self.failUnless(ad['FooPkg'])
# But only 1 package
self.assertEqual(list(ad), ['foopkg'])
......@@ -490,4 +490,44 @@ class ParseTests(TestCase):
class ScriptHeaderTests(TestCase):
non_ascii_exe = '/Users/José/bin/python'
def test_get_script_header(self):
if not sys.platform.startswith('java') or not is_sh(sys.executable):
# This test is for non-Jython platforms
self.assertEqual(get_script_header('#!/usr/local/bin/python'),
'#!%s\n' % os.path.normpath(sys.executable))
self.assertEqual(get_script_header('#!/usr/bin/python -x'),
'#!%s -x\n' % os.path.normpath(sys.executable))
self.assertEqual(get_script_header('#!/usr/bin/python',
executable=self.non_ascii_exe),
'#!%s -x\n' % self.non_ascii_exe)
def test_get_script_header_jython_workaround(self):
platform = sys.platform
sys.platform = 'java1.5.0_13'
stdout = sys.stdout
try:
# A mock sys.executable that uses a shebang line (this file)
exe = os.path.normpath(os.path.splitext(__file__)[0] + '.py')
self.assertEqual(
get_script_header('#!/usr/local/bin/python', executable=exe),
'#!/usr/bin/env %s\n' % exe)
# Ensure we generate what is basically a broken shebang line
# when there's options, with a warning emitted
sys.stdout = StringIO.StringIO()
self.assertEqual(get_script_header('#!/usr/bin/python -x',
executable=exe),
'#!%s -x\n' % exe)
self.assert_('Unable to adapt shebang line' in sys.stdout.getvalue())
sys.stdout = StringIO.StringIO()
self.assertEqual(get_script_header('#!/usr/bin/python',
executable=self.non_ascii_exe),
'#!%s -x\n' % self.non_ascii_exe)
self.assert_('Unable to adapt shebang line' in sys.stdout.getvalue())
finally:
sys.platform = platform
sys.stdout = stdout
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment