Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions src/manage/scriptutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,16 @@ def _find_shebang_command(cmd, full_cmd):
if not sh_cmd.match("*.exe"):
sh_cmd = sh_cmd.with_name(sh_cmd.name + ".exe")

is_default = sh_cmd.match("python.exe") or sh_cmd.match("py.exe")
is_wdefault = sh_cmd.match("pythonw.exe") or sh_cmd.match("pyw.exe")
is_default = is_wdefault or sh_cmd.match("python.exe") or sh_cmd.match("py.exe")

for i in cmd.get_installs():
if is_default and i.get("default"):
return i
if is_wdefault:
target = [t for t in i.get("run-for", []) if t.get("windowed")]
if target:
return {**i, "executable": i["prefix"] / target[0]["target"]}
return {**i, "executable": i["prefix"] / i["executable"]}
for a in i.get("alias", ()):
if sh_cmd.match(a["name"]):
LOGGER.debug("Matched alias %s in %s", a["name"], i["id"])
Expand All @@ -35,7 +40,10 @@ def _find_shebang_command(cmd, full_cmd):
LOGGER.debug("Matched executable %s in %s", i["executable"], i["id"])
return i

# Fallback search for 'python<TAG>.exe' shebangs
# Fallback search for 'python[w]<TAG>.exe' shebangs
if sh_cmd.match("pythonw*.exe"):
tag = sh_cmd.name[7:-4]
return cmd.get_install_to_run(f"PythonCore/{tag}", windowed=True)
if sh_cmd.match("python*.exe"):
tag = sh_cmd.name[6:-4]
return cmd.get_install_to_run(f"PythonCore/{tag}")
Expand Down
9 changes: 8 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,14 @@ def __init__(self, global_dir, installs=[]):
def get_installs(self, *, include_unmanaged=True, set_default=True):
return self.installs

def get_install_to_run(self, tag):
def get_install_to_run(self, tag, *, windowed=False):
if windowed:
i = self.get_install_to_run(tag)
target = [t for t in i.get("run-for", []) if t.get("windowed")]
if target:
return {**i, "executable": i["prefix"] / target[0]["target"]}
return i

company, _, tag = tag.replace("/", "\\").rpartition("\\")
return [i for i in self.installs
if i["tag"] == tag and (not company or i["company"] == company)][0]
Expand Down
20 changes: 20 additions & 0 deletions tests/test_scriptutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from manage.scriptutils import (
find_install_from_script,
_find_shebang_command,
_read_script,
NewEncoding,
_maybe_quote,
Expand Down Expand Up @@ -69,6 +70,25 @@ def test_read_shebang(fake_config, tmp_path, script, expect):
assert not expect


def test_default_py_shebang(fake_config, tmp_path):
inst = _fake_install("1.0", company="PythonCore", prefix=PurePath("C:\\TestRoot"), default=True)
inst["run-for"] = [
dict(name="python.exe", target=".\\python.exe"),
dict(name="pythonw.exe", target=".\\pythonw.exe", windowed=1),
]
fake_config.installs[:] = [inst]

# Finds the install's default executable
assert _find_shebang_command(fake_config, "python")["executable"].match("test-binary-1.0.exe")
assert _find_shebang_command(fake_config, "py")["executable"].match("test-binary-1.0.exe")
assert _find_shebang_command(fake_config, "python1.0")["executable"].match("test-binary-1.0.exe")
# Finds the install's run-for executable with windowed=1
assert _find_shebang_command(fake_config, "pythonw")["executable"].match("pythonw.exe")
assert _find_shebang_command(fake_config, "pyw")["executable"].match("pythonw.exe")
assert _find_shebang_command(fake_config, "pythonw1.0")["executable"].match("pythonw.exe")



@pytest.mark.parametrize("script, expect", [
("# not a coding comment", None),
("# coding: utf-8-sig", None),
Expand Down