Hi!

For a long time, I have been annoyed by distutils behavior concerning 
"scripts":  I always put 
  #!/usr/bin/env python
into the first line in order to let the incredibly useful "env" program start 
the right python version.

I know that it is quite evil to hardcode /usr/bin/python 
or /usr/local/bin/python; I have seen dozens of #! hacks for finding e.g. 
perl, and I was delighted to find /usr/bin/env, which solves the problem once 
and for all.  (And yes - it is always in /usr/bin/! ;-) )

Now distutils tries to be intelligent and "destroys" my nice #! lines, which 
can be quite evil in complex setups, e.g. when you share your home directory 
via NFS (or rsync/unison) between several environments with different python 
installations.  Furthermore, we are using the "module" system here at our 
university, so that I can dynamically choose between half a dozen python 
versions ("module" manages your PATH variables).  Replacing the python path 
turns nice, pure python scrips into platform-specific programs as you can see 
here:

[EMAIL PROTECTED]:~ head -n1 ~/vigra/interactive/build/scripts-2.4/pyterm
#!/software/python-2.4.4/SuSE-9.0/bin/python

Note the SuSE-9.0 exec-prefix in the path; we are using several Linux and 
Solaris versions here:

[EMAIL PROTECTED]:~/tmp/vi3build -> ls -1 /software/python-2.4.4/*/bin/python
/software/python-2.4.4/SuSE-10.0/bin/python*
/software/python-2.4.4/SuSE-9.0/bin/python*
/software/python-2.4.4/SunOS-5.8/bin/python*

I see that distutils as it is now does the right thing
* on Windows systems,
* on any system where /usr/bin/env is missing, or
* when the source file has a #! with a broken path.

What I propose is a minimal invasive change which keeps /usr/bin/env iff it is 
in the #! line *and* exists on the current system.  (A more brave change 
would be to always use /usr/bin/env if it exists, but I think that is a topic 
open for discussion.)  Attached you'll find a patch which implements this; I 
did not yet update tests/test_build_scripts.py however.

Comments?  (I first posted this to distutils-sig but was told that distutils 
is a bit neglected there, so I decided to try to push these simple patches in 
via python-dev.)

Ciao, /  /
     /--/
    /  / ANS
--- /software/python-2.4.4/lib/python2.4/distutils/command/build_scripts.py.orig	2007-01-02 14:06:37.000000000 +0100
+++ /software/python-2.4.4/lib/python2.4/distutils/command/build_scripts.py	2007-02-15 15:02:39.000000000 +0100
@@ -15,7 +15,7 @@
 from distutils import log
 
 # check if Python is called on the first line with this expression
-first_line_re = re.compile('^#!.*python[0-9.]*([ \t].*)?$')
+first_line_re = re.compile('^#! *(.*python[0-9.]*)([ \t].*)?$')
 
 class build_scripts (Command):
 
@@ -89,23 +89,27 @@
                 match = first_line_re.match(first_line)
                 if match:
                     adjust = 1
-                    post_interp = match.group(1) or ''
+                    use_env = match.group(1).startswith("/usr/bin/env") and \
+                             os.path.exists("/usr/bin/env")
+                    if use_env and match.group(1) == "/usr/bin/env python":
+                        adjust = 0
+                    post_interp = match.group(2) or ''
 
             if adjust:
+                if use_env:
+                    python_executable = "/usr/bin/env python"
+                elif not sysconfig.python_build:
+                    python_executable = self.executable
+                else:
+                    python_executable = os.path.join(
+                        sysconfig.get_config_var("BINDIR"),
+                        "python" + sysconfig.get_config_var("EXE"))
+
                 log.info("copying and adjusting %s -> %s", script,
                          self.build_dir)
                 if not self.dry_run:
                     outf = open(outfile, "w")
-                    if not sysconfig.python_build:
-                        outf.write("#!%s%s\n" %
-                                   (self.executable,
-                                    post_interp))
-                    else:
-                        outf.write("#!%s%s\n" %
-                                   (os.path.join(
-                            sysconfig.get_config_var("BINDIR"),
-                            "python" + sysconfig.get_config_var("EXE")),
-                                    post_interp))
+                    outf.write("#!%s%s\n" % (python_executable, post_interp))
                     outf.writelines(f.readlines())
                     outf.close()
                 if f:
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to