[Python-checkins] r66596 - in sandbox/trunk/setuptools/setuptools: command/easy_install.py tests/test_resources.py
phillip.eby
python-checkins at python.org
Wed Sep 24 18:42:21 CEST 2008
Author: phillip.eby
Date: Wed Sep 24 18:42:20 2008
New Revision: 66596
Log:
Fix for http://bugs.python.org/setuptools/issue27 (Jython shebang
lines)
Modified:
sandbox/trunk/setuptools/setuptools/command/easy_install.py
sandbox/trunk/setuptools/setuptools/tests/test_resources.py
Modified: sandbox/trunk/setuptools/setuptools/command/easy_install.py
==============================================================================
--- sandbox/trunk/setuptools/setuptools/command/easy_install.py (original)
+++ sandbox/trunk/setuptools/setuptools/command/easy_install.py Wed Sep 24 18:42:20 2008
@@ -1415,8 +1415,7 @@
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 @@
# 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 @@
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 @@
"""
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 @@
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):
Modified: sandbox/trunk/setuptools/setuptools/tests/test_resources.py
==============================================================================
--- sandbox/trunk/setuptools/setuptools/tests/test_resources.py (original)
+++ sandbox/trunk/setuptools/setuptools/tests/test_resources.py Wed Sep 24 18:42:20 2008
@@ -1,8 +1,10 @@
-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 @@
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 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
More information about the Python-checkins
mailing list