mirror of https://github.com/python/cpython
Merge from 3.5 (including all NEWS entries)
This commit is contained in:
commit
7b28eb1457
264
Misc/NEWS
264
Misc/NEWS
|
@ -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?
|
||||
=================================
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -76,7 +76,9 @@ Select Customize to review current options.</String>
|
|||
<String Id="Include_testLabel">Python &test suite</String>
|
||||
<String Id="Include_testHelpLabel">Installs the standard library test suite.</String>
|
||||
<String Id="Include_launcherLabel">py &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 &files with Python (requires the py launcher)</String>
|
||||
<String Id="ShortcutsLabel">Create shortcuts for installed applications</String>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue