From 345b35c48af0c6534fc649ef4b2050ebf0b91d50 Mon Sep 17 00:00:00 2001 From: Frederik Rietdijk Date: Tue, 21 Mar 2017 10:08:10 +0100 Subject: [PATCH] Python: add buildPythonPackage.overridePythonPackage method. This allows one to always override the call to `buildPythonPackage`. In the following example we create an environment where we have the `blaze` package using an older version of `pandas`. We override first the Python interpreter and pass `packageOverrides` which contains the overrides for packages in the package set. ``` with import {}; (let python = let packageOverrides = self: super: { pandas = super.pandas.overridePythonPackage(old: rec { version = "0.19.1"; name = "pandas-${version}"; src = super.fetchPypi { pname = "pandas"; inherit version; sha256 = "08blshqj9zj1wyjhhw3kl2vas75vhhicvv72flvf1z3jvapgw295"; }; }); }; in pkgs.python3.override {inherit packageOverrides;}; in python.withPackages(ps: [ps.blaze])).env ``` --- doc/languages-frameworks/python.md | 39 ++++++++++++++++++++++++++---- pkgs/top-level/python-packages.nix | 19 ++++++++++++++- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/doc/languages-frameworks/python.md b/doc/languages-frameworks/python.md index 8e7a8760604..c8add96a148 100644 --- a/doc/languages-frameworks/python.md +++ b/doc/languages-frameworks/python.md @@ -545,6 +545,35 @@ All parameters from `mkDerivation` function are still supported. * `catchConflicts` If `true`, abort package build if a package name appears more than once in dependency tree. Default is `true`. * `checkInputs` Dependencies needed for running the `checkPhase`. These are added to `buildInputs` when `doCheck = true`. +##### Overriding Python packages + +The `buildPythonPackage` function has a `overridePythonPackage` method that +can be used to override the package. In the following example we create an +environment where we have the `blaze` package using an older version of `pandas`. +We override first the Python interpreter and pass +`packageOverrides` which contains the overrides for packages in the package set. + +```nix +with import {}; + +(let + python = let + packageOverrides = self: super: { + pandas = super.pandas.overridePythonPackage(old: rec { + version = "0.19.1"; + name = "pandas-${version}"; + src = super.fetchPypi { + pname = "pandas"; + inherit version; + sha256 = "08blshqj9zj1wyjhhw3kl2vas75vhhicvv72flvf1z3jvapgw295"; + }; + }); + }; + in pkgs.python3.override {inherit packageOverrides;}; + +in python.withPackages(ps: [ps.blaze])).env +``` + #### `buildPythonApplication` function The `buildPythonApplication` function is practically the same as `buildPythonPackage`. @@ -754,17 +783,17 @@ In the following example we rename the `pandas` package and build it. ```nix with import {}; -let +(let python = let packageOverrides = self: super: { - pandas = super.pandas.override {name="foo";}; + pandas = super.pandas.overridePythonPackage(old: {name="foo";}); }; in pkgs.python35.override {inherit packageOverrides;}; -in python.pkgs.pandas +in python.withPackages(ps: [ps.pandas])).env ``` -Using `nix-build` on this expression will build the package `pandas` -but with the new name `foo`. +Using `nix-build` on this expression will build an environment that contains the +package `pandas` but with the new name `foo`. All packages in the package set will use the renamed package. A typical use case is to switch to another version of a certain package. diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 6df0af98295..eb5e5459450 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -35,7 +35,24 @@ let mkPythonDerivation = makeOverridable( callPackage ../development/interpreters/python/mk-python-derivation.nix { }); - buildPythonPackage = makeOverridable (callPackage ../development/interpreters/python/build-python-package.nix { + + # Derivations built with `buildPythonPackage` can already be overriden with `override`, `overrideAttrs`, and `overrideDerivation`. + # This function introduces `overridePythonPackage` and it overrides the call to `buildPythonPackage`. + makeOverridablePythonPackage = f: origArgs: + let + ff = f origArgs; + overrideWith = newArgs: origArgs // (if builtins.isFunction newArgs then newArgs origArgs else newArgs); + in + if builtins.isAttrs ff then (ff // { + overridePythonPackage = newArgs: makeOverridable f (overrideWith newArgs); + }) + else if builtins.isFunction ff then { + overridePythonPackage = newArgs: makeOverridable f (overrideWith newArgs); + __functor = self: ff; + } + else ff; + + buildPythonPackage = makeOverridablePythonPackage (callPackage ../development/interpreters/python/build-python-package.nix { inherit mkPythonDerivation; inherit bootstrapped-pip; flit = self.flit;