Merge from 3.5 (including all NEWS entries)

This commit is contained in:
Steve Dower 2015-12-02 09:19:07 -08:00
commit 7b28eb1457
6 changed files with 390 additions and 109 deletions

264
Misc/NEWS
View File

@ -476,21 +476,84 @@ Tools/Demos
`python3 -m venv`.
What's New in Python 3.5.1 release candidate 1?
===============================================
What's New in Python 3.5.1 final?
=================================
Release date: TBA
Release date: 2015-12-06
Core and Builtins
-----------------
Library
-------
Windows
-------
- Issue #25715: Python 3.5.1 installer shows wrong upgrade path and incorrect
logic for launcher detection.
What's New in Python 3.5.1 release candidate 1?
===============================================
Release date: 2015-11-22
Core and Builtins
-----------------
- Issue #25630: Fix a possible segfault during argument parsing in functions
that accept filesystem paths.
- Issue #23564: Fixed a partially broken sanity check in the _posixsubprocess
internals regarding how fds_to_pass were passed to the child. The bug had
no actual impact as subprocess.py already avoided it.
- Issue #25388: Fixed tokenizer crash when processing undecodable source code
with a null byte.
- Issue #25462: The hash of the key now is calculated only once in most
operations in C implementation of OrderedDict.
- Issue #22995: Default implementation of __reduce__ and __reduce_ex__ now
rejects builtin types with not defined __new__.
- Issue #25555: Fix parser and AST: fill lineno and col_offset of "arg" node
when compiling AST from Python objects.
- Issue #24802: Avoid buffer overreads when int(), float(), compile(), exec()
and eval() are passed bytes-like objects. These objects are not
necessarily terminated by a null byte, but the functions assumed they were.
- Issue #24726: Fixed a crash and leaking NULL in repr() of OrderedDict that
was mutated by direct calls of dict methods.
- Issue #25449: Iterating OrderedDict with keys with unstable hash now raises
KeyError in C implementations as well as in Python implementation.
- Issue #25395: Fixed crash when highly nested OrderedDict structures were
garbage collected.
- Issue #25274: sys.setrecursionlimit() now raises a RecursionError if the new
recursion limit is too low depending at the current recursion depth. Modify
also the "lower-water mark" formula to make it monotonic. This mark is used
to decide when the overflowed flag of the thread state is reset.
- Issue #24402: Fix input() to prompt to the redirected stdout when
sys.stdout.fileno() fails.
- Issue #24806: Prevent builtin types that are not allowed to be subclassed from
being subclassed through multiple inheritance.
- Issue #24848: Fixed a number of bugs in UTF-7 decoding of misformed data.
- Issue #25280: Import trace messages emitted in verbose (-v) mode are no
longer formatted twice.
- Issue #25003: On Solaris 11.3 or newer, os.urandom() now uses the
getrandom() function instead of the getentropy() function. The getentropy()
function is blocking to generate very good quality entropy, os.urandom()
doesn't need such high-quality entropy.
- Issue #25182: The stdprinter (used as sys.stderr before the io module is
imported at startup) now uses the backslashreplace error handler.
@ -514,6 +577,12 @@ Library
- Issue #25583: Avoid incorrect errors raised by os.makedirs(exist_ok=True)
when the OS gives priority to errors such as EACCES over EEXIST.
- Issue #25593: Change semantics of EventLoop.stop() in asyncio.
- Issue #6973: When we know a subprocess.Popen process has died, do
not allow the send_signal(), terminate(), or kill() methods to do
anything as they could potentially signal a different process.
- Issue #25590: In the Readline completer, only call getattr() once per
attribute.
@ -521,6 +590,71 @@ Library
by wrapping a memoryview. This was a regression made in 3.5a1. Based
on patch by Eryksun.
- Issue #25584: Added "escape" to the __all__ list in the glob module.
- Issue #25584: Fixed recursive glob() with patterns starting with '\*\*'.
- Issue #25446: Fix regression in smtplib's AUTH LOGIN support.
- Issue #18010: Fix the pydoc web server's module search function to handle
exceptions from importing packages.
- Issue #25554: Got rid of circular references in regular expression parsing.
- Issue #25510: fileinput.FileInput.readline() now returns b'' instead of ''
at the end if the FileInput was opened with binary mode.
Patch by Ryosuke Ito.
- Issue #25503: Fixed inspect.getdoc() for inherited docstrings of properties.
Original patch by John Mark Vandenberg.
- Issue #25515: Always use os.urandom as a source of randomness in uuid.uuid4.
- Issue #21827: Fixed textwrap.dedent() for the case when largest common
whitespace is a substring of smallest leading whitespace.
Based on patch by Robert Li.
- Issue #25447: The lru_cache() wrapper objects now can be copied and pickled
(by returning the original object unchanged).
- Issue #25390: typing: Don't crash on Union[str, Pattern].
- Issue #25441: asyncio: Raise error from drain() when socket is closed.
- Issue #25410: Cleaned up and fixed minor bugs in C implementation of
OrderedDict.
- Issue #25411: Improved Unicode support in SMTPHandler through better use of
the email package. Thanks to user simon04 for the patch.
- Issue #25407: Remove mentions of the formatter module being removed in
Python 3.6.
- Issue #25406: Fixed a bug in C implementation of OrderedDict.move_to_end()
that caused segmentation fault or hang in iterating after moving several
items to the start of ordered dict.
- Issue #25364: zipfile now works in threads disabled builds.
- Issue #25328: smtpd's SMTPChannel now correctly raises a ValueError if both
decode_data and enable_SMTPUTF8 are set to true.
- Issue #25316: distutils raises OSError instead of DistutilsPlatformError
when MSVC is not installed.
- Issue #25380: Fixed protocol for the STACK_GLOBAL opcode in
pickletools.opcodes.
- Issue #23972: Updates asyncio datagram create method allowing reuseport
and reuseaddr socket options to be set prior to binding the socket.
Mirroring the existing asyncio create_server method the reuseaddr option
for datagram sockets defaults to True if the O/S is 'posix' (except if the
platform is Cygwin). Patch by Chris Laws.
- Issue #25304: Add asyncio.run_coroutine_threadsafe(). This lets you
submit a coroutine to a loop from another thread, returning a
concurrent.futures.Future. By Vincent Michel.
- Issue #25232: Fix CGIRequestHandler to split the query from the URL at the
first question mark (?) rather than the last. Patch from Xiang Zhang.
@ -548,6 +682,9 @@ Library
- Issue #25233: Rewrite the guts of asyncio.Queue and
asyncio.Semaphore to be more understandable and correct.
- Issue #25203: Failed readline.set_completer_delims() no longer left the
module in inconsistent state.
- Issue #23600: Default implementation of tzinfo.fromutc() was returning
wrong results in some cases.
@ -621,6 +758,19 @@ Library
- Issue #24881: Fixed setting binary mode in Python implementation of FileIO
on Windows and Cygwin. Patch from Akira Li.
- Issue #25578: Fix (another) memory leak in SSLSocket.getpeercer().
- Issue #25530: Disable the vulnerable SSLv3 protocol by default when creating
ssl.SSLContext.
- Issue #25569: Fix memory leak in SSLSocket.getpeercert().
- Issue #25471: Sockets returned from accept() shouldn't appear to be
nonblocking.
- Issue #25319: When threading.Event is reinitialized, the underlying condition
should use a regular lock rather than a recursive lock.
- Issue #21112: Fix regression in unittest.expectedFailure on subclasses.
Patch from Berker Peksag.
@ -642,8 +792,104 @@ Library
- Issue #23572: Fixed functools.singledispatch on classes with falsy
metaclasses. Patch by Ethan Furman.
- Issue #12006: Add ISO 8601 year, week, and day directives (%G, %V, %u) to
strptime.
- asyncio: ensure_future() now accepts awaitable objects.
IDLE
----
- Issue 15348: Stop the debugger engine (normally in a user process)
before closing the debugger window (running in the IDLE process).
This prevents the RuntimeErrors that were being caught and ignored.
- Issue #24455: Prevent IDLE from hanging when a) closing the shell while the
debugger is active (15347); b) closing the debugger with the [X] button
(15348); and c) activating the debugger when already active (24455).
The patch by Mark Roseman does this by making two changes.
1. Suspend and resume the gui.interaction method with the tcl vwait
mechanism intended for this purpose (instead of root.mainloop & .quit).
2. In gui.run, allow any existing interaction to terminate first.
- Change 'The program' to 'Your program' in an IDLE 'kill program?' message
to make it clearer that the program referred to is the currently running
user program, not IDLE itself.
- Issue #24750: Improve the appearance of the IDLE editor window status bar.
Patch by Mark Roseman.
- Issue #25313: Change the handling of new built-in text color themes to better
address the compatibility problem introduced by the addition of IDLE Dark.
Consistently use the revised idleConf.CurrentTheme everywhere in idlelib.
- Issue #24782: Extension configuration is now a tab in the IDLE Preferences
dialog rather than a separate dialog. The former tabs are now a sorted
list. Patch by Mark Roseman.
- Issue #22726: Re-activate the config dialog help button with some content
about the other buttons and the new IDLE Dark theme.
- Issue #24820: IDLE now has an 'IDLE Dark' built-in text color theme.
It is more or less IDLE Classic inverted, with a cobalt blue background.
Strings, comments, keywords, ... are still green, red, orange, ... .
To use it with IDLEs released before November 2015, hit the
'Save as New Custom Theme' button and enter a new name,
such as 'Custom Dark'. The custom theme will work with any IDLE
release, and can be modified.
- Issue #25224: README.txt is now an idlelib index for IDLE developers and
curious users. The previous user content is now in the IDLE doc chapter.
'IDLE' now means 'Integrated Development and Learning Environment'.
- Issue #24820: Users can now set breakpoint colors in
Settings -> Custom Highlighting. Original patch by Mark Roseman.
- Issue #24972: Inactive selection background now matches active selection
background, as configured by users, on all systems. Found items are now
always highlighted on Windows. Initial patch by Mark Roseman.
- Issue #24570: Idle: make calltip and completion boxes appear on Macs
affected by a tk regression. Initial patch by Mark Roseman.
- Issue #24988: Idle ScrolledList context menus (used in debugger)
now work on Mac Aqua. Patch by Mark Roseman.
- Issue #24801: Make right-click for context menu work on Mac Aqua.
Patch by Mark Roseman.
- Issue #25173: Associate tkinter messageboxes with a specific widget.
For Mac OSX, make them a 'sheet'. Patch by Mark Roseman.
- Issue #25198: Enhance the initial html viewer now used for Idle Help.
* Properly indent fixed-pitch text (patch by Mark Roseman).
* Give code snippet a very Sphinx-like light blueish-gray background.
* Re-use initial width and height set by users for shell and editor.
* When the Table of Contents (TOC) menu is used, put the section header
at the top of the screen.
- Issue #25225: Condense and rewrite Idle doc section on text colors.
- Issue #21995: Explain some differences between IDLE and console Python.
- Issue #22820: Explain need for *print* when running file from Idle editor.
- Issue #25224: Doc: augment Idle feature list and no-subprocess section.
- Issue #25219: Update doc for Idle command line options.
Some were missing and notes were not correct.
- Issue #24861: Most of idlelib is private and subject to change.
Use idleib.idle.* to start Idle. See idlelib.__init__.__doc__.
- Issue #25199: Idle: add synchronization comments for future maintainers.
- Issue #16893: Replace help.txt with help.html for Idle doc display.
The new idlelib/help.html is rstripped Doc/build/html/library/idle.html.
It looks better than help.txt and will better document Idle as released.
The tkinter html viewer that works for this file was written by Mark Roseman.
The now unused EditorWindow.HelpDialog class and helt.txt file are deprecated.
- Issue #24199: Deprecate unused idlelib.idlever with possible removal in 3.6.
- Issue #24790: Remove extraneous code (which also create 2 & 3 conflicts).
Documentation
-------------
@ -670,6 +916,8 @@ Documentation
Tests
-----
- Issue #25449: Added tests for OrderedDict subclasses.
- Issue #25099: Make test_compileall not fail when an entry on sys.path cannot
be written to (commonly seen in administrative installs on Windows).
@ -689,7 +937,6 @@ Build
- Issue #24986: It is now possible to build Python on Windows without errors
when external libraries are not available.
Windows
-------
@ -728,6 +975,11 @@ Windows
- Issue #25022: Removed very outdated PC/example_nt/ directory.
Tools/Demos
-----------
- Issue #25440: Fix output of python-config --extension-suffix.
What's New in Python 3.5.0 final?
=================================

