nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at python-updates 199 lines 6.4 kB view raw
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}