On 3/8/2011 9:06 PM, Mark Hammond wrote:
On 9/03/2011 1:43 PM, Glenn Linderman wrote:
I'm of the opinion that attempting to parse a Unix #! line, and intuit
what would be the equivalent on Windows is unnecessarily complex and
error prone, and assumes that the variant systems are configured using
the same guidelines (which the Python community may espouse, but may not
be followed by all distributions, sysadmins, or users). That's why I
propose a different line for Windows... it is as simple as the
long-proven Unix #! line, but imposes no restrictions on or requirements
that there be a #! line; it has more flexibility in that it could invoke
different versions or provide different options on Unix and Windows if
necessary for some environments.

#!/usr/bin/env python2.6 -B
#@c:\python26\python2.6.exe

or

#!/usr/bin/python2.5
#@"C:\Program Files (x86)\IronPython 2.6 for .NET 4.0\ipy.exe"

I don't think that buys us much.  A script with "#!/usr/bin/env python" could be distributed with an expectation it will work across various different machines (and possibly even different operating systems).  A script with "c:\..." could not be distributed and expected to work reliably anywhere.  ie, any script with a #! line (or even a #@ line) with a fully qualified Windows path can only be expected to work on a single machine - so there is no need to support both #! and #@ as the script is not even cross-machine portable, let alone cross-platform portable.

Standard installation paths are accepted by about 99% of the users, so embedding standard installation paths can work well for that batch of users.  Of course, Windows changes the standard path periodically, so that it different from versions prior to and including WinXP versus versions after WinXP.  And they had no standard before WinNT (or if they did, few followed it).  Your comment does point out a possible need for multiple standard installation paths just for different versions of Windows, though :(

Also, corporate environments are generally quite standardized, so scripts developed within and for a corporation (or modified for use within a corporation) could quite successfully use such.

You do make a good point, though, that Unix-based environments have more standardization in their diversity than Windows does.  Back when I wrote Unix code, though, there were plenty of system utility programs that had different default paths on different Unix platforms.  /usr/bin/env can cover some of that, but is also somewhat of a security hole.


The only way to expect a #! line to work across machines would be to have a "virtual" path - eg just "python2.6" without any path specifier at all.  In that case, I see no problem with reusing the #! from *nix systems and treating "/usr/bin" etc as a "virtual" specifier on Windows.  If people find a need on Windows to add a fully-qualified path to this line (whatever the spelling), they are implicitly saying this script works only on the current machine.

IOW, as soon as someone has:

#!/usr/bin/env python2.6 -B
#@c:\python26\python2.6.exe

in their script, the script is targeted at exactly 1 specific machine, so why not just reuse the #! syntax?  OTOH, if an existing script has:

#!/usr/bin/env python2.6 -B

They are attempting to declare in a portable way that Python 2.6 is necessary - so why force them to add a #@ line to make it work on Windows when the #! line is the only clue Windows needs to make it work automagically?

Your premise that using a standard installation path in #@ restricts the script to be targeted to one machine is fallacious, so the conclusions are also.  You also missed the fact that the -B parameter was deemed necessary in the above for the Unix machine(s) of interest, but not needed for Windows, which a single line cannot impart (although that is an admittedly contrived example of potentially different option syntax).  And the use of  cpython on Unix and IronPython on Windows may be appropriate for some corporate environments.  A lot of the Unix discussion mentioned things like "curable by the sysadmin" like in regards to the links... a sysadmin implies a corporate environment, and a locked-down path structure.

Of course, /usr/bin/env  is already a "launcher" type facility, specific to Unix, to mask variations between systems, and to overcome the fact that Unix itself will not walk the PATH to find a non-fully-qualified name.

The #! line is clearly is NOT "the only clue Windows needs to make it work automagically" or we wouldn't be having this discussion at all.  And it is not at all clear if a Windows machine contains Jython, IronPython, and Cython which one should be launched by a launcher.  You could, of course, argue that python-dev is only concerned with CPython, and the launcher can be specific to CPython, and that argument might carry the day, but the CPython registry lookup necessary to make that happen doesn't help the users of alternate implementations a bit, forcing each of them to implement their own launcher as well... or have they already solved this problem some other way that has not been brought to this discussion?  I downloaded/installed IronPython today to get the above path to it, but I didn't find any decent documentation for it to learn this sort of thing... a book reference seemed to claim the most comprehensive documentation, but I'm not going to buy a book just to learn that they haven't solved this issue, even if Michael Foord is one of the authors!

Of course if appropriate versioned python executables were placed on the Windows path, then an exact corollary to /usr/bin/env could be used on Windows, also... but there would still be the question of whether to use  python2.6.exe or ipy2.6.exe, perhaps.  And then there is the "w" issue, too.

#!/usr/bin/env python2.6
#@"C:\Program Files\Env.exe" ipy2.6.3.exe

in .py files and

#!/usr/bin/env python2.6
#@"C:\Program Files\Env.exe" ipy2.6.3w.exe

in .pyw files.

I have scripts that I run on my web server using

#!/usr/bin/python2.6

because they only have that and /usr/bin/python which is 2.4.2.  But I want to run them locally for testing with (infrequently) Windows cpython 2.6 and (mostly) Windows cpython 3.2, to prove that they will (yes, certain common functions check sys.version to determine how to do things).  So using the Unix #! line certainly doesn't work for that case.  If I can have only one default, I would want it to be 3.2 locally, and 2.6 on the server, and to manually override something to run 2.6 locally.  Yet all my Pythons are installed in the standard installation directory, and still your Unix hack won't let me do what I need.

So no matter what is done, it won't solve world hunger.  Probably that's why Windows users have been left high and dry for years in this regard... there is no "system" Python on it, out of the box, so the only users are those that are smart enough to download and install and configure things, and those who use a Python embedded into an application, at the cost of a Python installation per application, because there has been no "system" Python, and because Windows users are not perceived to be capable of, or willing to bother with, downloading and installing various requisite dependencies.

The resulting vacuum has been filled by people with different points of view, because there has been no technique implemented, none declared to be "best", and anarchy and variant workarounds have abounded.