nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 pkgs,
3 stdenv,
4 lib,
5 python,
6}:
7
8self:
9
10let
11 inherit (self) callPackage;
12
13 namePrefix = python.libPrefix + "-";
14
15 # Derivations built with `buildPythonPackage` can already be overridden with `override`, `overrideAttrs`, and `overrideDerivation`.
16 # This function introduces `overridePythonAttrs` and it overrides the call to `buildPythonPackage`.
17 #
18 # Overridings specified through `overridePythonAttrs` will always be applied
19 # before those specified by `overrideAttrs`, even if invoked after them.
20 makeOverridablePythonPackage =
21 f:
22 lib.mirrorFunctionArgs f (
23 origArgs:
24 let
25 result = f origArgs;
26 overrideWith =
27 if lib.isFunction origArgs then
28 newArgs: lib.extends (_: lib.toFunction newArgs) origArgs
29 else
30 newArgs: origArgs // lib.toFunction newArgs origArgs;
31 in
32 if lib.isAttrs result then
33 result
34 // {
35 overridePythonAttrs = newArgs: makeOverridablePythonPackage f (overrideWith newArgs);
36 overrideAttrs =
37 newArgs: makeOverridablePythonPackage (args: (f args).overrideAttrs newArgs) origArgs;
38 }
39 else
40 result
41 )
42 // {
43 # Support overriding `f` itself, e.g. `buildPythonPackage.override { }`.
44 # Ensure `makeOverridablePythonPackage` is applied to the result.
45 override = lib.mirrorFunctionArgs f.override (
46 newArgs: makeOverridablePythonPackage (f.override newArgs)
47 );
48 };
49
50 overrideStdenvCompat =
51 f:
52 lib.fix (
53 f':
54 lib.mirrorFunctionArgs f (
55 args:
56 let
57 result = f args;
58 getName = x: x.pname or (lib.getName (x.name or "<unnamed>"));
59 applyMsgStdenvArg =
60 name:
61 lib.warnIf (lib.oldestSupportedReleaseIsAtLeast 2511) ''
62 ${name}: Passing `stdenv` directly to `buildPythonPackage` or `buildPythonApplication` is deprecated. You should use their `.override` function instead, e.g:
63 buildPythonPackage.override { stdenv = customStdenv; } { }
64 '';
65 in
66 if lib.isFunction args && result ? __stdenvPythonCompat then
67 # Less reliable, as constructing with the wrong `stdenv` might lead to evaluation errors in the package definition.
68 f'.override { stdenv = applyMsgStdenvArg (getName result) result.__stdenvPythonCompat; } (
69 finalAttrs: removeAttrs (args finalAttrs) [ "stdenv" ]
70 )
71 else if (!lib.isFunction args) && (args ? stdenv) then
72 # More reliable, but only works when args is not `(finalAttrs: { })`
73 f'.override { stdenv = applyMsgStdenvArg (getName args) args.stdenv; } (
74 removeAttrs args [ "stdenv" ]
75 )
76 else
77 result
78 )
79 // {
80 # Preserve the effect of overrideStdenvCompat when calling `buildPython*.override`.
81 override = lib.mirrorFunctionArgs f.override (newArgs: overrideStdenvCompat (f.override newArgs));
82 }
83 );
84
85 mkPythonDerivation =
86 if python.isPy3k then ./mk-python-derivation.nix else ./python2/mk-python-derivation.nix;
87
88 buildPythonPackage = makeOverridablePythonPackage (
89 overrideStdenvCompat (
90 callPackage mkPythonDerivation {
91 inherit namePrefix; # We want Python libraries to be named like e.g. "python3.6-${name}"
92 inherit toPythonModule; # Libraries provide modules
93 inherit (python) stdenv;
94 }
95 )
96 );
97
98 buildPythonApplication = makeOverridablePythonPackage (
99 overrideStdenvCompat (
100 callPackage mkPythonDerivation {
101 namePrefix = ""; # Python applications should not have any prefix
102 toPythonModule = x: x; # Application does not provide modules.
103 inherit (python) stdenv;
104 }
105 )
106 );
107
108 # Check whether a derivation provides a Python module.
109 hasPythonModule = drv: drv ? pythonModule && drv.pythonModule == python;
110
111 # Get list of required Python modules given a list of derivations.
112 requiredPythonModules =
113 drvs:
114 let
115 modules = lib.filter hasPythonModule drvs;
116 in
117 lib.unique (
118 [ python ] ++ modules ++ lib.concatLists (lib.catAttrs "requiredPythonModules" modules)
119 );
120
121 # Create a PYTHONPATH from a list of derivations. This function recurses into the items to find derivations
122 # providing Python modules.
123 makePythonPath = drvs: lib.makeSearchPath python.sitePackages (requiredPythonModules drvs);
124
125 removePythonPrefix = lib.removePrefix namePrefix;
126
127 mkPythonEditablePackage = callPackage ./editable.nix { };
128
129 mkPythonMetaPackage = callPackage ./meta-package.nix { };
130
131 # Convert derivation to a Python module.
132 toPythonModule =
133 drv:
134 drv.overrideAttrs (oldAttrs: {
135 # Use passthru in order to prevent rebuilds when possible.
136 passthru = (oldAttrs.passthru or { }) // {
137 pythonModule = python;
138 pythonPath = [ ]; # Deprecated, for compatibility.
139 requiredPythonModules = builtins.addErrorContext "while calculating requiredPythonModules for ${drv.name or drv.pname}:" (
140 requiredPythonModules drv.propagatedBuildInputs
141 );
142 };
143 });
144
145 # Convert a Python library to an application.
146 toPythonApplication =
147 drv:
148 drv.overrideAttrs (oldAttrs: {
149 passthru = (oldAttrs.passthru or { }) // {
150 # Remove Python prefix from name so we have a "normal" name.
151 # While the prefix shows up in the store path, it won't be
152 # used by `nix-env`.
153 name = removePythonPrefix oldAttrs.name;
154 pythonModule = false;
155 };
156 });
157
158 disabled =
159 drv:
160 throw "${
161 removePythonPrefix (drv.pname or drv.name)
162 } not supported for interpreter ${python.executable}";
163
164 disabledIf = x: drv: if x then disabled drv else drv;
165
166in
167{
168 inherit lib pkgs stdenv;
169 inherit (python.passthru)
170 isPy27
171 isPy37
172 isPy38
173 isPy39
174 isPy310
175 isPy311
176 isPy312
177 isPy313
178 isPy314
179 isPy3k
180 isPyPy
181 pythonAtLeast
182 pythonOlder
183 ;
184 inherit buildPythonPackage buildPythonApplication;
185 inherit
186 hasPythonModule
187 requiredPythonModules
188 makePythonPath
189 disabled
190 disabledIf
191 ;
192 inherit toPythonModule toPythonApplication;
193 inherit mkPythonMetaPackage mkPythonEditablePackage;
194
195 python = toPythonModule python;
196
197 # Don't take pythonPackages from "global" pkgs scope to avoid mixing python versions.
198 pythonPackages = self;
199}