2019-12-13 16:56:51 +01:00
|
|
|
{ autoPatchelfHook
|
|
|
|
, lib
|
|
|
|
, python
|
|
|
|
, buildPythonPackage
|
|
|
|
, poetryLib
|
2020-10-01 15:57:14 +02:00
|
|
|
, evalPep508
|
2019-12-13 16:56:51 +01:00
|
|
|
}:
|
|
|
|
{ name
|
|
|
|
, version
|
|
|
|
, files
|
2019-12-27 19:16:55 +00:00
|
|
|
, source
|
2020-04-29 14:12:59 +01:00
|
|
|
, dependencies ? { }
|
2019-12-29 12:51:22 +00:00
|
|
|
, pythonPackages
|
2019-12-13 16:56:51 +01:00
|
|
|
, python-versions
|
2019-12-29 12:51:22 +00:00
|
|
|
, pwd
|
2020-03-27 18:58:32 +00:00
|
|
|
, sourceSpec
|
2019-12-13 16:56:51 +01:00
|
|
|
, supportedExtensions ? lib.importJSON ./extensions.json
|
2020-04-21 16:49:01 +02:00
|
|
|
, preferWheels ? false
|
2019-12-13 16:56:51 +01:00
|
|
|
, ...
|
2020-01-12 19:27:19 +00:00
|
|
|
}:
|
2019-12-13 16:56:51 +01:00
|
|
|
|
2020-04-29 14:12:59 +01:00
|
|
|
pythonPackages.callPackage
|
|
|
|
(
|
|
|
|
{ preferWheel ? preferWheels
|
|
|
|
, ...
|
|
|
|
}@args:
|
2020-01-12 19:27:19 +00:00
|
|
|
let
|
2022-01-19 03:56:47 +12:00
|
|
|
inherit (python) stdenv;
|
2022-09-29 20:39:37 +03:00
|
|
|
inherit (poetryLib) isCompatible getManyLinuxDeps fetchFromLegacy fetchFromPypi normalizePackageName;
|
2019-12-29 12:51:22 +00:00
|
|
|
|
2020-01-12 19:27:19 +00:00
|
|
|
inherit (import ./pep425.nix {
|
2022-01-19 03:56:47 +12:00
|
|
|
inherit lib poetryLib python stdenv;
|
2020-01-12 19:27:19 +00:00
|
|
|
}) selectWheel
|
|
|
|
;
|
2020-04-29 14:12:59 +01:00
|
|
|
fileCandidates =
|
|
|
|
let
|
2021-05-31 04:15:54 +02:00
|
|
|
supportedRegex = ("^.*(" + builtins.concatStringsSep "|" supportedExtensions + ")");
|
2021-09-17 17:01:43 +10:00
|
|
|
matchesVersion = fname: builtins.match ("^.*" + builtins.replaceStrings [ "." "+" ] [ "\\." "\\+" ] version + ".*$") fname != null;
|
2020-04-29 14:12:59 +01:00
|
|
|
hasSupportedExtension = fname: builtins.match supportedRegex fname != null;
|
|
|
|
isCompatibleEgg = fname: ! lib.strings.hasSuffix ".egg" fname || lib.strings.hasSuffix "py${python.pythonVersion}.egg" fname;
|
|
|
|
in
|
2020-01-12 19:27:19 +00:00
|
|
|
builtins.filter (f: matchesVersion f.file && hasSupportedExtension f.file && isCompatibleEgg f.file) files;
|
|
|
|
toPath = s: pwd + "/${s}";
|
|
|
|
isSource = source != null;
|
|
|
|
isGit = isSource && source.type == "git";
|
2020-11-05 16:47:38 +00:00
|
|
|
isUrl = isSource && source.type == "url";
|
2021-07-10 13:38:34 +02:00
|
|
|
isDirectory = isSource && source.type == "directory";
|
|
|
|
isFile = isSource && source.type == "file";
|
2021-05-09 21:47:06 +02:00
|
|
|
isLegacy = isSource && source.type == "legacy";
|
2020-01-12 19:27:19 +00:00
|
|
|
localDepPath = toPath source.url;
|
2020-08-21 13:58:31 +02:00
|
|
|
|
|
|
|
buildSystemPkgs =
|
|
|
|
let
|
|
|
|
pyProjectPath = localDepPath + "/pyproject.toml";
|
|
|
|
pyProject = poetryLib.readTOML pyProjectPath;
|
|
|
|
in
|
2020-10-01 19:08:57 +02:00
|
|
|
if builtins.pathExists pyProjectPath then
|
|
|
|
poetryLib.getBuildSystemPkgs
|
|
|
|
{
|
|
|
|
inherit pythonPackages pyProject;
|
|
|
|
} else [ ];
|
2020-08-21 13:58:31 +02:00
|
|
|
|
2020-04-29 14:12:59 +01:00
|
|
|
fileInfo =
|
|
|
|
let
|
|
|
|
isBdist = f: lib.strings.hasSuffix "whl" f.file;
|
|
|
|
isSdist = f: ! isBdist f && ! isEgg f;
|
|
|
|
isEgg = f: lib.strings.hasSuffix ".egg" f.file;
|
|
|
|
binaryDist = selectWheel fileCandidates;
|
|
|
|
sourceDist = builtins.filter isSdist fileCandidates;
|
|
|
|
eggs = builtins.filter isEgg fileCandidates;
|
2020-05-19 21:06:02 +01:00
|
|
|
entries = (if preferWheel then binaryDist ++ sourceDist else sourceDist ++ binaryDist) ++ eggs;
|
2021-07-02 04:23:35 -05:00
|
|
|
lockFileEntry = (
|
|
|
|
if lib.length entries > 0 then builtins.head entries
|
|
|
|
else throw "Missing suitable source/wheel file entry for ${name}"
|
|
|
|
);
|
2020-04-29 14:12:59 +01:00
|
|
|
_isEgg = isEgg lockFileEntry;
|
|
|
|
in
|
2020-01-12 19:27:19 +00:00
|
|
|
rec {
|
|
|
|
inherit (lockFileEntry) file hash;
|
|
|
|
name = file;
|
|
|
|
format =
|
|
|
|
if _isEgg then "egg"
|
|
|
|
else if lib.strings.hasSuffix ".whl" name then "wheel"
|
2020-04-01 00:10:00 +01:00
|
|
|
else "pyproject";
|
2020-01-12 19:27:19 +00:00
|
|
|
kind =
|
|
|
|
if _isEgg then python.pythonVersion
|
2020-04-01 00:10:00 +01:00
|
|
|
else if format == "pyproject" then "source"
|
2020-01-12 19:27:19 +00:00
|
|
|
else (builtins.elemAt (lib.strings.splitString "-" name) 2);
|
|
|
|
};
|
2019-12-13 16:56:51 +01:00
|
|
|
|
2021-07-10 13:38:34 +02:00
|
|
|
format = if isDirectory || isGit || isUrl then "pyproject" else fileInfo.format;
|
2022-10-28 00:40:18 +03:00
|
|
|
|
|
|
|
hooks = python.pkgs.callPackage ./hooks { };
|
2019-12-13 16:56:51 +01:00
|
|
|
in
|
2020-04-29 14:12:59 +01:00
|
|
|
buildPythonPackage {
|
2022-09-29 20:39:37 +03:00
|
|
|
pname = normalizePackageName name;
|
2020-04-29 14:12:59 +01:00
|
|
|
version = version;
|
2020-01-12 19:27:19 +00:00
|
|
|
|
2022-10-07 21:37:53 +13:00
|
|
|
# Circumvent output separation (https://github.com/NixOS/nixpkgs/pull/190487)
|
|
|
|
format = if format == "pyproject" then "poetry2nix" else format;
|
2020-01-12 19:27:19 +00:00
|
|
|
|
2020-04-29 14:12:59 +01:00
|
|
|
doCheck = false; # We never get development deps
|
2020-01-17 18:06:09 +00:00
|
|
|
|
2020-04-29 14:12:59 +01:00
|
|
|
# Stripping pre-built wheels lead to `ELF load command address/offset not properly aligned`
|
|
|
|
dontStrip = format == "wheel";
|
2020-01-17 18:06:09 +00:00
|
|
|
|
2020-04-29 14:12:59 +01:00
|
|
|
nativeBuildInputs = [
|
2022-10-28 00:40:18 +03:00
|
|
|
hooks.poetry2nixFixupHook
|
2020-04-29 14:12:59 +01:00
|
|
|
]
|
|
|
|
++ lib.optional (!isSource && (getManyLinuxDeps fileInfo.name).str != null) autoPatchelfHook
|
2022-10-07 23:09:59 +13:00
|
|
|
++ lib.optionals (format == "wheel") [
|
2022-10-28 00:40:18 +03:00
|
|
|
hooks.wheelUnpackHook
|
2022-10-07 23:09:59 +13:00
|
|
|
pythonPackages.pipInstallHook
|
|
|
|
pythonPackages.setuptools
|
|
|
|
]
|
2021-11-07 09:50:59 -05:00
|
|
|
++ lib.optionals (format == "pyproject") [
|
2022-10-28 00:40:18 +03:00
|
|
|
hooks.removePathDependenciesHook
|
|
|
|
hooks.removeGitDependenciesHook
|
|
|
|
hooks.pipBuildHook
|
2021-11-07 09:50:59 -05:00
|
|
|
];
|
2020-02-18 15:58:31 +13:00
|
|
|
|
2020-04-29 14:12:59 +01:00
|
|
|
buildInputs = (
|
2022-09-29 20:39:37 +03:00
|
|
|
lib.optional (!isSource) (getManyLinuxDeps fileInfo.name).pkg
|
2021-07-10 13:38:34 +02:00
|
|
|
++ lib.optional isDirectory buildSystemPkgs
|
2022-09-29 20:39:37 +03:00
|
|
|
++ lib.optional (stdenv.buildPlatform != stdenv.hostPlatform) pythonPackages.setuptools
|
2020-04-29 14:12:59 +01:00
|
|
|
);
|
2020-01-12 19:27:19 +00:00
|
|
|
|
2020-04-29 14:12:59 +01:00
|
|
|
propagatedBuildInputs =
|
|
|
|
let
|
2020-04-29 13:22:20 +01:00
|
|
|
compat = isCompatible (poetryLib.getPythonVersion python);
|
2020-05-19 21:06:02 +01:00
|
|
|
deps = lib.filterAttrs
|
|
|
|
(n: v: v)
|
2020-04-29 14:12:59 +01:00
|
|
|
(
|
|
|
|
lib.mapAttrs
|
|
|
|
(
|
|
|
|
n: v:
|
|
|
|
let
|
|
|
|
constraints = v.python or "";
|
2020-10-01 15:57:14 +02:00
|
|
|
pep508Markers = v.markers or "";
|
2020-04-29 14:12:59 +01:00
|
|
|
in
|
2020-10-01 15:57:14 +02:00
|
|
|
compat constraints && evalPep508 pep508Markers
|
2020-05-19 21:06:02 +01:00
|
|
|
)
|
|
|
|
dependencies
|
2020-04-29 14:12:59 +01:00
|
|
|
);
|
2020-02-28 13:17:48 +00:00
|
|
|
depAttrs = lib.attrNames deps;
|
|
|
|
in
|
2022-09-29 20:39:37 +03:00
|
|
|
builtins.map (n: pythonPackages.${normalizePackageName n}) depAttrs;
|
2020-01-12 19:27:19 +00:00
|
|
|
|
2020-04-29 14:12:59 +01:00
|
|
|
meta = {
|
|
|
|
broken = ! isCompatible (poetryLib.getPythonVersion python) python-versions;
|
|
|
|
license = [ ];
|
|
|
|
inherit (python.meta) platforms;
|
|
|
|
};
|
2020-01-12 19:27:19 +00:00
|
|
|
|
2020-04-29 14:12:59 +01:00
|
|
|
passthru = {
|
|
|
|
inherit args;
|
|
|
|
};
|
2020-01-21 11:43:03 +00:00
|
|
|
|
2020-04-29 14:12:59 +01:00
|
|
|
# We need to retrieve kind from the interpreter and the filename of the package
|
|
|
|
# Interpreters should declare what wheel types they're compatible with (python type + ABI)
|
|
|
|
# Here we can then choose a file based on that info.
|
|
|
|
src =
|
2020-10-01 19:08:57 +02:00
|
|
|
if isGit then
|
|
|
|
(
|
2021-10-20 18:33:06 +02:00
|
|
|
builtins.fetchGit ({
|
2020-10-01 19:08:57 +02:00
|
|
|
inherit (source) url;
|
2020-10-06 14:44:26 +02:00
|
|
|
rev = source.resolved_reference or source.reference;
|
2021-10-21 10:12:35 +02:00
|
|
|
ref = sourceSpec.branch or (if sourceSpec ? tag then "refs/tags/${sourceSpec.tag}" else "HEAD");
|
2021-10-20 18:33:06 +02:00
|
|
|
} // (
|
2022-09-08 16:02:32 -04:00
|
|
|
lib.optionalAttrs ((sourceSpec ? rev) && (lib.versionAtLeast builtins.nixVersion "2.4")) {
|
2021-10-20 18:33:06 +02:00
|
|
|
allRefs = true;
|
|
|
|
}
|
|
|
|
))
|
2020-11-05 16:47:38 +00:00
|
|
|
)
|
|
|
|
else if isUrl then
|
|
|
|
builtins.fetchTarball
|
|
|
|
{
|
|
|
|
inherit (source) url;
|
|
|
|
}
|
2021-07-10 13:38:34 +02:00
|
|
|
else if isDirectory then
|
2020-11-05 16:47:38 +00:00
|
|
|
(poetryLib.cleanPythonSources { src = localDepPath; })
|
2021-07-10 13:38:34 +02:00
|
|
|
else if isFile then
|
|
|
|
localDepPath
|
2021-05-09 21:47:06 +02:00
|
|
|
else if isLegacy then
|
|
|
|
fetchFromLegacy
|
|
|
|
{
|
|
|
|
pname = name;
|
|
|
|
inherit python;
|
|
|
|
inherit (fileInfo) file hash;
|
|
|
|
inherit (source) url;
|
|
|
|
}
|
2020-11-05 16:47:38 +00:00
|
|
|
else
|
|
|
|
fetchFromPypi {
|
|
|
|
pname = name;
|
|
|
|
inherit (fileInfo) file hash kind;
|
2021-05-13 19:16:58 +02:00
|
|
|
inherit version;
|
2020-11-05 16:47:38 +00:00
|
|
|
};
|
2020-04-29 14:12:59 +01:00
|
|
|
}
|
2020-10-01 19:08:57 +02:00
|
|
|
)
|
|
|
|
{ }
|