From 13aafb0f1de03fddb6f7fe33273e48b3bcbdc1a6 Mon Sep 17 00:00:00 2001 From: Yueh-Shun Li Date: Sat, 28 Oct 2023 01:56:02 +0000 Subject: [PATCH] makeOverridablePythonPackage: take care of overrideAttrs Make it possible to mix overridePythonAttrs and overrideAttrs, i.e. ((.overrideAttrs (_: { foo = "a"; })).overridePythonAttrs (_: { })).foo now works --- .../python/python-packages-base.nix | 32 ++++++++++--------- pkgs/test/overriding.nix | 23 +++++++++++++ 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/pkgs/development/interpreters/python/python-packages-base.nix b/pkgs/development/interpreters/python/python-packages-base.nix index 47466d3171fe47..9098624886d999 100644 --- a/pkgs/development/interpreters/python/python-packages-base.nix +++ b/pkgs/development/interpreters/python/python-packages-base.nix @@ -14,8 +14,10 @@ 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`. - makeOverridablePythonPackage = - f: + # + # Overridings specified through `overridePythonAttrs` will always be applied + # before those specified by `overrideAttrs`, even if invoked after them. + makeOverridablePythonPackage = f: let mirrorArgs = lib.mirrorFunctionArgs f; in @@ -31,19 +33,19 @@ let ); result = f args; - overrideWith = newArgs: args // lib.toFunction newArgs args; - overridePythonAttrs = mirrorArgs (newArgs: makeOverridablePythonPackage f (overrideWith newArgs)); - in - if builtins.isAttrs result then - result - else if builtins.isFunction result then - { - inherit overridePythonAttrs; - __functor = self: result; - } - else - result - ); + 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; + __functor = self: result; + } + else result); mkPythonDerivation = if python.isPy3k then ./mk-python-derivation.nix else ./python2/mk-python-derivation.nix; 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