Skip to content

Commit 4f10964

Browse files
authored
Allow python3 shebangs to use default runtime. (#296)
Fixes #249
1 parent 3755cde commit 4f10964

File tree

3 files changed

+26
-9
lines changed

3 files changed

+26
-9
lines changed

src/manage/scriptutils.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,16 @@ def _find_shebang_command(cmd, full_cmd, *, windowed=None):
4848
if not sh_cmd.match("*.exe"):
4949
sh_cmd = sh_cmd.with_name(sh_cmd.name + ".exe")
5050

51-
is_wdefault = sh_cmd.match("pythonw.exe") or sh_cmd.match("pyw.exe")
52-
is_default = is_wdefault or sh_cmd.match("python.exe") or sh_cmd.match("py.exe")
51+
is_wdefault = (
52+
sh_cmd.match("pythonw.exe")
53+
or sh_cmd.match("pyw.exe")
54+
or sh_cmd.match("pythonw3.exe")
55+
)
56+
is_default = is_wdefault or (
57+
sh_cmd.match("python.exe")
58+
or sh_cmd.match("py.exe")
59+
or sh_cmd.match("python3.exe")
60+
)
5361

5462
# Internal logic error, but non-fatal, if it has no value
5563
assert windowed is not None

tests/conftest.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,15 @@ def get_install_to_run(self, tag, *, windowed=False):
178178
return i
179179

180180
company, _, tag = tag.replace("/", "\\").rpartition("\\")
181-
return [i for i in self.installs
182-
if (not tag or i["tag"] == tag) and (not company or i["company"] == company)][0]
181+
try:
182+
found = [i for i in self.installs
183+
if (not tag or i["tag"] == tag) and (not company or i["company"] == company)]
184+
except LookupError as ex:
185+
# LookupError is expected from this function, so make sure we don't raise it here
186+
raise RuntimeError from ex
187+
if found:
188+
return found[0]
189+
raise LookupError(tag)
183190

184191
def ask_yn(self, question):
185192
return False if self.confirm else True

tests/test_scriptutils.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,8 @@ def test_read_shebang_windowed(fake_config, tmp_path, script, expect, windowed):
139139
def test_default_py_shebang(fake_config, tmp_path):
140140
inst = _fake_install("1.0", company="PythonCore", prefix=PurePath("C:\\TestRoot"), default=True)
141141
inst["run-for"] = [
142-
dict(name="python.exe", target=".\\python.exe"),
143-
dict(name="pythonw.exe", target=".\\pythonw.exe", windowed=1),
142+
dict(name="othername.exe", target=".\\test-binary-1.0.exe"),
143+
dict(name="othernamew.exe", target=".\\test-binary-1.0-w.exe", windowed=1),
144144
]
145145
fake_config.installs[:] = [inst]
146146

@@ -150,11 +150,13 @@ def t(n):
150150
# Finds the install's default executable
151151
assert t("python")["executable"].match("test-binary-1.0.exe")
152152
assert t("py")["executable"].match("test-binary-1.0.exe")
153+
assert t("python3")["executable"].match("test-binary-1.0.exe")
153154
assert t("python1.0")["executable"].match("test-binary-1.0.exe")
154155
# Finds the install's run-for executable with windowed=1
155-
assert t("pythonw")["executable"].match("pythonw.exe")
156-
assert t("pyw")["executable"].match("pythonw.exe")
157-
assert t("pythonw1.0")["executable"].match("pythonw.exe")
156+
assert t("pythonw")["executable"].match("test-binary-1.0-w.exe")
157+
assert t("pyw")["executable"].match("test-binary-1.0-w.exe")
158+
assert t("pythonw3")["executable"].match("test-binary-1.0-w.exe")
159+
assert t("pythonw1.0")["executable"].match("test-binary-1.0-w.exe")
158160

159161

160162
def test_unmanaged_py_shebang(fake_config, tmp_path):

0 commit comments

Comments
 (0)