Python Scripts on Windows
=========================

zetuptoolz can install Python scripts in such a way that they can be
run from a Windows Command Prompt, a Cygwin shell, or a Windows shortcut.
It implements this in a different way to setuptools (which used .exe
wrappers as described at
<http://svn.python.org/projects/sandbox/trunk/setuptools/setuptools/tests/win_script_wrapper.txt>).

There are two kinds of scripts -- command-line and graphical.
Command-line scripts have a .pyscript extension, which should be
associated with python.exe. Graphical scripts have a .pyw extension,
which should be associated with pythonw.exe. The .pyscript and .pyw
extensions should be listed in the PATHEXT environment variable.

The reason for introducing a new .pyscript extension is to work around
a problem with naming conflicts between modules and scripts. When Python
runs a script file, it adds the parent directory of that file to the
start of the sys.path. So any scripts in that directory that have the
same name as a module, will shadow the module and be imported in
preference to it. This would particularly be a problem when running scripts
installed to <pythondir>\Scripts. Using a .pyscript extension still
allows the script to be run, but prevents it from being unintentionally
imported.

First let's install zetuptoolz (we could also just build it):

    C:\> cd path\to\zetuptoolz

    C:\path\to\zetuptoolz> python setup.py install
    ...
    Setting up environment to run scripts...
    Done: associate the .pyscript extension with Python.File.
    Done: add .pyscript to the user environment variable PATHEXT.
    Done: add .pyw to the user environment variable PATHEXT.

    Changes have been made to the persistent environment, but not
    in this Command Prompt. Running installed Python scripts will
    only work from new Command Prompts opened from now on.

If you had built or installed it or a previous version (since 0.6c16dev)
before, this would have said something like:

    Setting up environment to run scripts...
    Already done: associate the .pyscript extension with Python.File.
    Already done: add .pyscript to the user environment variable PATHEXT.
    Already done: add .pyw to the user environment variable PATHEXT.

(In fact zetuptoolz will re-check that the .pyscript association and
PATHEXT variable are set up correctly when you build or install *any*
distribution with it.)

A zetuptoolz-created command-line script -- say mycmd.pyscript -- typically
looks something like this:

    #!c:\Python26\python.exe
    # EASY-INSTALL-ENTRY-SCRIPT: 'application==1.0','console_scripts','mycmd'
    # generated by zetuptoolz 0.6c16dev
    __requires__ = 'application==1.0'
    import sys, site
    from pkg_resources import load_entry_point

    # If this script doesn't work for you, make sure that the .pyscript
    # extension is included in the PATHEXT environment variable, and is
    # associated with python.exe in the registry.

    if sys.argv[0].endswith('.pyscript'):
        sys.argv[0] = sys.argv[0][:-9]

    sys.exit(
      load_entry_point('application==1.0', 'console_scripts', 'mycmd')()
    )

(The Unix-style '#!' line isn't really necessary; in fact it will be
ignored if we run this from a Command Prompt, although it may help if the
user is using a Unix-style shell.)

Suppose that 'mycmd' just prints out sys.argv. In that case, if we run it
we'll get:

    C:\> mycmd.pyscript arg1 "arg 2" "arg \"2\\\"" "arg 4\" "still4 arg5\b"
    ['arg1', 'arg 2', 'arg "2\\"', 'arg 4" still4', 'arg5\\b']

Omitting the .pyscript extension has the same effect:

    C:\> mycmd arg1 "arg 2" "arg \"2\\\"" "arg 4\" "still4 arg5\b"
    ['arg1', 'arg 2', 'arg "2\\"', 'arg 4" still4', 'arg5\\b']

Note that the arguments are parsed only by cmd.exe, ensuring exact
compatibility with Windows quoting conventions.

Unicode arguments to the script are preserved. However, they cannot be read
from sys.argv due to <http://bugs.python.org/issue2128> (a workaround is
given there).

GUI scripts work in an identical way, but use the .pyw extension and are
associated with pythonw.exe.


Cygwin shell
------------

When running a script from the Windows Command Prompt, or other Windows
shells that honour PATHEXT, the .pyscript wrapper is sufficient. However,
the Cygwin bash shell does not honour PATHEXT.

So that Cygwin shell users do not have to type the .pyscript extension,
we also write a shell script (with no extension and a "#!/bin/sh" shebang
line) alongside the .pyscript file. This script invokes the Python interpreter
(normally the one that ran easy_install, or "python.exe" in the case of a
cross-installation for a Windows target), giving the .pyscript name and
passing on its own arguments.