View File

@ -66,7 +66,7 @@
<Checkbox Name="Include_launcher" X="185" Y="251" Width="100" Height="24" TabStop="yes" FontId="3" HideWhenDisabled="no">#(loc.Include_launcherLabel)</Checkbox>
<Checkbox Name="CustomInstallLauncherAllUsers" X="285" Y="251" Width="-11" Height="24" TabStop="yes" FontId="3">#(loc.InstallLauncherAllUsersLabel)</Checkbox>
<Text X="205" Y="276" Width="-11" Height="24" TabStop="no" FontId="5">#(loc.Include_launcherHelpLabel)</Text>
<Text Name="Include_launcherHelp" X="205" Y="276" Width="-11" Height="24" TabStop="no" FontId="5"></Text>
<Button Name="Custom1BackButton" X="185" Y="-11" Width="85" Height="27" TabStop="yes" FontId="0">#(loc.CustomBackButton)</Button>
<Button Name="CustomNextButton" X="-101" Y="-11" Width="85" Height="27" TabStop="yes" FontId="0">#(loc.CustomNextButton)</Button>

View File

@ -76,7 +76,9 @@ Select Customize to review current options.</String>
<String Id="Include_testLabel">Python &amp;test suite</String>
<String Id="Include_testHelpLabel">Installs the standard library test suite.</String>
<String Id="Include_launcherLabel">py &amp;launcher</String>
<String Id="Include_launcherHelpLabel">Installs the global 'py' launcher to make it easier to start Python.</String>
<String Id="Include_launcherHelp">Installs the global 'py' launcher to make it easier to start Python.</String>
<String Id="Include_launcherRemove">Use Programs and Features to remove the 'py' launcher.</String>
<String Id="Include_launcherUpgrade">Upgrades the global 'py' launcher from the previous version.</String>
<String Id="AssociateFilesLabel">Associate &amp;files with Python (requires the py launcher)</String>
<String Id="ShortcutsLabel">Create shortcuts for installed applications</String>

