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
This commit is contained in:
parent
b01c574ad6
commit
5b8f972e09
|
@ -365,6 +365,21 @@ Changes in the C API
|
||||||
characters. (Contributed by Serhiy Storchaka in :issue:`30708`.)
|
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
|
Removed
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Adds list options (-0, -0p) to py.exe launcher. Contributed by Steve Barnes.
|
|
@ -0,0 +1,2 @@
|
||||||
|
Allow requiring 64-bit interpreters from py.exe using -64 suffix. Contributed
|
||||||
|
by Steve (Gadget) Barnes.
|
156
PC/launcher.c
156
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
|
static int
|
||||||
process(int argc, wchar_t ** argv)
|
process(int argc, wchar_t ** argv)
|
||||||
{
|
{
|
||||||
|
@ -1380,12 +1463,12 @@ process(int argc, wchar_t ** argv)
|
||||||
wchar_t * p;
|
wchar_t * p;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
size_t plen;
|
size_t plen;
|
||||||
|
size_t slen;
|
||||||
INSTALLED_PYTHON * ip;
|
INSTALLED_PYTHON * ip;
|
||||||
BOOL valid;
|
BOOL valid;
|
||||||
DWORD size, attrs;
|
DWORD size, attrs;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
wchar_t message[MSGSIZE];
|
wchar_t message[MSGSIZE];
|
||||||
wchar_t version_text [MAX_PATH];
|
|
||||||
void * version_data;
|
void * version_data;
|
||||||
VS_FIXEDFILEINFO * file_info;
|
VS_FIXEDFILEINFO * file_info;
|
||||||
UINT block_size;
|
UINT block_size;
|
||||||
|
@ -1516,12 +1599,22 @@ process(int argc, wchar_t ** argv)
|
||||||
else {
|
else {
|
||||||
p = argv[1];
|
p = argv[1];
|
||||||
plen = wcslen(p);
|
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) {
|
if (valid) {
|
||||||
ip = locate_python(&p[1], FALSE);
|
ip = locate_python(&p[1], FALSE);
|
||||||
if (ip == NULL)
|
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 \
|
error(RC_NO_PYTHON, L"Requested Python version (%ls) not \
|
||||||
installed", &p[1]);
|
installed, use -0 for available pythons", &p[1]);
|
||||||
|
}
|
||||||
executable = ip->executable;
|
executable = ip->executable;
|
||||||
command += wcslen(p);
|
command += wcslen(p);
|
||||||
command = skip_whitespace(command);
|
command = skip_whitespace(command);
|
||||||
|
@ -1540,49 +1633,28 @@ installed", &p[1]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
/* Look for an active virtualenv */
|
if ((argc == 2) && (!_wcsicmp(p, L"-h") || !_wcsicmp(p, L"--help")))
|
||||||
executable = find_python_by_venv();
|
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 we didn't find one, look for the default Python */
|
||||||
if (executable == NULL) {
|
if (executable == NULL) {
|
||||||
ip = locate_python(L"", FALSE);
|
ip = locate_python(L"", FALSE);
|
||||||
if (ip == NULL)
|
if (ip == NULL)
|
||||||
error(RC_NO_PYTHON, L"Can't find a default Python.");
|
error(RC_NO_PYTHON, L"Can't find a default Python.");
|
||||||
executable = ip->executable;
|
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);
|
|
||||||
}
|
}
|
||||||
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;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue