Commit d503d880 authored by Reinout van Rees's avatar Reinout van Rees

Distutils script: supporting future and docstrings.

Fixes #102

Distutils scripts can contain quite a lot of code. Up till now,
only a encoding hint was detected and placed at the top above
our 'import sys' and 'sys.path=' stuff.

Now we look for the first non-__future__ import line and place our
sys.path statement above that line. This makes sure the encoding hint,
the module docstring and the future imports are all above our code,
as should be.

There might be corner cases, but at least this fixes a couple of
common problems.
parent 6874dc07
...@@ -1067,27 +1067,36 @@ def _script(module_name, attrs, path, dest, arguments, initialization, rsetup): ...@@ -1067,27 +1067,36 @@ def _script(module_name, attrs, path, dest, arguments, initialization, rsetup):
def _distutils_script(path, dest, script_content, initialization, rsetup): def _distutils_script(path, dest, script_content, initialization, rsetup):
if is_win32: if is_win32:
dest += '-script.py' dest += '-script.py'
lines = script_content.splitlines(True) lines = script_content.splitlines(True)
if not ('#!' in lines[0]) and ('python' in lines[0]): if not ('#!' in lines[0]) and ('python' in lines[0]):
# The script doesn't follow distutil's rules. Ignore it. # The script doesn't follow distutil's rules. Ignore it.
return [] return []
source_encoding_line = '' lines = lines[1:] # Strip off the first hashbang line.
original_content = ''.join(lines[1:]) line_with_first_import = None
if (len(lines) > 1) and is_source_encoding_line(lines[1]): for line_number, line in enumerate(lines):
# The second line contains a source encoding line. Copy it verbatim. if not 'import' in line:
source_encoding_line = lines[1].rstrip() continue
original_content = ''.join(lines[2:]) if not line.startswith('import') or line.startswith('from'):
continue
if '__future__' in line:
continue
line_with_first_import = line_number
if line_with_first_import is None:
before = ''.join(lines)
after = ''
else:
before = ''.join(lines[:line_with_first_import])
after = ''.join(lines[line_with_first_import:])
python = _safe_arg(sys.executable) python = _safe_arg(sys.executable)
contents = distutils_script_template % dict( contents = distutils_script_template % dict(
python = python, python = python,
source_encoding_line = source_encoding_line,
path = path, path = path,
initialization = initialization, initialization = initialization,
relative_paths_setup = rsetup, relative_paths_setup = rsetup,
original_content = original_content before = before,
after = after
) )
return _create_script(contents, dest) return _create_script(contents, dest)
...@@ -1148,9 +1157,8 @@ if __name__ == '__main__': ...@@ -1148,9 +1157,8 @@ if __name__ == '__main__':
sys.exit(%(module_name)s.%(attrs)s(%(arguments)s)) sys.exit(%(module_name)s.%(attrs)s(%(arguments)s))
''' '''
distutils_script_template = script_header + '''\ distutils_script_template = script_header + '''
%(before)s
%(source_encoding_line)s
%(relative_paths_setup)s %(relative_paths_setup)s
import sys import sys
sys.path[0:0] = [ sys.path[0:0] = [
...@@ -1158,7 +1166,7 @@ sys.path[0:0] = [ ...@@ -1158,7 +1166,7 @@ sys.path[0:0] = [
] ]
%(initialization)s %(initialization)s
%(original_content)s''' %(after)s'''
def _pyscript(path, dest, rsetup, initialization=''): def _pyscript(path, dest, rsetup, initialization=''):
......
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