View File

@ -94,6 +94,7 @@ enum CONTROL_ID {
ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX,
ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX,
ID_CUSTOM_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX,
ID_CUSTOM_INCLUDE_LAUNCHER_HELP_LABEL,
ID_CUSTOM_COMPILE_ALL_CHECKBOX,
ID_CUSTOM_BROWSE_BUTTON,
ID_CUSTOM_BROWSE_BUTTON_LABEL,
@ -158,6 +159,7 @@ static THEME_ASSIGN_CONTROL_ID CONTROL_ID_NAMES[] = {
{ ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX, L"AssociateFiles" },
{ ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX, L"InstallAllUsers" },
{ ID_CUSTOM_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX, L"CustomInstallLauncherAllUsers" },
{ ID_CUSTOM_INCLUDE_LAUNCHER_HELP_LABEL, L"Include_launcherHelp" },
{ ID_CUSTOM_COMPILE_ALL_CHECKBOX, L"CompileAll" },
{ ID_CUSTOM_BROWSE_BUTTON, L"CustomBrowseButton" },
{ ID_CUSTOM_BROWSE_BUTTON_LABEL, L"CustomBrowseButtonLabel" },
@ -454,6 +456,20 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication {
ThemeSendControlMessage(_theme, ID_CUSTOM_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX, BM_SETCHECK,
installLauncherAllUsers ? BST_CHECKED : BST_UNCHECKED, 0);
LOC_STRING *pLocString = nullptr;
LPCWSTR locKey = L"#(loc.Include_launcherHelp)";
LONGLONG detectedLauncher;
if (SUCCEEDED(BalGetNumericVariable(L"DetectedLauncher", &detectedLauncher)) && detectedLauncher) {
locKey = L"#(loc.Include_launcherRemove)";
} else if (SUCCEEDED(BalGetNumericVariable(L"DetectedOldLauncher", &detectedLauncher)) && detectedLauncher) {
locKey = L"#(loc.Include_launcherUpgrade)";
}
if (SUCCEEDED(LocGetString(_wixLoc, locKey, &pLocString)) && pLocString) {
ThemeSetTextControl(_theme, ID_CUSTOM_INCLUDE_LAUNCHER_HELP_LABEL, pLocString->wzText);
}
}
void Custom2Page_Show() {
@ -641,6 +657,29 @@ public: // IBootstrapperApplication
return nResult;
}
virtual STDMETHODIMP_(int) OnDetectRelatedMsiPackage(
__in_z LPCWSTR wzPackageId,
__in_z LPCWSTR /*wzProductCode*/,
__in BOOL fPerMachine,
__in DWORD64 /*dw64Version*/,
__in BOOTSTRAPPER_RELATED_OPERATION operation
) {
if (BOOTSTRAPPER_RELATED_OPERATION_MAJOR_UPGRADE == operation &&
(CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzPackageId, -1, L"launcher_AllUsers", -1) ||
CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzPackageId, -1, L"launcher_JustForMe", -1))) {
auto hr = LoadAssociateFilesStateFromKey(_engine, fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER);
if (hr == S_OK) {
_engine->SetVariableNumeric(L"AssociateFiles", 1);
} else if (FAILED(hr)) {
BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to load AssociateFiles state: error code 0x%08X", hr);
}
_engine->SetVariableNumeric(L"Include_launcher", 1);
_engine->SetVariableNumeric(L"DetectedOldLauncher", 1);
_engine->SetVariableNumeric(L"InstallLauncherAllUsers", fPerMachine ? 1 : 0);
}
return CheckCanceled() ? IDCANCEL : IDNOACTION;
}
virtual STDMETHODIMP_(int) OnDetectRelatedBundle(
__in LPCWSTR wzBundleId,
@ -656,24 +695,8 @@ public: // IBootstrapperApplication
if (BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE == operation) {
_downgradingOtherVersion = TRUE;
} else if (BOOTSTRAPPER_RELATED_OPERATION_MAJOR_UPGRADE == operation) {
_upgradingOldVersion = TRUE;
// Assume we don't want the launcher or file associations, and if
// they have already been installed then loading the state will
// reactivate these settings.
_engine->SetVariableNumeric(L"Include_launcher", 0);
_engine->SetVariableNumeric(L"AssociateFiles", 0);
auto hr = LoadLauncherStateFromKey(_engine, HKEY_CURRENT_USER);
if (hr == S_FALSE) {
hr = LoadLauncherStateFromKey(_engine, HKEY_LOCAL_MACHINE);
}
if (FAILED(hr)) {
BalLog(
BOOTSTRAPPER_LOG_LEVEL_ERROR,
"Failed to load launcher state: error code 0x%08X",
hr
);
}
BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Detected previous version - planning upgrade");
_upgrading = TRUE;
LoadOptionalFeatureStates(_engine);
} else if (BOOTSTRAPPER_RELATED_OPERATION_NONE == operation) {
@ -699,9 +722,42 @@ public: // IBootstrapperApplication
virtual STDMETHODIMP_(void) OnDetectPackageComplete(
__in LPCWSTR wzPackageId,
__in HRESULT /*hrStatus*/,
__in HRESULT hrStatus,
__in BOOTSTRAPPER_PACKAGE_STATE state
) { }
) {
if (FAILED(hrStatus)) {
return;
}
BOOL detectedLauncher = FALSE;
HKEY hkey = HKEY_LOCAL_MACHINE;
if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzPackageId, -1, L"launcher_AllUsers", -1)) {
if (BOOTSTRAPPER_PACKAGE_STATE_PRESENT == state || BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE == state) {
detectedLauncher = TRUE;
_engine->SetVariableNumeric(L"InstallLauncherAllUsers", 1);
}
} else if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzPackageId, -1, L"launcher_JustForMe", -1)) {
if (BOOTSTRAPPER_PACKAGE_STATE_PRESENT == state || BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE == state) {
detectedLauncher = TRUE;
_engine->SetVariableNumeric(L"InstallLauncherAllUsers", 0);
}
}
if (detectedLauncher) {
/* When we detect the current version of the launcher. */
_engine->SetVariableNumeric(L"Include_launcher", 1);
_engine->SetVariableNumeric(L"DetectedLauncher", 1);
_engine->SetVariableString(L"Include_launcherState", L"disable");
_engine->SetVariableString(L"InstallLauncherAllUsersState", L"disable");
auto hr = LoadAssociateFilesStateFromKey(_engine, hkey);
if (hr == S_OK) {
_engine->SetVariableNumeric(L"AssociateFiles", 1);
} else if (FAILED(hr)) {
BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to load AssociateFiles state: error code 0x%08X", hr);
}
}
}
virtual STDMETHODIMP_(void) OnDetectComplete(__in HRESULT hrStatus) {
@ -716,32 +772,7 @@ public: // IBootstrapperApplication
if (SUCCEEDED(hrStatus)) {
// Ensure the default path has been set
LONGLONG installAll;
LPWSTR targetDir = nullptr;
LPWSTR defaultTargetDir = nullptr;
hrStatus = BalGetStringVariable(L"TargetDir", &targetDir);
if (FAILED(hrStatus) || !targetDir || !targetDir[0]) {
ReleaseStr(targetDir);
targetDir = nullptr;
if (FAILED(BalGetNumericVariable(L"InstallAllUsers", &installAll))) {
installAll = 0;
}
hrStatus = BalGetStringVariable(
installAll ? L"DefaultAllUsersTargetDir" : L"DefaultJustForMeTargetDir",
&defaultTargetDir
);
if (SUCCEEDED(hrStatus) && defaultTargetDir) {
if (defaultTargetDir[0] && SUCCEEDED(BalFormatString(defaultTargetDir, &targetDir))) {
hrStatus = _engine->SetVariableString(L"TargetDir", targetDir);
ReleaseStr(targetDir);
}
ReleaseStr(defaultTargetDir);
}
}
hrStatus = EnsureTargetDir();
}
SetState(PYBA_STATE_DETECTED, hrStatus);
@ -1396,9 +1427,14 @@ private:
hr = LoadBootstrapperBAFunctions();
BalExitOnFailure(hr, "Failed to load bootstrapper functions.");
hr = UpdateUIStrings(_command.action);
BalExitOnFailure(hr, "Failed to load UI strings.");
if (_command.action == BOOTSTRAPPER_ACTION_MODIFY) {
LoadOptionalFeatureStates(_engine);
}
GetBundleFileVersion();
// don't fail if we couldn't get the version info; best-effort only
LExit:
@ -1906,27 +1942,6 @@ private:
for (DWORD i = 0; i < _theme->cControls; ++i) {
THEME_CONTROL* pControl = _theme->rgControls + i;
LPWSTR text = nullptr;
LPWSTR name = nullptr;
LOC_STRING *locText = nullptr;
// If a command link has a note, then add it.
if ((pControl->dwStyle & BS_TYPEMASK) == BS_COMMANDLINK ||
(pControl->dwStyle & BS_TYPEMASK) == BS_DEFCOMMANDLINK) {
hr = StrAllocFormatted(&name, L"#(loc.%lsNote)", pControl->sczName);
if (SUCCEEDED(hr)) {
hr = LocGetString(_wixLoc, name, &locText);
ReleaseStr(name);
if (SUCCEEDED(hr) && locText && locText->wzText && locText->wzText[0]) {
hr = BalFormatString(locText->wzText, &text);
if (SUCCEEDED(hr) && text && text[0]) {
ThemeSendControlMessage(_theme, pControl->wId, BCM_SETNOTE, 0, (LPARAM)text);
ReleaseStr(text);
text = nullptr;
}
}
}
hr = S_OK;
}
if (!pControl->wPageId && pControl->sczText && *pControl->sczText) {
HRESULT hrFormat;
@ -2048,6 +2063,7 @@ private:
return;
}
HRESULT UpdateUIStrings(__in BOOTSTRAPPER_ACTION action) {
HRESULT hr = S_OK;
LPCWSTR likeInstalling = nullptr;
@ -2270,6 +2286,30 @@ private:
StrFree(controlState);
}
StrFree(controlName);
controlName = nullptr;
// If a command link has a note, then add it.
if ((pControl->dwStyle & BS_TYPEMASK) == BS_COMMANDLINK ||
(pControl->dwStyle & BS_TYPEMASK) == BS_DEFCOMMANDLINK) {
hr = StrAllocFormatted(&controlName, L"#(loc.%lsNote)", pControl->sczName);
if (SUCCEEDED(hr)) {
LOC_STRING *locText = nullptr;
hr = LocGetString(_wixLoc, controlName, &locText);
if (SUCCEEDED(hr) && locText && locText->wzText && locText->wzText[0]) {
LPWSTR text = nullptr;
hr = BalFormatString(locText->wzText, &text);
if (SUCCEEDED(hr) && text && text[0]) {
ThemeSendControlMessage(_theme, pControl->wId, BCM_SETNOTE, 0, (LPARAM)text);
ReleaseStr(text);
text = nullptr;
}
}
ReleaseStr(controlName);
controlName = nullptr;
}
hr = S_OK;
}
}
ThemeControlEnable(_theme, pControl->wId, enableControl);
@ -2515,9 +2555,8 @@ private:
if (_installPage == PAGE_LOADING) {
switch (_command.action) {
case BOOTSTRAPPER_ACTION_INSTALL:
if (_upgradingOldVersion) {
if (_upgrading) {
_installPage = PAGE_UPGRADE;
_upgrading = TRUE;
} else if (SUCCEEDED(BalGetNumericVariable(L"SimpleInstall", &simple)) && simple) {
_installPage = PAGE_SIMPLE_INSTALL;
} else {
@ -2560,11 +2599,9 @@ private:
static BAL_CONDITION WILL_ELEVATE_CONDITION = {
L"not WixBundleElevated and ("
/*Elevate when installing for all users*/
L"InstallAllUsers or"
L"InstallAllUsers or "
/*Elevate when installing the launcher for all users and it was not detected*/
L"(InstallLauncherAllUsers and Include_launcher and not DetectedLauncher) or"
/*Elevate when the launcher was installed for all users and it is being removed*/
L"(DetectedLauncher and DetectedLauncherAllUsers and not Include_launcher)"
L"(Include_launcher and InstallLauncherAllUsers and not DetectedLauncher)"
L")",
L""
};
@ -2867,19 +2904,16 @@ private:
return HRESULT_FROM_WIN32(res);
}
static HRESULT LoadLauncherStateFromKey(
static HRESULT LoadAssociateFilesStateFromKey(
__in IBootstrapperEngine* pEngine,
__in HKEY hkHive
) {
const LPCWSTR subkey = L"Software\\Python\\PyLauncher";
HKEY hKey;
LRESULT res;
HRESULT hr;
if (IsTargetPlatformx64(pEngine)) {
res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
} else {
res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
}
res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
if (res == ERROR_FILE_NOT_FOUND) {
return S_FALSE;
@ -2888,26 +2922,17 @@ private:
return HRESULT_FROM_WIN32(res);
}
res = RegQueryValueExW(hKey, nullptr, nullptr, nullptr, nullptr, nullptr);
if (res == ERROR_FILE_NOT_FOUND) {
pEngine->SetVariableNumeric(L"Include_launcher", 0);
} else if (res == ERROR_SUCCESS) {
pEngine->SetVariableNumeric(L"Include_launcher", 1);
pEngine->SetVariableNumeric(L"DetectedLauncher", 1);
pEngine->SetVariableNumeric(L"InstallLauncherAllUsers", (hkHive == HKEY_LOCAL_MACHINE) ? 1 : 0);
pEngine->SetVariableNumeric(L"DetectedLauncherAllUsers", (hkHive == HKEY_LOCAL_MACHINE) ? 1 : 0);
pEngine->SetVariableString(L"InstallLauncherAllUsersState", L"disable");
}
res = RegQueryValueExW(hKey, L"AssociateFiles", nullptr, nullptr, nullptr, nullptr);
if (res == ERROR_FILE_NOT_FOUND) {
pEngine->SetVariableNumeric(L"AssociateFiles", 0);
hr = S_FALSE;
} else if (res == ERROR_SUCCESS) {
pEngine->SetVariableNumeric(L"AssociateFiles", 1);
hr = S_OK;
} else {
hr = HRESULT_FROM_WIN32(res);
}
RegCloseKey(hKey);
return S_OK;
return hr;
}
static void LoadOptionalFeatureStates(__in IBootstrapperEngine* pEngine) {
@ -2918,7 +2943,11 @@ private:
HKEY hkHive;
// The launcher installation is separate from the Python install, so we
// check its state later. This also checks the file association option.
// check its state later. For now, assume we don't want the launcher or
// file associations, and if they have already been installed then
// loading the state will reactivate these settings.
pEngine->SetVariableNumeric(L"Include_launcher", 0);
pEngine->SetVariableNumeric(L"AssociateFiles", 0);
// Get the registry key from the bundle, to save having to duplicate it
// in multiple places.
@ -3089,7 +3118,6 @@ public:
_hrFinal = hrHostInitialization;
_downgradingOtherVersion = FALSE;
_upgradingOldVersion = FALSE;
_restartResult = BOOTSTRAPPER_APPLY_RESTART_NONE;
_restartRequired = FALSE;
_allowRestart = FALSE;
@ -3113,8 +3141,6 @@ public:
_hBAFModule = nullptr;
_baFunction = nullptr;
EnsureTargetDir();
}
@ -3174,7 +3200,6 @@ private:
DWORD _calculatedExecuteProgress;
BOOL _downgradingOtherVersion;
BOOL _upgradingOldVersion;
BOOTSTRAPPER_APPLY_RESTART _restartResult;
BOOL _restartRequired;
BOOL _allowRestart;

View File

@ -51,7 +51,7 @@
-->
<Variable Name="DefaultCustomTargetDir" Value="" bal:Overridable="yes" />
<Variable Name="InstallAllUsersState" Value="enabled" />
<Variable Name="InstallAllUsersState" Value="enabled" bal:Overridable="yes" />
<?if "$(var.PyTestExt)"="" ?>
<Variable Name="InstallLauncherAllUsersState" Value="enabled" bal:Overridable="yes" />
<?else ?>
@ -72,6 +72,7 @@
<Variable Name="Include_pip" Value="1" bal:Overridable="yes" />
<?if "$(var.PyTestExt)"="" ?>
<Variable Name="Include_launcher" Value="1" bal:Overridable="yes" />
<Variable Name="Include_launcherState" Value="enabled" bal:Overridable="yes" />
<?else ?>
<Variable Name="Include_launcher" Value="0" />
<Variable Name="Include_launcherState" Value="disable" />
@ -81,6 +82,7 @@
<Variable Name="LauncherOnly" Value="0" bal:Overridable="yes" />
<Variable Name="DetectedLauncher" Value="0" />
<Variable Name="DetectedOldLauncher" Value="0" />
<Variable Name="AssociateFiles" Value="1" bal:Overridable="yes" />
<Variable Name="Shortcuts" Value="1" bal:Overridable="yes" />

View File

@ -11,7 +11,7 @@
EnableFeatureSelection="yes"
Permanent="yes"
Visible="yes"
InstallCondition="(InstallAllUsers or InstallLauncherAllUsers) and Include_launcher" />
InstallCondition="(InstallAllUsers or InstallLauncherAllUsers) and Include_launcher and not DetectedLauncher" />
<MsiPackage Id="launcher_JustForMe"
SourceFile="launcher.msi"
@ -21,7 +21,7 @@
EnableFeatureSelection="yes"
Permanent="yes"
Visible="yes"
InstallCondition="not (InstallAllUsers or InstallLauncherAllUsers) and Include_launcher" />
InstallCondition="not (InstallAllUsers or InstallLauncherAllUsers) and Include_launcher and not DetectedLauncher" />
</PackageGroup>
</Fragment>
</Wix>