at master 4.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 makeOverridablePythonPackage = 18 f: 19 lib.mirrorFunctionArgs f ( 20 origArgs: 21 let 22 args = lib.fix ( 23 lib.extends (_: previousAttrs: { 24 passthru = (previousAttrs.passthru or { }) // { 25 overridePythonAttrs = newArgs: makeOverridablePythonPackage f (overrideWith newArgs); 26 }; 27 }) (_: origArgs) 28 ); 29 result = f args; 30 overrideWith = newArgs: args // (if pkgs.lib.isFunction newArgs then newArgs args else newArgs); 31 in 32 if builtins.isAttrs result then 33 result 34 else if builtins.isFunction result then 35 { 36 overridePythonAttrs = newArgs: makeOverridablePythonPackage f (overrideWith newArgs); 37 __functor = self: result; 38 } 39 else 40 result 41 ); 42 43 mkPythonDerivation = 44 if python.isPy3k then ./mk-python-derivation.nix else ./python2/mk-python-derivation.nix; 45 46 buildPythonPackage = makeOverridablePythonPackage ( 47 callPackage mkPythonDerivation { 48 inherit namePrefix; # We want Python libraries to be named like e.g. "python3.6-${name}" 49 inherit toPythonModule; # Libraries provide modules 50 } 51 ); 52 53 buildPythonApplication = makeOverridablePythonPackage ( 54 callPackage mkPythonDerivation { 55 namePrefix = ""; # Python applications should not have any prefix 56 toPythonModule = x: x; # Application does not provide modules. 57 } 58 ); 59 60 # Check whether a derivation provides a Python module. 61 hasPythonModule = drv: drv ? pythonModule && drv.pythonModule == python; 62 63 # Get list of required Python modules given a list of derivations. 64 requiredPythonModules = 65 drvs: 66 let 67 modules = lib.filter hasPythonModule drvs; 68 in 69 lib.unique ( 70 [ python ] ++ modules ++ lib.concatLists (lib.catAttrs "requiredPythonModules" modules) 71 ); 72 73 # Create a PYTHONPATH from a list of derivations. This function recurses into the items to find derivations 74 # providing Python modules. 75 makePythonPath = drvs: lib.makeSearchPath python.sitePackages (requiredPythonModules drvs); 76 77 removePythonPrefix = lib.removePrefix namePrefix; 78 79 mkPythonEditablePackage = callPackage ./editable.nix { }; 80 81 mkPythonMetaPackage = callPackage ./meta-package.nix { }; 82 83 # Convert derivation to a Python module. 84 toPythonModule = 85 drv: 86 drv.overrideAttrs (oldAttrs: { 87 # Use passthru in order to prevent rebuilds when possible. 88 passthru = (oldAttrs.passthru or { }) // { 89 pythonModule = python; 90 pythonPath = [ ]; # Deprecated, for compatibility. 91 requiredPythonModules = builtins.addErrorContext "while calculating requiredPythonModules for ${drv.name or drv.pname}:" ( 92 requiredPythonModules drv.propagatedBuildInputs 93 ); 94 }; 95 }); 96 97 # Convert a Python library to an application. 98 toPythonApplication = 99 drv: 100 drv.overrideAttrs (oldAttrs: { 101 passthru = (oldAttrs.passthru or { }) // { 102 # Remove Python prefix from name so we have a "normal" name. 103 # While the prefix shows up in the store path, it won't be 104 # used by `nix-env`. 105 name = removePythonPrefix oldAttrs.name; 106 pythonModule = false; 107 }; 108 }); 109 110 disabled = 111 drv: 112 throw "${ 113 removePythonPrefix (drv.pname or drv.name) 114 } not supported for interpreter ${python.executable}"; 115 116 disabledIf = x: drv: if x then disabled drv else drv; 117 118in 119{ 120 inherit lib pkgs stdenv; 121 inherit (python.passthru) 122 isPy27 123 isPy37 124 isPy38 125 isPy39 126 isPy310 127 isPy311 128 isPy312 129 isPy313 130 isPy314 131 isPy3k 132 isPyPy 133 pythonAtLeast 134 pythonOlder 135 ; 136 inherit buildPythonPackage buildPythonApplication; 137 inherit 138 hasPythonModule 139 requiredPythonModules 140 makePythonPath 141 disabled 142 disabledIf 143 ; 144 inherit toPythonModule toPythonApplication; 145 inherit mkPythonMetaPackage mkPythonEditablePackage; 146 147 python = toPythonModule python; 148 149 # Don't take pythonPackages from "global" pkgs scope to avoid mixing python versions. 150 pythonPackages = self; 151}