Skip to content

Commit 6724e26

Browse files
committed
Fix shebang of installed python scripts
Closes: #449340 Fixes: #449325
1 parent 6a08e6b commit 6724e26

File tree

4 files changed

+80
-6
lines changed

4 files changed

+80
-6
lines changed

pkgs/development/interpreters/python/hooks/default.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ in
138138
propagatedBuildInputs = [ installer ];
139139
substitutions = {
140140
inherit pythonInterpreter pythonSitePackages;
141+
python = python.interpreter;
141142
};
142143
} ./pypa-install-hook.sh
143144
)

pkgs/development/interpreters/python/hooks/pypa-install-hook.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pypaInstallPhase() {
88
pushd dist >/dev/null
99

1010
for wheel in *.whl; do
11-
@pythonInterpreter@ -m installer --prefix "$out" "$wheel"
11+
@pythonInterpreter@ -m installer --prefix "$out" --executable "@python@" "$wheel"
1212
echo "Successfully installed $wheel"
1313
done
1414

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
diff --git a/src/installer/__main__.py b/src/installer/__main__.py
2+
index 51014b9..45682d0 100644
3+
--- a/src/installer/__main__.py
4+
+++ b/src/installer/__main__.py
5+
@@ -30,6 +30,13 @@ def _get_main_parser() -> argparse.ArgumentParser:
6+
type=str,
7+
help="override prefix to install packages to",
8+
)
9+
+ parser.add_argument(
10+
+ "--executable",
11+
+ metavar="path",
12+
+ default=sys.executable,
13+
+ type=str,
14+
+ help="#! executable to install scripts with (default=sys.executable)",
15+
+ )
16+
parser.add_argument(
17+
"--compile-bytecode",
18+
action="append",
19+
@@ -86,7 +93,7 @@ def _main(cli_args: Sequence[str], program: Optional[str] = None) -> None:
20+
with WheelFile.open(args.wheel) as source:
21+
destination = SchemeDictionaryDestination(
22+
scheme_dict=_get_scheme_dict(source.distribution, prefix=args.prefix),
23+
- interpreter=sys.executable,
24+
+ interpreter=args.executable,
25+
script_kind=get_launcher_kind(),
26+
bytecode_optimization_levels=bytecode_levels,
27+
destdir=args.destdir,
28+
@@ -94,5 +101,6 @@ def _main(cli_args: Sequence[str], program: Optional[str] = None) -> None:
29+
installer.install(source, destination, {})
30+
31+
32+
+
33+
if __name__ == "__main__": # pragma: no cover
34+
_main(sys.argv[1:], "python -m installer")
35+
diff --git a/tests/test_main.py b/tests/test_main.py
36+
index 391a13d..d7b4192 100644
37+
--- a/tests/test_main.py
38+
+++ b/tests/test_main.py
39+
@@ -53,6 +53,28 @@ def test_main_prefix(fancy_wheel, tmp_path):
40+
}
41+
42+
43+
+def test_main_executable(fancy_wheel, tmp_path):
44+
+ destdir = tmp_path / "dest"
45+
+
46+
+ main(
47+
+ [
48+
+ str(fancy_wheel),
49+
+ "-d",
50+
+ str(destdir),
51+
+ "--executable",
52+
+ "/monty/python3.x",
53+
+ ],
54+
+ "python -m installer",
55+
+ )
56+
+
57+
+ installed_scripts = destdir.rglob("bin/*")
58+
+
59+
+ for f in installed_scripts:
60+
+ with f.open("rb") as fp:
61+
+ shebang = fp.readline()
62+
+ assert shebang == b"#!/monty/python3.x\n"
63+
+
64+
+
65+
def test_main_no_pyc(fancy_wheel, tmp_path):
66+
destdir = tmp_path / "dest"
67+

pkgs/development/python-modules/installer/default.nix

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,17 @@ buildPythonPackage rec {
2121
hash = "sha256-thHghU+1Alpay5r9Dc3v7ATRFfYKV8l9qR0nbGOOX/A=";
2222
};
2323

24-
patches = lib.optionals (pythonAtLeast "3.13") [
25-
# Fix compatibility with Python 3.13
26-
# https://github.com/pypa/installer/pull/201
27-
./python313-compat.patch
28-
];
24+
patches =
25+
lib.optionals (pythonAtLeast "3.13") [
26+
# Fix compatibility with Python 3.13
27+
# https://github.com/pypa/installer/pull/201
28+
./python313-compat.patch
29+
]
30+
++ [
31+
# Add -m flag to installer to correctly support cross
32+
# https://github.com/pypa/installer/pull/258
33+
./cross.patch
34+
];
2935

3036
nativeBuildInputs = [ flit-core ];
3137

0 commit comments

Comments
 (0)