Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion pkgs/development/interpreters/python/hooks/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,19 @@ in {
pypaBuildHook = callPackage ({ makePythonHook, build, wheel }:
makePythonHook {
name = "pypa-build-hook.sh";
propagatedBuildInputs = [ build wheel ];
propagatedBuildInputs = [ wheel ];
substitutions = {
inherit build;
};
# A test to ensure that this hook never propagates any of its dependencies
# into the build environment.
# This prevents false positive alerts raised by catchConflictsHook.
# Such conflicts don't happen within the standard nixpkgs python package
# set, but in downstream projects that build packages depending on other
# versions of this hook's dependencies.
passthru.tests = import ./pypa-build-hook-tests.nix {
inherit pythonForBuild runCommand;
};
} ./pypa-build-hook.sh) {
inherit (pythonForBuild.pkgs) build;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{ pythonForBuild, runCommand }: {
dont-propagate-conflicting-deps = let
# customize a package so that its store paths differs
mkConflict = pkg: pkg.overrideAttrs { some_modification = true; };
# minimal pyproject.toml for the example project
pyprojectToml = builtins.toFile "pyproject.toml" ''
[project]
name = "my-project"
version = "1.0.0"
'';
# the source of the example project
projectSource = runCommand "my-project-source" {} ''
mkdir -p $out/src
cp ${pyprojectToml} $out/pyproject.toml
touch $out/src/__init__.py
'';
in
# this build must never triger conflicts
pythonForBuild.pkgs.buildPythonPackage {
pname = "dont-propagate-conflicting-deps";
version = "0.0.0";
src = projectSource;
format = "pyproject";
propagatedBuildInputs = [
# At least one dependency of `build` should be included here to
# keep the test meaningful
(mkConflict pythonForBuild.pkgs.tomli)
# setuptools is also needed to build the example project
pythonForBuild.pkgs.setuptools
];
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pypaBuildPhase() {
runHook preBuild

echo "Creating a wheel..."
pyproject-build --no-isolation --outdir dist/ --wheel $pypaBuildFlags
@build@/bin/pyproject-build --no-isolation --outdir dist/ --wheel $pypaBuildFlags
echo "Finished creating a wheel..."

runHook postBuild
Expand Down
33 changes: 27 additions & 6 deletions pkgs/development/python-modules/bootstrap/build/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@
, packaging
, pyproject-hooks
, tomli
, makeWrapper
}:
let
buildBootstrapPythonModule = basePackage: attrs: stdenv.mkDerivation ({
pname = "${python.libPrefix}-bootstrap-${basePackage.pname}";
inherit (basePackage) version src meta;

nativeBuildInputs = [ makeWrapper ];

buildPhase = ''
runHook preBuild

Expand All @@ -38,12 +41,30 @@ let
bootstrap-pyproject-hooks = buildBootstrapPythonModule pyproject-hooks {};

bootstrap-tomli = buildBootstrapPythonModule tomli {};

sitePkgs = python.sitePackages;
in
buildBootstrapPythonModule build {
propagatedBuildInputs = [
bootstrap-packaging
bootstrap-pyproject-hooks
] ++ lib.optionals (python.pythonOlder "3.11") [
bootstrap-tomli
];
# like the installPhase above, but wrapping the pyproject-build command
# to set up PYTHONPATH with the correct dependencies.
# This allows using `pyproject-build` without propagating its dependencies
# into the build environment, which is necessary to prevent
# pythonCatchConflicts from raising false positive alerts.
# This would happen whenever the package to build has a dependency on
# another version of a package that is also a dependency of pyproject-build.
installPhase = ''
runHook preInstall

PYTHONPATH="${installer}/${python.sitePackages}" \
${python.interpreter} -m installer \
--destdir "$out" --prefix "" dist/*.whl

wrapProgram $out/bin/pyproject-build \
--prefix PYTHONPATH : "$out/${sitePkgs}" \
--prefix PYTHONPATH : "${bootstrap-pyproject-hooks}/${sitePkgs}" \
--prefix PYTHONPATH : "${bootstrap-packaging}/${sitePkgs}" \
--prefix PYTHONPATH : "${bootstrap-tomli}/${sitePkgs}"

runHook postInstall
'';
}