1{ pkgs
2, stdenv
3, lib
4, python
5}:
6
7self:
8
9let
10 inherit (self) callPackage;
11
12 namePrefix = python.libPrefix + "-";
13
14 # Derivations built with `buildPythonPackage` can already be overridden with `override`, `overrideAttrs`, and `overrideDerivation`.
15 # This function introduces `overridePythonAttrs` and it overrides the call to `buildPythonPackage`.
16 makeOverridablePythonPackage = f: lib.mirrorFunctionArgs f (origArgs:
17 let
18 args = lib.fix (lib.extends
19 (_: previousAttrs: {
20 passthru = (previousAttrs.passthru or { }) // {
21 overridePythonAttrs = newArgs: makeOverridablePythonPackage f (overrideWith newArgs);
22 };
23 })
24 (_: origArgs));
25 result = f args;
26 overrideWith = newArgs: args // (if pkgs.lib.isFunction newArgs then newArgs args else newArgs);
27 in
28 if builtins.isAttrs result then result
29 else if builtins.isFunction result then {
30 overridePythonAttrs = newArgs: makeOverridablePythonPackage f (overrideWith newArgs);
31 __functor = self: result;
32 }
33 else result);
34
35 mkPythonDerivation = if python.isPy3k then
36 ./mk-python-derivation.nix
37 else
38 ./python2/mk-python-derivation.nix;
39
40 buildPythonPackage = makeOverridablePythonPackage (lib.makeOverridable (callPackage mkPythonDerivation {
41 inherit namePrefix; # We want Python libraries to be named like e.g. "python3.6-${name}"
42 inherit toPythonModule; # Libraries provide modules
43 }));
44
45 buildPythonApplication = makeOverridablePythonPackage (lib.makeOverridable (callPackage mkPythonDerivation {
46 namePrefix = ""; # Python applications should not have any prefix
47 toPythonModule = x: x; # Application does not provide modules.
48 }));
49
50 # See build-setupcfg/default.nix for documentation.
51 buildSetupcfg = import ../../../build-support/build-setupcfg lib self;
52
53 # Check whether a derivation provides a Python module.
54 hasPythonModule = drv: drv?pythonModule && drv.pythonModule == python;
55
56 # Get list of required Python modules given a list of derivations.
57 requiredPythonModules = drvs: let
58 modules = lib.filter hasPythonModule drvs;
59 in lib.unique ([python] ++ modules ++ lib.concatLists (lib.catAttrs "requiredPythonModules" modules));
60
61 # Create a PYTHONPATH from a list of derivations. This function recurses into the items to find derivations
62 # providing Python modules.
63 makePythonPath = drvs: lib.makeSearchPath python.sitePackages (requiredPythonModules drvs);
64
65 removePythonPrefix = lib.removePrefix namePrefix;
66
67 # Convert derivation to a Python module.
68 toPythonModule = drv:
69 drv.overrideAttrs( oldAttrs: {
70 # Use passthru in order to prevent rebuilds when possible.
71 passthru = (oldAttrs.passthru or {})// {
72 pythonModule = python;
73 pythonPath = [ ]; # Deprecated, for compatibility.
74 requiredPythonModules = requiredPythonModules drv.propagatedBuildInputs;
75 };
76 });
77
78 # Convert a Python library to an application.
79 toPythonApplication = drv:
80 drv.overrideAttrs( oldAttrs: {
81 passthru = (oldAttrs.passthru or {}) // {
82 # Remove Python prefix from name so we have a "normal" name.
83 # While the prefix shows up in the store path, it won't be
84 # used by `nix-env`.
85 name = removePythonPrefix oldAttrs.name;
86 pythonModule = false;
87 };
88 });
89
90 disabled = drv: throw "${removePythonPrefix (drv.pname or drv.name)} not supported for interpreter ${python.executable}";
91
92 disabledIf = x: drv: if x then disabled drv else drv;
93
94in {
95
96 inherit lib pkgs stdenv;
97 inherit (python.passthru) isPy27 isPy37 isPy38 isPy39 isPy310 isPy311 isPy3k isPyPy pythonAtLeast pythonOlder;
98 inherit buildPythonPackage buildPythonApplication;
99 inherit hasPythonModule requiredPythonModules makePythonPath disabled disabledIf;
100 inherit toPythonModule toPythonApplication;
101 inherit buildSetupcfg;
102
103 python = toPythonModule python;
104 # Dont take pythonPackages from "global" pkgs scope to avoid mixing python versions
105 pythonPackages = self;
106
107 # Remove?
108 recursivePthLoader = toPythonModule (callPackage ../../../development/python-modules/recursive-pth-loader { });
109
110}