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