From 835416cf7caff0d397c10b98eb146372d6d6dfd0 Mon Sep 17 00:00:00 2001
From: Paul Moore
Date: Sun, 22 May 2016 12:28:41 +0100
Subject: [PATCH] Issue #27064: The py.exe launcher now defaults to Python 3.
The Windows launcher ``py.exe`` no longer prefers an installed Python 2
version over Python 3 by default when used interactively.
---
Doc/using/windows.rst | 22 +++++++++++++++-------
Doc/whatsnew/3.6.rst | 9 +++++++++
Misc/NEWS | 7 +++++++
PC/launcher.c | 21 ++++++++++++++-------
4 files changed, 45 insertions(+), 14 deletions(-)
diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst
index 7520d608463..2399278752d 100644
--- a/Doc/using/windows.rst
+++ b/Doc/using/windows.rst
@@ -418,6 +418,8 @@ Getting started
From the command-line
^^^^^^^^^^^^^^^^^^^^^
+.. versionchanged:: 3.6
+
System-wide installations of Python 3.3 and later will put the launcher on your
:envvar:`PATH`. The launcher is compatible with all available versions of
Python, so it does not matter which version is installed. To check that the
@@ -427,25 +429,26 @@ launcher is available, execute the following command in Command Prompt:
py
-You should find that the latest version of Python 2.x you have installed is
+You should find that the latest version of Python you have installed is
started - it can be exited as normal, and any additional command-line
arguments specified will be sent directly to Python.
-If you have multiple versions of Python 2.x installed (e.g., 2.6 and 2.7) you
-will have noticed that Python 2.7 was started - to launch Python 2.6, try the
+If you have multiple versions of Python installed (e.g., 2.7 and 3.6) you
+will have noticed that Python 3.6 was started - to launch Python 2.7, try the
command:
::
- py -2.6
+ py -2.7
-If you have a Python 3.x installed, try the command:
+If you want the latest version of Python 2.x you have installed, try the
+command:
::
- py -3
+ py -2
-You should find the latest version of Python 3.x starts.
+You should find the latest version of Python 2.x starts.
If you see the following error, you do not have the launcher installed:
@@ -500,6 +503,11 @@ version qualifier. Assuming you have Python 2.6 installed, try changing the
first line to ``#! python2.6`` and you should find the 2.6 version
information printed.
+Note that unlike interactive use, a bare "python" will use the latest
+version of Python 2.x that you have installed. This is for backward
+compatibility and for compatibility with Unix, where the command ``python``
+typically refers to Python 2.
+
From file associations
^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst
index 2ec8f004b26..f829e4a9175 100644
--- a/Doc/whatsnew/3.6.rst
+++ b/Doc/whatsnew/3.6.rst
@@ -62,8 +62,17 @@ Summary -- Release highlights
.. This section singles out the most important changes in Python 3.6.
Brevity is key.
+New syntax features:
+
* PEP 498: :ref:`Formatted string literals `
+Windows improvements:
+
+* The ``py.exe`` launcher, when used interactively, no longer prefers
+ Python 2 over Python 3 when the user doesn't specify a version (via
+ command line arguments or a config file). Handling of shebang lines
+ remains unchanged - "python" refers to Python 2 in that case.
+
.. PEP-sized items next.
.. _pep-4XX:
diff --git a/Misc/NEWS b/Misc/NEWS
index 363454df140..b7d96075f40 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -32,6 +32,13 @@ Tests
- Issue #25285: Tools/buildbot/test.bat script now uses -j1 by default to run
each test file in fresh child process.
+Windows
+-------
+
+- Issue #27064: The py.exe launcher now defaults to Python 3.
+ The Windows launcher ``py.exe`` no longer prefers an installed
+ Python 2 version over Python 3 by default when used interactively.
+
What's New in Python 3.6.0 alpha 1?
===================================
diff --git a/PC/launcher.c b/PC/launcher.c
index e5f2cea610d..e4d3e8e0955 100644
--- a/PC/launcher.c
+++ b/PC/launcher.c
@@ -465,7 +465,7 @@ get_configured_value(wchar_t * key)
}
static INSTALLED_PYTHON *
-locate_python(wchar_t * wanted_ver)
+locate_python(wchar_t * wanted_ver, BOOL from_shebang)
{
static wchar_t config_key [] = { L"pythonX" };
static wchar_t * last_char = &config_key[sizeof(config_key) /
@@ -497,10 +497,17 @@ locate_python(wchar_t * wanted_ver)
configured_value = get_configured_value(config_key);
if (configured_value)
result = find_python_by_version(configured_value);
+ /* Not found a value yet - try by major version.
+ * If we're looking for an interpreter specified in a shebang line,
+ * we want to try Python 2 first, then Python 3 (for Unix and backward
+ * compatibility). If we're being called interactively, assume the user
+ * wants the latest version available, so try Python 3 first, then
+ * Python 2.
+ */
if (result == NULL)
- result = find_python_by_version(L"2");
+ result = find_python_by_version(from_shebang ? L"2" : L"3");
if (result == NULL)
- result = find_python_by_version(L"3");
+ result = find_python_by_version(from_shebang ? L"3" : L"2");
debug(L"search for default Python found ");
if (result) {
debug(L"version %ls at '%ls'\n",
@@ -1094,7 +1101,7 @@ find_by_magic(unsigned short magic)
for (mp = magic_values; mp->min; mp++) {
if ((magic >= mp->min) && (magic <= mp->max)) {
- result = locate_python(mp->version);
+ result = locate_python(mp->version, FALSE);
if (result != NULL)
break;
}
@@ -1279,7 +1286,7 @@ specification: '%ls'.\nIn the first line of the script, 'python' needs to be \
followed by a valid version specifier.\nPlease check the documentation.",
command);
/* TODO could call validate_version(command) */
- ip = locate_python(command);
+ ip = locate_python(command, TRUE);
if (ip == NULL) {
error(RC_NO_PYTHON, L"Requested Python version \
(%ls) is not installed", command);
@@ -1485,7 +1492,7 @@ process(int argc, wchar_t ** argv)
plen = wcslen(p);
valid = (*p == L'-') && validate_version(&p[1]);
if (valid) {
- ip = locate_python(&p[1]);
+ ip = locate_python(&p[1], FALSE);
if (ip == NULL)
error(RC_NO_PYTHON, L"Requested Python version (%ls) not \
installed", &p[1]);
@@ -1512,7 +1519,7 @@ installed", &p[1]);
/* If we didn't find one, look for the default Python */
if (executable == NULL) {
- ip = locate_python(L"");
+ ip = locate_python(L"", FALSE);
if (ip == NULL)
error(RC_NO_PYTHON, L"Can't find a default Python.");
executable = ip->executable;