diff --git a/src/manage/install_command.py b/src/manage/install_command.py index c89afb2..b62589e 100644 --- a/src/manage/install_command.py +++ b/src/manage/install_command.py @@ -295,7 +295,20 @@ def update_all_shortcuts(cmd): shortcut_written = {} for i in cmd.get_installs(): if cmd.global_dir: - for a in i.get("alias", ()): + aliases = i.get("alias", ()) + + # Generate a python.exe for the default runtime in case the user + # later disables/removes the global python.exe command. + if i.get("default"): + aliases = list(i.get("alias", ())) + alias_1 = [a for a in aliases if not a.get("windowed")] + alias_2 = [a for a in aliases if a.get("windowed")] + if alias_1: + aliases.append({**alias_1[0], "name": "python.exe"}) + if alias_2: + aliases.append({**alias_2[0], "name": "pythonw.exe"}) + + for a in aliases: if a["name"].casefold() in alias_written: continue target = i["prefix"] / a["target"] @@ -576,6 +589,10 @@ def execute(cmd): cmd.tags = [] + if cmd.virtual_env: + LOGGER.debug("Clearing virtual_env setting to avoid conflicts during install.") + cmd.virtual_env = None + if cmd.refresh: if cmd.args: LOGGER.warn("Ignoring arguments; --refresh always refreshes all installs.") @@ -673,9 +690,6 @@ def execute(cmd): else: cmd.tags.append(tag_or_range(cmd.default_tag)) - if cmd.virtual_env: - LOGGER.debug("Clearing virtual_env setting to avoid conflicts during install.") - cmd.virtual_env = None installed = list(cmd.get_installs()) if cmd.download: diff --git a/tests/test_install_command.py b/tests/test_install_command.py index 50a485b..6c0cae3 100644 --- a/tests/test_install_command.py +++ b/tests/test_install_command.py @@ -103,6 +103,47 @@ def test_write_alias_fallback_platform(alias_checker): alias_checker.check_w64(alias_checker.Cmd("-spam"), "1.0", "testB") +@pytest.mark.parametrize("default", [1, 0]) +def test_write_alias_default(alias_checker, monkeypatch, tmp_path, default): + prefix = Path(tmp_path) / "runtime" + + class Cmd: + global_dir = Path(tmp_path) / "bin" + launcher_exe = None + def get_installs(self): + return [ + { + "alias": [ + {"name": "python3.exe", "target": "p.exe"}, + {"name": "pythonw3.exe", "target": "pw.exe", "windowed": 1}, + ], + "default": default, + "prefix": prefix, + } + ] + + prefix.mkdir(exist_ok=True, parents=True) + (prefix / "p.exe").write_bytes(b"") + (prefix / "pw.exe").write_bytes(b"") + + written = [] + def write_alias(*a): + written.append(a) + + monkeypatch.setattr(IC, "_write_alias", write_alias) + monkeypatch.setattr(IC, "SHORTCUT_HANDLERS", {}) + + IC.update_all_shortcuts(Cmd()) + + if default: + # Main test: python.exe and pythonw.exe are added in automatically + assert sorted(w[2]["name"] for w in written) == ["python.exe", "python3.exe", "pythonw.exe", "pythonw3.exe"] + else: + assert sorted(w[2]["name"] for w in written) == ["python3.exe", "pythonw3.exe"] + # Ensure we still only have the two targets + assert set(w[3].name for w in written) == {"p.exe", "pw.exe"} + + def test_print_cli_shortcuts(patched_installs, assert_log, monkeypatch, tmp_path): class Cmd: global_dir = Path(tmp_path)