Skip to content

Commit

Permalink
renderers: Add mkPythonEditablePackage
Browse files Browse the repository at this point in the history
  • Loading branch information
adisbladis committed Sep 4, 2024
1 parent 424e960 commit f70611f
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 2 deletions.
79 changes: 78 additions & 1 deletion lib/renderers.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
pep508,
pep440,
pep621,
renderers,
...
}:
let
Expand All @@ -19,6 +20,8 @@ let
mapAttrs
filterAttrs
concatMap
nameValuePair
isString
;

# Group licenses by their SPDX IDs for easy lookup
Expand Down Expand Up @@ -103,7 +106,7 @@ in
project,
# Python derivation
python,
# Python extras (markers) to enable.
# Python extras (optional-dependencies) to enable.
extras ? [ ],
# Map a Python extras group name to a Nix attribute set like:
# { dev = "checkInputs"; }
Expand Down Expand Up @@ -201,4 +204,78 @@ in
}
)
(attrNames filteredDeps.extras);

/*
Renders a project as an argument that can be passed to mkPythonEditablePackage.
Evaluates PEP-508 environment markers to select correct dependencies for the platform but does not validate version constraints.
For validation see `lib.validators`.
Note for Nix Flake users:
Flakes are copied to the store when using pure evaluation, meaning that the project root will point to a store directory.
Either set root manually to a string using the returned attribute set, or evaluate using `--impure`.
Type: mkPythonEditablePackage :: AttrSet -> AttrSet
Example:
# mkPythonEditablePackage { project = lib.project.loadPyproject ...; python = pkgs.python3; }
{ pname = "blinker"; version = "1.3.3.7"; dependencies = [ ]; }
*/
mkPythonEditablePackage =
let
cleanArgs = lib.flip removeAttrs [ "root" ];
in
{
# Project metadata as returned by `lib.project.loadPyproject`
project,
# Editable root directory as a string
root ? toString (
# Prefer src layout if available
if lib.pathExists (project.projectRoot + "/src") then
(project.projectRoot + "/src")
# Otherwise assume project root is editable root
else
project.projectRoot
),
# Unknown args passed on verbatim to renderers.buildPythonPackage
...
}@args:
let
# Render using buildPythonPackage
attrs = renderers.buildPythonPackage (cleanArgs args);

project' = project.pyproject.project;
in
# Reshape into mkPythonEditablePackage
assert isString root && root != "";
{
inherit (attrs)
dependencies
optional-dependencies
build-system
meta
;
inherit root;
}
// optionalAttrs (project' ? scripts) {
inherit (project') scripts;
}
// optionalAttrs (project' ? gui-scripts) {
inherit (project') gui-scripts;
}
// optionalAttrs (project' ? entry-points) {
inherit (project') entry-points;
}
// optionalAttrs (attrs ? pname) {
inherit (attrs) pname;
}
// optionalAttrs (attrs ? version) {
inherit (attrs) version;
}
// optionalAttrs (args ? extrasAttrMappings && args.extrasAttrMappings != { }) {
# Inject derivationArgs for additional functionality
derivationArgs = lib.listToAttrs (
map (attr: nameValuePair attr attrs.${attr}) (attrValues args.extrasAttrMappings)
);
};
}
1 change: 1 addition & 0 deletions lib/test_project.nix
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ lib.fix (self: {
expected = {
renderers = [
"buildPythonPackage"
"mkPythonEditablePackage"
"withPackages"
];
requires-python = null;
Expand Down
27 changes: 26 additions & 1 deletion lib/test_renderers.nix
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ let
// optionalAttrs (attrs ? checkInputs) { checkInputs = map (drv: drv.pname) attrs.checkInputs; };

in
{
rec {
# withPackages can't be easily tested by mocks, dummy out.
# Tested by integration tests.
withPackages = {
Expand All @@ -43,6 +43,31 @@ in
};
};

mkPythonEditablePackage = {
testPdm = {
expr = clearDrvInputs (
renderers.mkPythonEditablePackage {
root = "/path/to/my_root";
project = projects.pdm;
python = mocks.cpythonLinux38;
}
);
expected = {
inherit (buildPythonPackage.testPdm.expected)
dependencies
optional-dependencies
build-system
meta
pname
;
root = "/path/to/my_root";
scripts = {
pdm = "pdm.core:main";
};
};
};
};

buildPythonPackage = {
testPdm = {
expr = clearDrvInputs (
Expand Down

0 comments on commit f70611f

Please sign in to comment.