-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
gh-115554: Improved logic for handling multiple existing py.exe launcher installs #115793
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
… launcher installs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
at a high level I think this makes sense. I can look past the specific api c++ boilerplate for what really seems to just be a way to spell get and set these variables from the whatever-script maybe functionalish installer state machine runtime ultimately running this logic.
My comments are mostly code stuff, I trust that this does what it describes itself as doing. But I'm definitely not a windows installer expert (I last created one over 20 years ago).
// User can deselect the option to include the launcher, but cannot | ||
// change it from the current per user/machine setting. | ||
LONGLONG includeLauncher, includeLauncherAllUsers; | ||
if (FAILED(BalGetNumericVariable(L"Include_launcher", &includeLauncher))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The _ in that L" Variable name when most others don't appear use that style it is unfortunate... but i'm guessing this comes from elsewhere in the XML definition or whatnot and is just style would require larger refactoring beyond the scope of this PR better done as its own no-functionality change if ever.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's actually consistent with the other Include_<name>
variables, which all refer to a <name>.msi
file. It's just none of the others need to be referenced as much because they're all easy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here they are all in a list:
cpython/Tools/msi/bundle/bundle.wxs
Lines 68 to 77 in 41d5391
<Variable Name="Include_core" Value="1" /> | |
<Variable Name="Include_exe" Value="1" bal:Overridable="yes" /> | |
<Variable Name="Include_dev" Value="1" bal:Overridable="yes" /> | |
<Variable Name="Include_lib" Value="1" bal:Overridable="yes" /> | |
<Variable Name="Include_test" Value="1" bal:Overridable="yes" /> | |
<Variable Name="Include_doc" Value="1" bal:Overridable="yes" /> | |
<Variable Name="Include_tools" Value="0" bal:Overridable="yes" /> | |
<Variable Name="Include_tcltk" Value="1" bal:Overridable="yes" /> | |
<Variable Name="Include_pip" Value="1" bal:Overridable="yes" /> | |
<Variable Name="Include_launcher" Value="-1" bal:Overridable="yes" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this seems a bit convoluted and hard to follow (maybe a combination of installer-toolkit-isms and non-trivial business logic) -- it might benefit from a flowchart!
can you clarify what would be the behavior when both 3.12.1 & 3.11.5 are installed, and we attempt to upgrade both to 3.12.2 & 3.11.8? (arbitrary patch releases)
in particular, I'm curious about the scenario of unattended installations that attempt to upgrade both (and can happen in unspecified order on different machines).
Misc/NEWS.d/next/Windows/2024-02-21-23-48-59.gh-issue-115554.02mpQC.rst
Outdated
Show resolved
Hide resolved
Agreed! It hurt my head figuring out the right places to put the logic.
So the important aspect for this change isn't which Python version(s) are installed, but which launcher version. There's only one launcher installer, so there should only ever be one version installed. Multiple is a bad enough error that we now refuse to do anything. If we assume 3.12.1 and 3.11.5 are installed correctly, then launcher 3.12.1 will be installed. If we then install 3.11.8, it'll compare its launcher 3.11.8 to 3.12.1 and decide that's a downgrade, and so will take the downgrade path in the new code (which deselects the launcher and disables the controls). If we're installing 3.12.2, it'll compare its launcher 3.12.2 to 3.12.1 and decide it's a major upgrade, and so will select the launcher and update the "launcher for all users" option to match the existing install (but only if the option wasn't specified on the command line, in which case we disable the launcher entirely if they conflict). If a second launcher is installed, this typically means one is per-user and one is per-machine, which we can't handle, so we block the launcher install entirely. This will update the checkbox on the main page to say that the launcher has to be uninstalled in order to update. If no launchers are detected, we update the default options (-1) to what we want for our standard default (i.e. to include the launcher). It's possible to override these on the command line though, so we want to respect those selections. It's not much of a flowchart, but you can probably imagine "OnPackageDetected" getting called once for every package that's already installed, and "OnDetectionComplete" being called once at the end. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the Windows installer could probably benefit from an end-to-end test suite, with all the complexity and possible scenarios, but I can't imagine writing such a test suite would be easy, and it'll probably be excruciatingly slow and flaky...
I just tried getting the smoke tests that are part of the installer build to run more reliably (GitHub installs Python on the build machines, so the installers can't really be tested when they're already installed 😅) and yeah, slow and flaky. But we do run the basics through their paces on every release - just not through every possible combination. However, most combinations shouldn't have interactions, and the problems almost always come up because of preexisting things on peoples' machines, and not because of the installer itself. So it becomes a case of scripting the setup of broken machines so that we can run the test and ... err... yeah... it's a huge amount of work for not actually a lot of benefit. |
< 8000 details-menu class="dropdown-menu dropdown-menu-sw show-more-popover color-fg-default" style="width:185px" src="" preload >
Thanks @zooba for the PR 🌮🎉.. I'm working now to backport this PR to: 3.11, 3.12. |
… launcher installs (pythonGH-115793) (cherry picked from commit 9b7f253) Co-authored-by: Steve Dower <steve.dower@python.org>
Sorry, @zooba, I could not cleanly backport this to
|
GH-116200 is a backport of this pull request to the 3.12 branch. |
GH-116201 is a backport of this pull request to the 3.11 branch. |
… launcher installs (pythonGH-115793)
|
… launcher installs (pythonGH-115793)
… launcher installs (pythonGH-115793)
… launcher installs (pythonGH-115793)
Uh oh!
There was an error while loading. Please reload this page.