new version of pep-0397 based on python-dev feedback

This commit is contained in:
Mark Hammond 2011-05-17 17:35:44 +10:00
parent 3acd94ec7f
commit 0abda1e625
1 changed files with 180 additions and 112 deletions

View File

@ -7,7 +7,7 @@ Status: Draft
Type: Standards Track Type: Standards Track
Content-Type: text/plain Content-Type: text/plain
Created: 15-Mar-2011 Created: 15-Mar-2011
Post-History: 17-May-2011, 15-Mar-2011
Abstract Abstract
@ -67,8 +67,8 @@ Rationale
An overview of the launcher. An overview of the launcher.
This PEP outlines the general functionality and key guidelines of a This PEP outlines the general functionality and key guidelines of a
launcher for Windows. It is accompanied by reference implementation, launcher for Windows. It is accompanied by a reference implementation
written in Python, which defines the detailed implementation. Over [3], written in Python, which defines the detailed implementation. Over
time, changes to the implementation may be desired - if the changes time, changes to the implementation may be desired - if the changes
adhere to the guidelines in this PEP and have been made following adhere to the guidelines in this PEP and have been made following
the standard Python development model this PEP need not change. the standard Python development model this PEP need not change.
@ -141,16 +141,15 @@ Guidelines for a Python launcher.
feature offered by Unix and would be useful for Windows users in feature offered by Unix and would be useful for Windows users in
some cases. some cases.
The launcher should be capable of supporting implementations other The launcher will be capable of supporting implementations other than
than CPython, such as jython and IronPython. In particular, if there CPython, such as jython and IronPython, but given both the absence of
are common symbolic links used on Unix to specify such an common links on Unix (such as "/usr/bin/jython") and the inability for the
implementation (such as "/usr/bin/jython"), the launcher need not launcher to automatically locate the installation location of these
support such references on Windows. However, if there is strong desire implementations on Windows, the launcher will support this via
from the community to support these other implementations in a Windows customization options. Scripts taking advantage of this will not be
specific way, any such proposals will be judged on their merit. Even portable (as these customization options must be set to reflect the
without specialized support for these alternate implementations, the configuration of the machine on which the launcher is running) but this
ability to specify the fully-qualified path to an executable could be ability is nonetheless considered worthwhile.
used as a fallback.
On Unix, the user can control which specific version of Python is used On Unix, the user can control which specific version of Python is used
by adjusting the links in /usr/bin to point to the desired version. As by adjusting the links in /usr/bin to point to the desired version. As
@ -160,76 +159,155 @@ Guidelines for a Python launcher.
"/usr/bin/python2" will automatically locate a Python 2.x implementation, "/usr/bin/python2" will automatically locate a Python 2.x implementation,
an environment variable can override exactly which Python 2.x an environment variable can override exactly which Python 2.x
implementation will be chosen. Similarly for "/usr/bin/python" and implementation will be chosen. Similarly for "/usr/bin/python" and
"/usr/bin/python3". "/usr/bin/python3". This is specified in detail later in this PEP.
While the guidelines above are general, the launcher should make
concessions for any Windows specific issues which increase the
usefulness of the launcher on Windows. In other words, the
guidelines above will not prevent Windows specific functionality
which makes the launcher significantly more useful for Windows
users.
Shebang line parsing Shebang line parsing
If the first command-line argument does not start with a dash ('-') If the first command-line argument does not start with a dash ('-')
character, an attempt will be made to open that argument as a file character, an attempt will be made to open that argument as a file
and parsed for a shebang line according to the rules in [1]. Once and parsed for a shebang line according to the rules in [1]. Once
parsed, the command will be examined to see if it is a "virtual parsed, the command will be categorized according to the following rules:
command". A virtual command starts with either of the strings
'/usr/bin/python', '/usr/bin/env python' or 'python' - while the
latter will not work on Unix, it will be offered as a convenience
for Windows users not familiar with the Unix conventions and with no
desire to have the shebang line work on Unix.
Commands which are virtual are not treated as containing a file-system * If the command starts with the definition of a customized command
path, but instead are treated as references to an installed Python. followed by a space character, the customized command will be used.
Optionally, the virtual command may include a specific version, such See below for a description of customized commands.
as '/usr/bin/python2' or '/usr/bin/python3.2'. If only a "major version"
qualifier is found, the launcher will enumerate the installed Python
versions and use the latest minor release found for the major version,
which is likely, although not guaranteed, to be the most recently
installed version in that family. If major and minor version qualifiers
are found, that specific version will be located and used.
If a virtual command has no version specifier, or if no shebang line * If the command starts with the strings '/usr/bin/python',
is found, the launcher will attempt to locate a Python 2.x '/usr/bin/env python' or 'python' the command will be treated as a
installation and use the latest found. If none are found, it will 'virtual command' and the rules described in Python Version Qualifiers
attempt to use the latest Python 3.x implementation found. (below) will be used to locate the executable to use.
* Otherwise the command is assumed to be directly ready to execute - ie.
a fully-qualified path optionally followed by arguments. The contents
of the string will not be parsed - it will be passed directly to the
Windows CreateProcess function after appending the name of the script
and the launcher command-line arguments. This means that the rules used
by CreateProcess will be used, including how relative path names and
executable references without extensions are treated. Notably, the
Windows command processor will not be used, so special rules used by the
command processor (such as automatic appending of extensions other than
'.exe', support for batch files, etc) will not be used.
The use of 'virtual' shebang lines will be encouraged as this should The use of 'virtual' shebang lines will be encouraged as this should
allow for portable shebang lines to be specified which work on allow for portable shebang lines to be specified which work on
multiple operating systems. multiple operating systems and different installations of the same
operating system.
If the shebang line is not a virtual one as described above, it is
assumed to be a path to an executable - presumably a Python
executable, but this will not be checked. No version qualifiers are
parsed - if a specific version is required, then the path should
reflect that. Relative path specifications will be considered
relative to the directory of the launcher. Thus, a shebang line of
'#! python' will look for a python executable in the same directory
as the launcher.
Non-virtual shebang lines should be discouraged as they make the
script specific to a specific Windows installation. However, they
are supported for maximum flexibility.
If the first argument can not be opened as a file or if no valid If the first argument can not be opened as a file or if no valid
shebang line can be found, a default Python interpreter will be shebang line can be found, the launcher will act as if a shebang line of
'!#python' was found - ie., a default Python interpreter will be
located and the arguments passed to that. However, if a valid located and the arguments passed to that. However, if a valid
shebang line is found but the process specified by that line can not shebang line is found but the process specified by that line can not
be started, the default interpreter will not be started - the error be started, the default interpreter will not be started - the error
to create the specified child process will be considered fatal and to create the specified child process will cause the launcher to display
the launcher will display an appropriate message and terminate with an appropriate message and terminate with a specific exit code.
a specific exit code.
Virtual commands in shebang lines:
Virtual Commands are shebang lines which start with the strings
'/usr/bin/python', '/usr/bin/env python' or 'python'. Optionally, the
virtual command may be suffixed with a version qualifier (see below),
such as '/usr/bin/python2' or '/usr/bin/python3.2'. The command executed
is based on the rules described in Python Version Qualifiers below.
Customized Commands:
The launcher will support the ability to define "Customized Commands" in a
Windows .ini file (ie, a file which can be parsed by the Windows function
GetPrivateProfileString). A section called '[commands]' can be created
with key names defining the virtual command and the value specifying the
actual command-line to be used for this virtual command.
For example, if an INI file has the contents:
[commands]
vpython=c:\bin\vpython.exe -foo
Then a shebang line of '#! vpython' in a script named 'doit.py' will
result in the launcher using the command-line 'c:\bin\vpython.exe -foo
doit.py'
Two .ini files will be searched by the launcher - 'py.ini' in the
current user's "application data" directory (ie, the directory returned
by calling the Windows function SHGetFolderPath with CSIDL_APPDATA) and
'py.ini' in the same directory as the launcher. Commands specified
in the "application directory" will have precendence over the one next to
the executable, and the same .ini files will be used by both the Windows
and Console versions of the launcher.
Python Version Qualifiers
Some of the features described allow an optional Python version qualifier
to be used.
A version qualifier starts with a major version number and can optionally
be followed by a period ('.') and a minor version specifier. If the minor
qualifier is specified, it may optionally be followed by "-32" to indicate
the 32bit implementation of that version be used. Note that no "-64"
qualifier is necessary as this is the default implementation (see below).
If no version qualifiers are found, the environment variable PY_PYTHON can
be set to specify the default version qualifier - the default value is
"2". Note this value could specify just a major version (eg., "2") or a
major.minor qualifier (eg., "2.6"), or even major.minor-32.
If no minor version qualfiers are found, the environment variable
PY_PYTHON{major} (where {major} is the current major version qualifier
as determined above) can be set to specify the full version. If no such
option is found, the launcher will enumerate the installed Python
versions and use the latest minor release found for the major version,
which is likely, although not guaranteed, to be the most recently
installed version in that family.
On 64bit Windows with both 32bit and 64bit implementations of the On 64bit Windows with both 32bit and 64bit implementations of the
same (major.minor) Python version installed, the 64bit version will same (major.minor) Python version installed, the 64bit version will
always be preferred. This will be true for both 32bit and 64bit always be preferred. This will be true for both 32bit and 64bit
implementations of the launcher - a 32bit launcher will prefer to implementations of the launcher - a 32bit launcher will prefer to
execute a 64bit Python installation of the same version if execute a 64bit Python installation of the specified version if
available. This is so the behavior of the launcher can be predicted available. This is so the behavior of the launcher can be predicted
knowing only what versions are installed on the PC and without knowing only what versions are installed on the PC and without
regard to the order in which they were installed. regard to the order in which they were installed. As noted above, an
optional "-32" suffix can be used on a version specifier to change this
behaviour.
Examples:
* If no relevant options are set, the commands 'python' and
'python2' will use the latest Python 2.x version installed and
the command 'python3' will use the lastest Python 3.x installed.
* The commands 'python3.1' and 'python2.7' will not consult any
options at all as the versions are fully specified.
* if 'PY_PYTHON=3', the commands 'python' and 'python3' will both use
the latest installed Python 3 version.
* if 'PY_PYTHON=3.1-32', the command 'python' will use the 32bit
implementation of 3.1 whereas the command 'python3' will use the latest
installed Python (PY_PYTHON was not considered at all as a major
version was specified.)
* if 'PY_PYTHON=3' and 'PY_PYTHON3=3.1', the commands
'python' and 'python3' will both use specifically 3.1
In addition to environment variables, the same settings can be configured
in the .INI file used by the launcher. The section in the INI file will
be called '[defaults]' and the key name will be the same as the
environment variables without the leading 'PY_' prefix (and note that
the key names in the INI file are case insensitive. The contents of
an environment variable will override things specified in the INI file.
For example:
* Setting 'PY_PYTHON=3.1' is equivilent to the INI file
containing:
[defaults]
python=3.1
* Setting 'PY_PYTHON=3' and 'PY_PYTHON3=3.1' is equivilent to the INI file
containing:
[defaults]
python=3
python3=3.1
Command-line handling Command-line handling
@ -238,25 +316,25 @@ Command-line handling
If the only command-line argument is "-h" or "--help", the launcher will If the only command-line argument is "-h" or "--help", the launcher will
print a small banner and command-line usage, then pass the argument to print a small banner and command-line usage, then pass the argument to
the default Python. This will have the effect of help for the launcher the default Python. This will cause help for the launcher being printed
being printed followed by help for Python itself. The output from the followed by help for Python itself. The output from the launcher will
launcher will attempt to clearly indicate the extended help information attempt to clearly indicate the extended help information is coming from
is coming from the launcher and not Python. the launcher and not Python.
As a concession to interactively launching Python, the launcher will As a concession to interactively launching Python, the launcher will
support the first command-line argument optionally being a version support the first command-line argument optionally being a dash ("-")
specifier in the form "-n[.n][:bits]" (where n is a single integer and followed by a version qualifier, as described above, to nominate a
bits is either '32' or '64') to nominate a specific version be used. For specific version be used. For example, while "py.exe" may locate and
example, while "py.exe" may locate and launch the latest Python 2.x launch the latest Python 2.x implementation installed, a command-line such
implementation installed, a command-line such as "py.exe -3" could specify as "py.exe -3" could specify the latest Python 3.x implementation be
the latest Python 3.x implementation be launched, while "py.exe -2.6:32" launched, while "py.exe -2.6-32" could specify a 32bit implementation
could specify a 32bit implementation Python 2.6 be located and launched. Python 2.6 be located and launched. If a Python 2.x implementation is
If a Python 2.x implementation is desired to be launched with the -3 flag, desired to be launched with the -3 flag, the command-line would need to be
the command-line would need to be similar to "py.exe -2 -3" (or the similar to "py.exe -2 -3" (or the specific version of Python could
specific version of Python could obviously be launched manually without obviously be launched manually without use of this launcher.) Note that
use of this launcher.) Note that this feature can not be used with shebang this feature can not be used with shebang processing as the file scanned
processing as the file scanned for a shebang line and this argument must for a shebang line and this argument must both be the first argument and
both be the first argument and therefore are mutually exclusive. therefore are mutually exclusive.
All other arguments will be passed untouched to the child Python process. All other arguments will be passed untouched to the child Python process.
@ -275,44 +353,32 @@ Process Launching
side effect of this is that the value of sys.executable would refer to the side effect of this is that the value of sys.executable would refer to the
launcher instead of the Python implementation. Many Python scripts use the launcher instead of the Python implementation. Many Python scripts use the
value of sys.executable to launch child processes, and these scripts may value of sys.executable to launch child processes, and these scripts may
fail to work as expected if the launcher is used - consider a "parent" fail to work as expected if the launcher is used. Consider a "parent"
script with a shebang line of '#! /usr/bin/python3' which attempts to script with a shebang line of '#! /usr/bin/python3' which attempts to
launch a child script with no shebang line at all. Currently that launch a child script (with no shebang) via sys.executable - currently the
child script would be launched using the exact same version running child is launched using the exact same version running the parent script.
the parent script, but if sys.executable referred to the launcher the If sys.executable referred to the launcher the child would be likely
child would be likely executed using a Python 2.x version and would be executed using a Python 2.x version and would be likely to fail with a
likely to fail with a SyntaxError. A solution for this would need to be SyntaxError. A solution for this would need to be found before this could
found before this could be considered. be considered.
The rules mentioned above regarding 64bit and 32bit programs would also be Another hurdle is the support for alternative Python implementations
rendered impossible with this 'in-process' model - a 32bit launcher would using the "customized commands" feature described above, where loading
be unable to load the 64bit version of Python and vice-versa. the command dynamically into a running executable is not possible.
Given the impossibility of supporting the 64bit and 32bit requirements The final hurdle is the rules above regarding 64bit and 32bit programs -
above, the launcher will execute Python in a child process, remaining a 32bit launcher would be unable to load the 64bit version of Python and
alive while the child process is executing, then terminate with the same vice-versa.
exit code as returned by the child.
To address the concerns regarding the termination of the launcher not Given these considerations, the launcher will execute it's command in a
killing the child, the Win32 Job API will be used to arrange so that the child process, remaining alive while the child process is executing, then
child process is automatically killed when the parent is terminated terminate with the same exit code as returned by the child. To address the
(although children of that child process will continue as is the case concerns regarding the termination of the launcher not killing the child,
now.) However, that functionality only works on Windows XP and later, so the Win32 Job API will be used to arrange so that the child process is
the launcher running on the Windows 2000 platform will not have this automatically killed when the parent is terminated (although children of
feature - killing the launcher on that platform will keep the child that child process will continue as is the case now.) As this Windows API
process alive. This feature has been implemented in the reference is available in Windows XP and later, this launcher will not work on
implementation. Windows 2000 or earlier.
Alternative implementations and distributions of Python.
While this PEP is primarily concerned with the python.org distributions of
CPython, it does not preclude future enhancements to support both
different distributions of CPython (eg. ActivePython, Enthought), nor
different implementations of Python (eg. jython, IronPython.)
Enhancements to support these alternatives should be proposed by
(community or corporate) representatives of these alternatives and
addressed via the normal Python development process and after relevant
patches have been submitted for the reference implementation.
References References
@ -320,6 +386,8 @@ References
[2] http://www.python.org/dev/peps/pep-0394/ [2] http://www.python.org/dev/peps/pep-0394/
[3] http://bugs.python.org/issue11629
Copyright Copyright
This document has been placed in the public domain. This document has been placed in the public domain.