1 | Python Scripts on Windows |
---|
2 | ========================= |
---|
3 | |
---|
4 | zetuptoolz can install Python scripts in such a way that they can be |
---|
5 | run from a Windows Command Prompt, a Cygwin shell, or a Windows shortcut. |
---|
6 | It implements this in a different way to setuptools (which used .exe |
---|
7 | wrappers as described at |
---|
8 | <http://svn.python.org/projects/sandbox/trunk/setuptools/setuptools/tests/win_script_wrapper.txt>). |
---|
9 | |
---|
10 | There are two kinds of scripts -- command-line and graphical. |
---|
11 | Command-line scripts have a .pyscript extension, which should be |
---|
12 | associated with python.exe. Graphical scripts have a .pyw extension, |
---|
13 | which should be associated with pythonw.exe. The .pyscript and .pyw |
---|
14 | extensions should be listed in the PATHEXT environment variable. |
---|
15 | |
---|
16 | The reason for introducing a new .pyscript extension is to work around |
---|
17 | a problem with naming conflicts between modules and scripts. When Python |
---|
18 | runs a script file, it adds the parent directory of that file to the |
---|
19 | start of the sys.path. So any scripts in that directory that have the |
---|
20 | same name as a module, will shadow the module and be imported in |
---|
21 | preference to it. This would particularly be a problem when running scripts |
---|
22 | installed to <pythondir>\Scripts. Using a .pyscript extension still |
---|
23 | allows the script to be run, but prevents it from being unintentionally |
---|
24 | imported. |
---|
25 | |
---|
26 | First let's install zetuptoolz (we could also just build it): |
---|
27 | |
---|
28 | C:\> cd path\to\zetuptoolz |
---|
29 | |
---|
30 | C:\path\to\zetuptoolz> python setup.py install |
---|
31 | ... |
---|
32 | Setting up environment to run scripts... |
---|
33 | Done: associate the .pyscript extension with Python.File. |
---|
34 | Done: add .pyscript to the user environment variable PATHEXT. |
---|
35 | Done: add .pyw to the user environment variable PATHEXT. |
---|
36 | |
---|
37 | Changes have been made to the persistent environment, but not |
---|
38 | in this Command Prompt. Running installed Python scripts will |
---|
39 | only work from new Command Prompts opened from now on. |
---|
40 | |
---|
41 | If you had built or installed it or a previous version (since 0.6c16dev) |
---|
42 | before, this would have said something like: |
---|
43 | |
---|
44 | Setting up environment to run scripts... |
---|
45 | Already done: associate the .pyscript extension with Python.File. |
---|
46 | Already done: add .pyscript to the user environment variable PATHEXT. |
---|
47 | Already done: add .pyw to the user environment variable PATHEXT. |
---|
48 | |
---|
49 | (In fact zetuptoolz will re-check that the .pyscript association and |
---|
50 | PATHEXT variable are set up correctly when you build or install *any* |
---|
51 | distribution with it.) |
---|
52 | |
---|
53 | A zetuptoolz-created command-line script -- say mycmd.pyscript -- typically |
---|
54 | looks something like this: |
---|
55 | |
---|
56 | #!c:\Python26\python.exe |
---|
57 | # EASY-INSTALL-ENTRY-SCRIPT: 'application==1.0','console_scripts','mycmd' |
---|
58 | # generated by zetuptoolz 0.6c16dev |
---|
59 | __requires__ = 'application==1.0' |
---|
60 | import sys, site |
---|
61 | from pkg_resources import load_entry_point |
---|
62 | |
---|
63 | # If this script doesn't work for you, make sure that the .pyscript |
---|
64 | # extension is included in the PATHEXT environment variable, and is |
---|
65 | # associated with python.exe in the registry. |
---|
66 | |
---|
67 | if sys.argv[0].endswith('.pyscript'): |
---|
68 | sys.argv[0] = sys.argv[0][:-9] |
---|
69 | |
---|
70 | sys.exit( |
---|
71 | load_entry_point('application==1.0', 'console_scripts', 'mycmd')() |
---|
72 | ) |
---|
73 | |
---|
74 | (The Unix-style '#!' line isn't really necessary; in fact it will be |
---|
75 | ignored if we run this from a Command Prompt, although it may help if the |
---|
76 | user is using a Unix-style shell.) |
---|
77 | |
---|
78 | Suppose that 'mycmd' just prints out sys.argv. In that case, if we run it |
---|
79 | we'll get: |
---|
80 | |
---|
81 | C:\> mycmd.pyscript arg1 "arg 2" "arg \"2\\\"" "arg 4\" "still4 arg5\b" |
---|
82 | ['arg1', 'arg 2', 'arg "2\\"', 'arg 4" still4', 'arg5\\b'] |
---|
83 | |
---|
84 | Omitting the .pyscript extension has the same effect: |
---|
85 | |
---|
86 | C:\> mycmd arg1 "arg 2" "arg \"2\\\"" "arg 4\" "still4 arg5\b" |
---|
87 | ['arg1', 'arg 2', 'arg "2\\"', 'arg 4" still4', 'arg5\\b'] |
---|
88 | |
---|
89 | Note that the arguments are parsed only by cmd.exe, ensuring exact |
---|
90 | compatibility with Windows quoting conventions. |
---|
91 | |
---|
92 | Unicode arguments to the script are preserved. However, they cannot be read |
---|
93 | from sys.argv due to <http://bugs.python.org/issue2128> (a workaround is |
---|
94 | given there). |
---|
95 | |
---|
96 | GUI scripts work in an identical way, but use the .pyw extension and are |
---|
97 | associated with pythonw.exe. |
---|
98 | |
---|
99 | |
---|
100 | Cygwin shell |
---|
101 | ------------ |
---|
102 | |
---|
103 | When running a script from the Windows Command Prompt, or other Windows |
---|
104 | shells that honour PATHEXT, the .pyscript wrapper is sufficient. However, |
---|
105 | the Cygwin bash shell does not honour PATHEXT. |
---|
106 | |
---|
107 | So that Cygwin shell users do not have to type the .pyscript extension, |
---|
108 | we also write a shell script (with no extension and a "#!/bin/sh" shebang |
---|
109 | line) alongside the .pyscript file. This script invokes the Python interpreter |
---|
110 | (normally the one that ran easy_install, or "python.exe" in the case of a |
---|
111 | cross-installation for a Windows target), giving the .pyscript name and |
---|
112 | passing on its own arguments. |
---|