summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve (Gadget) Barnes <gadgetsteve@hotmail.com>2017-06-28 19:14:52 (GMT)
committerSteve Dower <steve.dower@microsoft.com>2017-06-28 19:14:52 (GMT)
commit5b8f972e093157cc55185841db9ad33fa332a641 (patch)
treee68e5f66ae6fc02c08599f4facf9cf9fdf829b1a
parentb01c574ad6d796025152b5d605eceb7816e6f7a7 (diff)
downloadcpython-5b8f972e093157cc55185841db9ad33fa332a641.zip
cpython-5b8f972e093157cc55185841db9ad33fa332a641.tar.gz
cpython-5b8f972e093157cc55185841db9ad33fa332a641.tar.bz2
bpo-30362 : Add list options to launcher. (#1578)
* bpo-30362 Add list options to launcher. * bpo-30362 Add list options to help message. * To avoid possible later conflict with python replaced flags with --launcher-list and --launcher-list-paths * bpo-30362 Changed flag to -0 as suggested on review. * bpo-30362: Modified to default to not path for -0, -0p to dispaly path and append * to default * bpo-30362: Modified to display list on required version not found. * bpo-30362 add --list and --list-paths added back in following review by paul.moore * bpo-30362 Cleaner handing of -0 & -0p by not calling exit directly per review by @zooba * bpo-30362: Tidy up and add news & what's new Removed commented out line of code in PC/launcher.c. Added the results of using blurb to add details of bpo-30362 & bpo-30291. Updated Doc/whatsnew/3.7.rst to add a Windows only section covering both tickets. * bpo-30362 Resolve conflict in Doc/whatsnew/3.7.rst * bpo-30362:Address Whitespace Issue in Doc\whatsnew\3.7.rst * Shorten NEWS message for bpo-30362 * Shorten NEWS item for bpo-30291
-rw-r--r--Doc/whatsnew/3.7.rst15
-rw-r--r--Misc/NEWS.d/next/Windows/2017-06-28-03-08-22.bpo-30362.XxeVMB.rst1
-rw-r--r--Misc/NEWS.d/next/Windows/2017-06-28-03-20-48.bpo-30291.zBpOl6.rst2
-rw-r--r--PC/launcher.c158
4 files changed, 133 insertions, 43 deletions
diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst
index e34268e..c75d769 100644
--- a/Doc/whatsnew/3.7.rst
+++ b/Doc/whatsnew/3.7.rst
@@ -365,6 +365,21 @@ Changes in the C API
characters. (Contributed by Serhiy Storchaka in :issue:`30708`.)
+Windows Only
+------------
+- The python launcher, (py.exe), can accept 32 & 64 bit specifiers **without**
+ having to specify a minor version as well. So ``py -3-32`` and ``py -3-64``
+ become valid as well as ``py -3.7-32``, also the -*m*-64 and -*m.n*-64 forms
+ are now accepted to force 64 bit python even if 32 bit would have otherwise
+ been used. If the specified version is not available py.exe will error exit.
+ (Contributed by Steve Barnes in :issue:`30291`.)
+
+- The launcher can be run as "py -0" to produce a list of the installed pythons,
+ *with default marked with an asterix*. Running "py -0p" will include the paths.
+ If py is run with a version specifier that cannot be matched it will also print
+ the *short form* list of available specifiers.
+ (Contributed by Steve Barnes in :issue:`30362`.)
+
Removed
=======
diff --git a/Misc/NEWS.d/next/Windows/2017-06-28-03-08-22.bpo-30362.XxeVMB.rst b/Misc/NEWS.d/next/Windows/2017-06-28-03-08-22.bpo-30362.XxeVMB.rst
new file mode 100644
index 0000000..fb24ec5
--- /dev/null
+++ b/Misc/NEWS.d/next/Windows/2017-06-28-03-08-22.bpo-30362.XxeVMB.rst
@@ -0,0 +1 @@
+Adds list options (-0, -0p) to py.exe launcher. Contributed by Steve Barnes.
diff --git a/Misc/NEWS.d/next/Windows/2017-06-28-03-20-48.bpo-30291.zBpOl6.rst b/Misc/NEWS.d/next/Windows/2017-06-28-03-20-48.bpo-30291.zBpOl6.rst
new file mode 100644
index 0000000..2869823
--- /dev/null
+++ b/Misc/NEWS.d/next/Windows/2017-06-28-03-20-48.bpo-30291.zBpOl6.rst
@@ -0,0 +1,2 @@
+Allow requiring 64-bit interpreters from py.exe using -64 suffix. Contributed
+by Steve (Gadget) Barnes.
diff --git a/PC/launcher.c b/PC/launcher.c
index 25fa4ca..0733df7 100644
--- a/PC/launcher.c
+++ b/PC/launcher.c
@@ -1371,6 +1371,89 @@ get_version_info(wchar_t * version_text, size_t size)
}
}
+static void
+show_help_text(wchar_t ** argv)
+{
+ wchar_t version_text [MAX_PATH];
+#if defined(_M_X64)
+ BOOL canDo64bit = TRUE;
+#else
+ /* If we are a 32bit process on a 64bit Windows, first hit the 64bit keys. */
+ BOOL canDo64bit = FALSE;
+ IsWow64Process(GetCurrentProcess(), &canDo64bit);
+#endif
+
+ get_version_info(version_text, MAX_PATH);
+ fwprintf(stdout, L"\
+Python Launcher for Windows Version %ls\n\n", version_text);
+ fwprintf(stdout, L"\
+usage:\n\
+%ls [launcher-args] [python-args] script [script-args]\n\n", argv[0]);
+ fputws(L"\
+Launcher arguments:\n\n\
+-2 : Launch the latest Python 2.x version\n\
+-3 : Launch the latest Python 3.x version\n\
+-X.Y : Launch the specified Python version\n", stdout);
+ if (canDo64bit) {
+ fputws(L"\
+ The above all default to 64 bit if a matching 64 bit python is present.\n\
+-X.Y-32: Launch the specified 32bit Python version\n\
+-X-32 : Launch the latest 32bit Python X version\n\
+-X.Y-64: Launch the specified 64bit Python version\n\
+-X-64 : Launch the latest 64bit Python X version", stdout);
+ }
+ fputws(L"\n-0 --list : List the available pythons", stdout);
+ fputws(L"\n-0p --list-paths : List with paths", stdout);
+ fputws(L"\n\nThe following help text is from Python:\n\n", stdout);
+ fflush(stdout);
+}
+
+static BOOL
+show_python_list(wchar_t ** argv)
+{
+ /*
+ * Display options -0
+ */
+ INSTALLED_PYTHON * result = NULL;
+ INSTALLED_PYTHON * ip = installed_pythons; /* List of installed pythons */
+ INSTALLED_PYTHON * defpy = locate_python(L"", FALSE);
+ size_t i = 0;
+ wchar_t *p = argv[1];
+ wchar_t *fmt = L"\n -%ls-%d"; /* print VER-BITS */
+ wchar_t *defind = L" *"; /* Default indicator */
+
+ /*
+ * Output informational messages to stderr to keep output
+ * clean for use in pipes, etc.
+ */
+ fwprintf(stderr,
+ L"Installed Pythons found by %s Launcher for Windows", argv[0]);
+ if (!_wcsicmp(p, L"-0p") || !_wcsicmp(p, L"--list-paths")) /* Show path? */
+ fmt = L"\n -%ls-%d\t%ls"; /* print VER-BITS path */
+
+ if (num_installed_pythons == 0) /* We have somehow got here without searching for pythons */
+ locate_all_pythons(); /* Find them, Populates installed_pythons */
+
+ if (num_installed_pythons == 0) /* No pythons found */
+ fwprintf(stderr, L"\nNo Installed Pythons Found!");
+ else
+ {
+ for (i = 0; i < num_installed_pythons; i++, ip++) {
+ fwprintf(stdout, fmt, ip->version, ip->bits, ip->executable);
+ /* If there is a default indicate it */
+ if ((defpy != NULL) && !_wcsicmp(ip->executable, defpy->executable))
+ fwprintf(stderr, defind);
+ }
+ }
+
+ if ((defpy == NULL) && (num_installed_pythons > 0))
+ /* We have pythons but none is the default */
+ fwprintf(stderr, L"\n\nCan't find a Default Python.\n\n");
+ else
+ fwprintf(stderr, L"\n\n"); /* End with a blank line */
+ return(FALSE); /* If this has been called we cannot continue */
+}
+
static int
process(int argc, wchar_t ** argv)
{
@@ -1380,12 +1463,12 @@ process(int argc, wchar_t ** argv)
wchar_t * p;
int rc = 0;
size_t plen;
+ size_t slen;
INSTALLED_PYTHON * ip;
BOOL valid;
DWORD size, attrs;
HRESULT hr;
wchar_t message[MSGSIZE];
- wchar_t version_text [MAX_PATH];
void * version_data;
VS_FIXEDFILEINFO * file_info;
UINT block_size;
@@ -1516,12 +1599,22 @@ process(int argc, wchar_t ** argv)
else {
p = argv[1];
plen = wcslen(p);
- valid = (*p == L'-') && validate_version(&p[1]);
+ if (argc == 2) {
+ slen = wcslen(L"-0");
+ if(!wcsncmp(p, L"-0", slen)) /* Starts with -0 */
+ valid = show_python_list(argv); /* Check for -0 FIRST */
+ }
+ valid = valid && (*p == L'-') && validate_version(&p[1]);
if (valid) {
ip = locate_python(&p[1], FALSE);
if (ip == NULL)
+ {
+ fwprintf(stdout, \
+ L"Python %ls not found!\n", &p[1]);
+ valid = show_python_list(argv);
error(RC_NO_PYTHON, L"Requested Python version (%ls) not \
-installed", &p[1]);
+installed, use -0 for available pythons", &p[1]);
+ }
executable = ip->executable;
command += wcslen(p);
command = skip_whitespace(command);
@@ -1540,49 +1633,28 @@ installed", &p[1]);
#endif
if (!valid) {
- /* Look for an active virtualenv */
- executable = find_python_by_venv();
-
- /* If we didn't find one, look for the default Python */
- if (executable == NULL) {
- ip = locate_python(L"", FALSE);
- if (ip == NULL)
- error(RC_NO_PYTHON, L"Can't find a default Python.");
- executable = ip->executable;
- }
- if ((argc == 2) && (!_wcsicmp(p, L"-h") || !_wcsicmp(p, L"--help"))) {
-#if defined(_M_X64)
- BOOL canDo64bit = TRUE;
-#else
- /* If we are a 32bit process on a 64bit Windows, first hit the 64bit keys. */
- BOOL canDo64bit = FALSE;
- IsWow64Process(GetCurrentProcess(), &canDo64bit);
-#endif
-
- get_version_info(version_text, MAX_PATH);
- fwprintf(stdout, L"\
-Python Launcher for Windows Version %ls\n\n", version_text);
- fwprintf(stdout, L"\
-usage:\n\
-%ls [launcher-args] [python-args] script [script-args]\n\n", argv[0]);
- fputws(L"\
-Launcher arguments:\n\n\
--2 : Launch the latest Python 2.x version\n\
--3 : Launch the latest Python 3.x version\n\
--X.Y : Launch the specified Python version\n", stdout);
- if (canDo64bit) {
- fputws(L"\
- The above all default to 64 bit if a matching 64 bit python is present.\n\
--X.Y-32: Launch the specified 32bit Python version\n\
--X-32 : Launch the latest 32bit Python X version\n\
--X.Y-64: Launch the specified 64bit Python version\n\
--X-64 : Launch the latest 64bit Python X version", stdout);
+ if ((argc == 2) && (!_wcsicmp(p, L"-h") || !_wcsicmp(p, L"--help")))
+ show_help_text(argv);
+ if ((argc == 2) && (!_wcsicmp(p, L"-0") || !_wcsicmp(p, L"-0p")))
+ executable = NULL; /* Info call only */
+ else
+ {
+ /* Look for an active virtualenv */
+ executable = find_python_by_venv();
+
+ /* If we didn't find one, look for the default Python */
+ if (executable == NULL) {
+ ip = locate_python(L"", FALSE);
+ if (ip == NULL)
+ error(RC_NO_PYTHON, L"Can't find a default Python.");
+ executable = ip->executable;
}
- fputws(L"\n\nThe following help text is from Python:\n\n", stdout);
- fflush(stdout);
}
}
- invoke_child(executable, NULL, command);
+ if (executable != NULL)
+ invoke_child(executable, NULL, command);
+ else
+ rc = RC_NO_PYTHON;
return rc;
}