diff --git a/pkgs/development/interpreters/python/python-packages-base.nix b/pkgs/development/interpreters/python/python-packages-base.nix index 47466d3171fe47..5569606f113aab 100644 --- a/pkgs/development/interpreters/python/python-packages-base.nix +++ b/pkgs/development/interpreters/python/python-packages-base.nix @@ -14,6 +14,9 @@ let # Derivations built with `buildPythonPackage` can already be overridden with `override`, `overrideAttrs`, and `overrideDerivation`. # This function introduces `overridePythonAttrs` and it overrides the call to `buildPythonPackage`. + # + # Overridings specified through `overridePythonAttrs` will always be applied + # before those specified by `overrideAttrs`, even if invoked after them. makeOverridablePythonPackage = f: let @@ -33,9 +36,15 @@ let overrideWith = newArgs: args // lib.toFunction newArgs args; overridePythonAttrs = mirrorArgs (newArgs: makeOverridablePythonPackage f (overrideWith newArgs)); + + # Change the result of the function call by applying g to it + overrideResult = g: makeOverridablePythonPackage (mirrorArgs (args: g (f args))) origArgs; in if builtins.isAttrs result then result + // lib.optionalAttrs (result ? overrideAttrs) { + overrideAttrs = fdrv: overrideResult (drv: drv.overrideAttrs fdrv); + } else if builtins.isFunction result then { inherit overridePythonAttrs; diff --git a/pkgs/test/overriding.nix b/pkgs/test/overriding.nix index 1bcb4e32e08997..14b67f44fb7c2f 100644 --- a/pkgs/test/overriding.nix +++ b/pkgs/test/overriding.nix @@ -205,6 +205,15 @@ let dontWrapPythonPrograms = false; }); checkOverridePythonAttrs = p: !lib.hasInfix "wrapPythonPrograms" p.postFixup; + overrideAttrsFooBar = + drv: + drv.overrideAttrs ( + finalAttrs: previousAttrs: { + FOO = "a"; + BAR = finalAttrs.FOO; + } + ); + checkAttrsFooBar = drv: drv.FOO == "a" && drv.BAR == "a"; in { overridePythonAttrs = { @@ -215,6 +224,20 @@ let expr = revertOverridePythonAttrs (applyOverridePythonAttrs pip) == pip; expected = true; }; + overrideAttrs-overridePythonAttrs-test-overrideAttrs = { + expr = checkAttrsFooBar (applyOverridePythonAttrs (overrideAttrsFooBar pip)); + expected = true; + }; + overrideAttrs-overridePythonAttrs-test-overridePythonAttrs = { + expr = checkOverridePythonAttrs (applyOverridePythonAttrs (overrideAttrsFooBar pip)); + expected = true; + }; + overrideAttrs-overridePythonAttrs-test-commutation = { + expr = + (applyOverridePythonAttrs (overrideAttrsFooBar pip)) + == (overrideAttrsFooBar (applyOverridePythonAttrs pip)); + expected = true; + }; }; in