Skip to content

Commit a542a7f

Browse files
authored
Improve shebang serach to handle 'w' suffixed names. (#195)
Fixes #191
1 parent f378d2a commit a542a7f

File tree

3 files changed

+39
-4
lines changed

3 files changed

+39
-4
lines changed

src/manage/scriptutils.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,16 @@ def _find_shebang_command(cmd, full_cmd):
1919
if not sh_cmd.match("*.exe"):
2020
sh_cmd = sh_cmd.with_name(sh_cmd.name + ".exe")
2121

22-
is_default = sh_cmd.match("python.exe") or sh_cmd.match("py.exe")
22+
is_wdefault = sh_cmd.match("pythonw.exe") or sh_cmd.match("pyw.exe")
23+
is_default = is_wdefault or sh_cmd.match("python.exe") or sh_cmd.match("py.exe")
2324

2425
for i in cmd.get_installs():
2526
if is_default and i.get("default"):
26-
return i
27+
if is_wdefault:
28+
target = [t for t in i.get("run-for", []) if t.get("windowed")]
29+
if target:
30+
return {**i, "executable": i["prefix"] / target[0]["target"]}
31+
return {**i, "executable": i["prefix"] / i["executable"]}
2732
for a in i.get("alias", ()):
2833
if sh_cmd.match(a["name"]):
2934
LOGGER.debug("Matched alias %s in %s", a["name"], i["id"])
@@ -35,7 +40,10 @@ def _find_shebang_command(cmd, full_cmd):
3540
LOGGER.debug("Matched executable %s in %s", i["executable"], i["id"])
3641
return i
3742

38-
# Fallback search for 'python<TAG>.exe' shebangs
43+
# Fallback search for 'python[w]<TAG>.exe' shebangs
44+
if sh_cmd.match("pythonw*.exe"):
45+
tag = sh_cmd.name[7:-4]
46+
return cmd.get_install_to_run(f"PythonCore/{tag}", windowed=True)
3947
if sh_cmd.match("python*.exe"):
4048
tag = sh_cmd.name[6:-4]
4149
return cmd.get_install_to_run(f"PythonCore/{tag}")

tests/conftest.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,14 @@ def __init__(self, global_dir, installs=[]):
159159
def get_installs(self, *, include_unmanaged=True, set_default=True):
160160
return self.installs
161161

162-
def get_install_to_run(self, tag):
162+
def get_install_to_run(self, tag, *, windowed=False):
163+
if windowed:
164+
i = self.get_install_to_run(tag)
165+
target = [t for t in i.get("run-for", []) if t.get("windowed")]
166+
if target:
167+
return {**i, "executable": i["prefix"] / target[0]["target"]}
168+
return i
169+
163170
company, _, tag = tag.replace("/", "\\").rpartition("\\")
164171
return [i for i in self.installs
165172
if i["tag"] == tag and (not company or i["company"] == company)][0]

tests/test_scriptutils.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
from manage.scriptutils import (
1010
find_install_from_script,
11+
_find_shebang_command,
1112
_read_script,
1213
NewEncoding,
1314
_maybe_quote,
@@ -69,6 +70,25 @@ def test_read_shebang(fake_config, tmp_path, script, expect):
6970
assert not expect
7071

7172

73+
def test_default_py_shebang(fake_config, tmp_path):
74+
inst = _fake_install("1.0", company="PythonCore", prefix=PurePath("C:\\TestRoot"), default=True)
75+
inst["run-for"] = [
76+
dict(name="python.exe", target=".\\python.exe"),
77+
dict(name="pythonw.exe", target=".\\pythonw.exe", windowed=1),
78+
]
79+
fake_config.installs[:] = [inst]
80+
81+
# Finds the install's default executable
82+
assert _find_shebang_command(fake_config, "python")["executable"].match("test-binary-1.0.exe")
83+
assert _find_shebang_command(fake_config, "py")["executable"].match("test-binary-1.0.exe")
84+
assert _find_shebang_command(fake_config, "python1.0")["executable"].match("test-binary-1.0.exe")
85+
# Finds the install's run-for executable with windowed=1
86+
assert _find_shebang_command(fake_config, "pythonw")["executable"].match("pythonw.exe")
87+
assert _find_shebang_command(fake_config, "pyw")["executable"].match("pythonw.exe")
88+
assert _find_shebang_command(fake_config, "pythonw1.0")["executable"].match("pythonw.exe")
89+
90+
91+
7292
@pytest.mark.parametrize("script, expect", [
7393
("# not a coding comment", None),
7494
("# coding: utf-8-sig", None),

0 commit comments

Comments
 (0)