1{ lib
2, python
3, makePythonHook
4, makeWrapper }:
5
6with lib;
7
8makePythonHook {
9 deps = makeWrapper;
10 substitutions.sitePackages = python.sitePackages;
11 substitutions.executable = python.interpreter;
12 substitutions.python = python.pythonForBuild;
13 substitutions.pythonHost = python;
14 substitutions.magicalSedExpression = let
15 # Looks weird? Of course, it's between single quoted shell strings.
16 # NOTE: Order DOES matter here, so single character quotes need to be
17 # at the last position.
18 quoteVariants = [ "'\"'''\"'" "\"\"\"" "\"" "'\"'\"'" ]; # hey Vim: ''
19
20 mkStringSkipper = labelNum: quote: let
21 label = "q${toString labelNum}";
22 isSingle = elem quote [ "\"" "'\"'\"'" ];
23 endQuote = if isSingle then "[^\\\\]${quote}" else quote;
24 in ''
25 /^[a-z]?${quote}/ {
26 /${quote}${quote}|${quote}.*${endQuote}/{n;br}
27 :${label}; n; /^${quote}/{n;br}; /${endQuote}/{n;br}; b${label}
28 }
29 '';
30
31 # This preamble does two things:
32 # * Sets argv[0] to the original application's name; otherwise it would be .foo-wrapped.
33 # Python doesn't support `exec -a`.
34 # * Adds all required libraries to sys.path via `site.addsitedir`. It also handles *.pth files.
35 preamble = ''
36 import sys
37 import site
38 import functools
39 sys.argv[0] = '"'$(readlink -f "$f")'"'
40 functools.reduce(lambda k, p: site.addsitedir(p, k), ['"$([ -n "$program_PYTHONPATH" ] && (echo "'$program_PYTHONPATH'" | sed "s|:|','|g") || true)"'], site._init_pathinfo())
41 '';
42
43 in ''
44 1 {
45 :r
46 /\\$|,$/{N;br}
47 /__future__|^ |^ *(#.*)?$/{n;br}
48 ${concatImapStrings mkStringSkipper quoteVariants}
49 /^[^# ]/i ${replaceStrings ["\n"] [";"] preamble}
50 }
51 '';
52} ./wrap.sh