| 
2 | 2 | 
 
  | 
3 | 3 | let  | 
4 | 4 |   inherit (pkgs) stdenv;  | 
5 |  | -  inherit (lib) isDerivation isAttrs;  | 
 | 5 | +  inherit (lib) isDerivation isAttrs listToAttrs;  | 
 | 6 | +  inherit (builtins)  | 
 | 7 | +    concatMap  | 
 | 8 | +    elem  | 
 | 9 | +    attrNames  | 
 | 10 | +    mapAttrs  | 
 | 11 | +    isFunction  | 
 | 12 | +    isList  | 
 | 13 | +    typeOf  | 
 | 14 | +    filter  | 
 | 15 | +    ;  | 
6 | 16 | 
 
  | 
7 | 17 | in  | 
8 | 18 | {  | 
 | 
192 | 202 |         rustc  | 
193 | 203 |       ];  | 
194 | 204 |     });  | 
 | 205 | + | 
 | 206 | +  /**  | 
 | 207 | +    Create a nixpkgs Python (buildPythonPackage) compatible package from a pyproject.nix build package.  | 
 | 208 | +
  | 
 | 209 | +    Adapts a package by:  | 
 | 210 | +    - Activating a wheel output, if not already enabled  | 
 | 211 | +    - Create a package using generated wheel as input  | 
 | 212 | +
  | 
 | 213 | +    # Example  | 
 | 214 | +
  | 
 | 215 | +    ```nix  | 
 | 216 | +    toNixpkgs {  | 
 | 217 | +      inherit pythonSet;  | 
 | 218 | +      packages = [ "requests" ];  | 
 | 219 | +    }  | 
 | 220 | +    =>  | 
 | 221 | +    «lambda @ /nix/store/f05hjk9fh1m5py5j1ixzly07p4lla56x-source/build/hacks/default.nix:263:5»  | 
 | 222 | +    ```  | 
 | 223 | +
  | 
 | 224 | +    # Type  | 
 | 225 | +
  | 
 | 226 | +    ```  | 
 | 227 | +    nixpkgsPrebuilt :: AttrSet -> derivation  | 
 | 228 | +    ```  | 
 | 229 | +
  | 
 | 230 | +    # Arguments  | 
 | 231 | +
  | 
 | 232 | +    pythonSet  | 
 | 233 | +    : Pyproject.nix build Python package set  | 
 | 234 | +
  | 
 | 235 | +    packages  | 
 | 236 | +    : List/predicate of overlay member packages  | 
 | 237 | +  */  | 
 | 238 | +  toNixpkgs =  | 
 | 239 | +    let  | 
 | 240 | +      # Always filter out when generating set  | 
 | 241 | +      wellKnown = [  | 
 | 242 | +        "python"  | 
 | 243 | +        "pkgs"  | 
 | 244 | +        "stdenv"  | 
 | 245 | +        "pythonPkgsBuildHost"  | 
 | 246 | +        "resolveBuildSystem"  | 
 | 247 | +        "resolveVirtualEnv"  | 
 | 248 | +        "mkVirtualEnv"  | 
 | 249 | +        "hooks"  | 
 | 250 | +      ];  | 
 | 251 | +    in  | 
 | 252 | +    {  | 
 | 253 | +      pythonSet,  | 
 | 254 | +      packages ? null,  | 
 | 255 | +    }:  | 
 | 256 | +    let  | 
 | 257 | +      packages' =  | 
 | 258 | +        if (packages == null || isFunction packages) then  | 
 | 259 | +          (  | 
 | 260 | +            let  | 
 | 261 | +              hookNames = attrNames pythonSet.hooks;  | 
 | 262 | +              predicate = if packages == null then (_: true) else packages;  | 
 | 263 | +            in  | 
 | 264 | +            filter (name: !elem name wellKnown && !elem name hookNames && predicate name) (attrNames pythonSet)  | 
 | 265 | +          )  | 
 | 266 | +        else if isList packages then  | 
 | 267 | +          packages  | 
 | 268 | +        else  | 
 | 269 | +          throw "Unhandled packages type: ${typeOf packages}";  | 
 | 270 | + | 
 | 271 | +      # Ensure wheel artifacts are created for all packages we are generating from  | 
 | 272 | +      pythonSet' = pythonSet.overrideScope (  | 
 | 273 | +        _final: prev:  | 
 | 274 | +        listToAttrs (  | 
 | 275 | +          map (  | 
 | 276 | +            name:  | 
 | 277 | +            let  | 
 | 278 | +              drv = prev.${name};  | 
 | 279 | +            in  | 
 | 280 | +            {  | 
 | 281 | +              inherit name;  | 
 | 282 | +              value =  | 
 | 283 | +                if elem "dist" (drv.outputs or [ ]) then  | 
 | 284 | +                  drv  | 
 | 285 | +                else  | 
 | 286 | +                  drv.overrideAttrs (old: {  | 
 | 287 | +                    outputs = (old.outputs or [ "out" ]) ++ [ "dist" ];  | 
 | 288 | +                  });  | 
 | 289 | +            }  | 
 | 290 | +          ) packages'  | 
 | 291 | +        )  | 
 | 292 | +      );  | 
 | 293 | +    in  | 
 | 294 | +    pythonPackagesFinal: _pythonPackagesPrev:  | 
 | 295 | +    let  | 
 | 296 | +      inherit (pythonPackagesFinal) buildPythonPackage pkgs;  | 
 | 297 | +      inherit (pkgs) autoPatchelfHook;  | 
 | 298 | +    in  | 
 | 299 | +    listToAttrs (  | 
 | 300 | +      map (  | 
 | 301 | +        name:  | 
 | 302 | +        let  | 
 | 303 | +          from = pythonSet'.${name};  | 
 | 304 | +          dependencies = from.passthru.dependencies or { };  | 
 | 305 | +          optional-dependencies = from.passthru.optional-dependencies or { };  | 
 | 306 | +        in  | 
 | 307 | +        {  | 
 | 308 | +          inherit name;  | 
 | 309 | +          value = buildPythonPackage {  | 
 | 310 | +            inherit (from) pname version;  | 
 | 311 | +            src = from.dist;  | 
 | 312 | + | 
 | 313 | +            format = "wheel";  | 
 | 314 | +            dontBuild = true;  | 
 | 315 | + | 
 | 316 | +            # Default wheelUnpackPhase assumes we are passing a single wheel, but we are passing a dist dir  | 
 | 317 | +            unpackPhase = ''  | 
 | 318 | +              runHook preUnpack  | 
 | 319 | +              mkdir dist  | 
 | 320 | +              cp ${from.dist}/* dist/  | 
 | 321 | +              # runHook postUnpack # Calls find...?  | 
 | 322 | +            '';  | 
 | 323 | + | 
 | 324 | +            # Include any buildInputs from build for autoPatchelfHook  | 
 | 325 | +            buildInputs = from.buildInputs or [ ];  | 
 | 326 | + | 
 | 327 | +            nativeBuildInputs = lib.optional stdenv.isLinux [  | 
 | 328 | +              autoPatchelfHook  | 
 | 329 | +            ];  | 
 | 330 | + | 
 | 331 | +            propagatedBuildInputs = concatMap (  | 
 | 332 | +              name:  | 
 | 333 | +              let  | 
 | 334 | +                pkg = pythonPackagesFinal.${name};  | 
 | 335 | +                extras = dependencies.${name};  | 
 | 336 | +              in  | 
 | 337 | +              [ pkg ] ++ concatMap (extra: pkg.optional-dependencies.${extra}) extras  | 
 | 338 | +            ) (attrNames dependencies);  | 
 | 339 | + | 
 | 340 | +            passthru = {  | 
 | 341 | +              optional-dependencies = mapAttrs (  | 
 | 342 | +                name: dependencies:  | 
 | 343 | +                concatMap (  | 
 | 344 | +                  name:  | 
 | 345 | +                  let  | 
 | 346 | +                    pkg = pythonPackagesFinal.${name};  | 
 | 347 | +                    extras = dependencies.${name};  | 
 | 348 | +                  in  | 
 | 349 | +                  [ pkg ] ++ concatMap (extra: pkg.optional-dependencies.${extra}) extras  | 
 | 350 | +                ) (attrNames dependencies)  | 
 | 351 | +              ) optional-dependencies;  | 
 | 352 | +            };  | 
 | 353 | + | 
 | 354 | +            # Note: PEP-735 dependency groups are dropped as nixpkgs lacks support.  | 
 | 355 | +          };  | 
 | 356 | +        }  | 
 | 357 | +      ) packages'  | 
 | 358 | +    );  | 
195 | 359 | }  | 
0 commit comments