buildPythonPackage: overrideStdenvCompat: add position to warning message

Co-authored-by: Matt Sturgeon <matt@sturgeon.me.uk>
This commit is contained in:
Yueh-Shun Li
2026-01-27 10:46:17 +00:00
committed by Matt Sturgeon
co-authored by Matt Sturgeon
parent f83867d2d4
commit 773f5cc8c8
2 changed files with 20 additions and 13 deletions
@@ -418,10 +418,12 @@ lib.extendMkDerivation {
optional-dependencies
;
updateScript = nix-update-script { };
# __stdenvPythonCompat attribute is here for overrideStdenvCompat in `python-packages-base.nix` to work.
# It is internal and subject to changes.
# __stdenvPythonCompat[Pos] attributes are here for overrideStdenvCompat in `python-packages-base.nix` to work.
# They are internal and subject to changes.
# TODO(@ShamrockLee): Remove when overrideStdenvCompat gets removed.
${if attrs ? stdenv then "__stdenvPythonCompat" else null} = attrs.stdenv;
${if attrs ? stdenv then "__stdenvPythonCompatPos" else null} =
builtins.unsafeGetAttrPos "stdenv" attrs;
}
// attrs.passthru or { };
@@ -55,24 +55,29 @@ let
args:
let
result = f args;
getName = x: x.pname or (lib.getName (x.name or "<unnamed>"));
applyMsgStdenvArg =
name:
lib.warnIf (lib.oldestSupportedReleaseIsAtLeast 2511) ''
${name}: Passing `stdenv` directly to `buildPythonPackage` or `buildPythonApplication` is deprecated. You should use their `.override` function instead, e.g:
buildPythonPackage.override { stdenv = customStdenv; } { }
'';
handleStdenvArg =
attrs: attrName:
let
name = attrs.pname or (lib.getName (attrs.name or "<unnamed>"));
pos = attrs.__stdenvPythonCompatPos or (builtins.unsafeGetAttrPos attrName attrs);
msg = [
"${name}: Passing `stdenv` directly to `buildPythonPackage` or `buildPythonApplication` is deprecated. You should use their `.override` function instead, e.g:"
" buildPythonPackage.override { stdenv = customStdenv; } { }"
]
++ lib.optionals (pos != null) [
"`stdenv` argument found at ${pos.file}:${toString pos.line}"
];
in
lib.warnIf (lib.oldestSupportedReleaseIsAtLeast 2511) (lib.concatLines msg) attrs.${attrName};
in
if lib.isFunction args && result ? __stdenvPythonCompat then
# Less reliable, as constructing with the wrong `stdenv` might lead to evaluation errors in the package definition.
f'.override { stdenv = applyMsgStdenvArg (getName result) result.__stdenvPythonCompat; } (
f'.override { stdenv = handleStdenvArg result "__stdenvPythonCompat"; } (
finalAttrs: removeAttrs (args finalAttrs) [ "stdenv" ]
)
else if (!lib.isFunction args) && (args ? stdenv) then
# More reliable, but only works when args is not `(finalAttrs: { })`
f'.override { stdenv = applyMsgStdenvArg (getName args) args.stdenv; } (
removeAttrs args [ "stdenv" ]
)
f'.override { stdenv = handleStdenvArg args "stdenv"; } (removeAttrs args [ "stdenv" ])
else
result
)