Skip to content

Commit e5f1f87

Browse files
authored
Generate python.exe and pythonw.exe in globals directory for default runtime. (#145)
Fixes #143
1 parent beedc25 commit e5f1f87

File tree

2 files changed

+59
-4
lines changed

2 files changed

+59
-4
lines changed

src/manage/install_command.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,20 @@ def update_all_shortcuts(cmd):
295295
shortcut_written = {}
296296
for i in cmd.get_installs():
297297
if cmd.global_dir:
298-
for a in i.get("alias", ()):
298+
aliases = i.get("alias", ())
299+
300+
# Generate a python.exe for the default runtime in case the user
301+
# later disables/removes the global python.exe command.
302+
if i.get("default"):
303+
aliases = list(i.get("alias", ()))
304+
alias_1 = [a for a in aliases if not a.get("windowed")]
305+
alias_2 = [a for a in aliases if a.get("windowed")]
306+
if alias_1:
307+
aliases.append({**alias_1[0], "name": "python.exe"})
308+
if alias_2:
309+
aliases.append({**alias_2[0], "name": "pythonw.exe"})
310+
311+
for a in aliases:
299312
if a["name"].casefold() in alias_written:
300313
continue
301314
target = i["prefix"] / a["target"]
@@ -576,6 +589,10 @@ def execute(cmd):
576589

577590
cmd.tags = []
578591

592+
if cmd.virtual_env:
593+
LOGGER.debug("Clearing virtual_env setting to avoid conflicts during install.")
594+
cmd.virtual_env = None
595+
579596
if cmd.refresh:
580597
if cmd.args:
581598
LOGGER.warn("Ignoring arguments; --refresh always refreshes all installs.")
@@ -673,9 +690,6 @@ def execute(cmd):
673690
else:
674691
cmd.tags.append(tag_or_range(cmd.default_tag))
675692

676-
if cmd.virtual_env:
677-
LOGGER.debug("Clearing virtual_env setting to avoid conflicts during install.")
678-
cmd.virtual_env = None
679693
installed = list(cmd.get_installs())
680694

681695
if cmd.download:

tests/test_install_command.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,47 @@ def test_write_alias_fallback_platform(alias_checker):
103103
alias_checker.check_w64(alias_checker.Cmd("-spam"), "1.0", "testB")
104104

105105

106+
@pytest.mark.parametrize("default", [1, 0])
107+
def test_write_alias_default(alias_checker, monkeypatch, tmp_path, default):
108+
prefix = Path(tmp_path) / "runtime"
109+
110+
class Cmd:
111+
global_dir = Path(tmp_path) / "bin"
112+
launcher_exe = None
113+
def get_installs(self):
114+
return [
115+
{
116+
"alias": [
117+
{"name": "python3.exe", "target": "p.exe"},
118+
{"name": "pythonw3.exe", "target": "pw.exe", "windowed": 1},
119+
],
120+
"default": default,
121+
"prefix": prefix,
122+
}
123+
]
124+
125+
prefix.mkdir(exist_ok=True, parents=True)
126+
(prefix / "p.exe").write_bytes(b"")
127+
(prefix / "pw.exe").write_bytes(b"")
128+
129+
written = []
130+
def write_alias(*a):
131+
written.append(a)
132+
133+
monkeypatch.setattr(IC, "_write_alias", write_alias)
134+
monkeypatch.setattr(IC, "SHORTCUT_HANDLERS", {})
135+
136+
IC.update_all_shortcuts(Cmd())
137+
138+
if default:
139+
# Main test: python.exe and pythonw.exe are added in automatically
140+
assert sorted(w[2]["name"] for w in written) == ["python.exe", "python3.exe", "pythonw.exe", "pythonw3.exe"]
141+
else:
142+
assert sorted(w[2]["name"] for w in written) == ["python3.exe", "pythonw3.exe"]
143+
# Ensure we still only have the two targets
144+
assert set(w[3].name for w in written) == {"p.exe", "pw.exe"}
145+
146+
106147
def test_print_cli_shortcuts(patched_installs, assert_log, monkeypatch, tmp_path):
107148
class Cmd:
108149
global_dir = Path(tmp_path)

0 commit comments

Comments
 (0)