at 24.11-pre 4.0 kB view raw
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 # Check whether a derivation provides a Python module. 51 hasPythonModule = drv: drv?pythonModule && drv.pythonModule == python; 52 53 # Get list of required Python modules given a list of derivations. 54 requiredPythonModules = drvs: let 55 modules = lib.filter hasPythonModule drvs; 56 in lib.unique ([python] ++ modules ++ lib.concatLists (lib.catAttrs "requiredPythonModules" modules)); 57 58 # Create a PYTHONPATH from a list of derivations. This function recurses into the items to find derivations 59 # providing Python modules. 60 makePythonPath = drvs: lib.makeSearchPath python.sitePackages (requiredPythonModules drvs); 61 62 removePythonPrefix = lib.removePrefix namePrefix; 63 64 # Convert derivation to a Python module. 65 toPythonModule = drv: 66 drv.overrideAttrs( oldAttrs: { 67 # Use passthru in order to prevent rebuilds when possible. 68 passthru = (oldAttrs.passthru or {})// { 69 pythonModule = python; 70 pythonPath = [ ]; # Deprecated, for compatibility. 71 requiredPythonModules = 72 builtins.addErrorContext 73 "while calculating requiredPythonModules for ${drv.name or drv.pname}:" 74 (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 inherit lib pkgs stdenv; 96 inherit (python.passthru) isPy27 isPy37 isPy38 isPy39 isPy310 isPy311 isPy3k isPyPy pythonAtLeast pythonOlder; 97 inherit buildPythonPackage buildPythonApplication; 98 inherit hasPythonModule requiredPythonModules makePythonPath disabled disabledIf; 99 inherit toPythonModule toPythonApplication; 100 101 python = toPythonModule python; 102 # Dont take pythonPackages from "global" pkgs scope to avoid mixing python versions 103 pythonPackages = self; 104}