Add wheel file selection according to pep425

Provides a `select` function that picks the most appropriate `.whl` file
based on platform, arch, python version and manylinux/OSX - version.

Unit tests for pep425 are provided as well.
This commit is contained in:
Tobias Pflug 2019-12-10 10:21:22 +01:00
parent df82c7d72c
commit 148fd890c6
3 changed files with 248 additions and 0 deletions

96
pep425.nix Normal file
View file

@ -0,0 +1,96 @@
{ lib, stdenv, python, isLinux ? stdenv.isLinux }:
let
inherit (lib.strings) hasSuffix hasInfix splitString removeSuffix;
# The 'cpxy" as determined by `python.version`
#
# e.g "2.7.17" -> "cp27"
# "3.5.9" -> "cp35"
pythonTag =
let
ver = builtins.splitVersion python.version;
major = builtins.elemAt ver 0;
minor = builtins.elemAt ver 1;
in
"cp${major}${minor}";
abiTag = "${pythonTag}m";
#
# Parses wheel file returning an attribute set
#
toWheelAttrs = str:
let
entries = splitString "-" str;
p = removeSuffix ".whl" (builtins.elemAt entries 4);
in
{
pkgName = builtins.elemAt entries 0;
pkgVer = builtins.elemAt entries 1;
pyVer = builtins.elemAt entries 2;
abi = builtins.elemAt entries 3;
platform = p;
};
#
# Renders a wheel attribute set into a string
#
# e.g (toFile (toWheelAttrs x)) == x
toFileName = x: "${x.pkgName}-${x.pkgVer}-${x.pyVer}-${x.abi}-${x.platform}.whl";
#
# Builds list of acceptable osx wheel files
#
# <versions> accepted versions in descending order of preference
# <candidates> list of wheel files to select from
findBestMatches = versions: candidates:
let
v = lib.lists.head versions;
vs = lib.lists.tail versions;
in
if (builtins.length versions == 0)
then []
else (builtins.filter (x: hasInfix v x) candidates) ++ (findBestMatches vs candidates);
#
# Selects the best matching wheel file from a list of files
#
select = files:
let
filesWithoutSources = (builtins.filter (x: !hasSuffix ".tar.gz" x) files);
wheelAttrs = builtins.map toWheelAttrs filesWithoutSources;
withPython = pyver: abi: x: x.pyVer == pyver && x.abi == abi;
withPlatform = if isLinux
then (x: x.platform == "manylinux1_${stdenv.platform.kernelArch}"
|| x.platform == "manylinux2010_${stdenv.platform.kernelArch}"
|| x.platform == "manylinux2014_${stdenv.platform.kernelArch}")
else (x: hasInfix "macosx" x.platform );
filterWheel = x: (withPython pythonTag abiTag x) && (withPlatform x);
filtered = builtins.filter filterWheel wheelAttrs;
choose = files:
let
osxMatches = [ "10_12" "10_11" "10_10" "10_9" ];
linuxMatches = [ "manylinux1_" "manylinux2010_" "manylinux2014_" ];
chooseLinux = x: lib.singleton (builtins.head (findBestMatches linuxMatches x));
chooseOSX = x: lib.singleton (builtins.head (findBestMatches osxMatches x));
in
if isLinux
then chooseLinux files
else chooseOSX files;
in
if (builtins.length filtered == 0)
then []
else choose (builtins.map toFileName filtered);
in
{
inherit select;
}

View file

@ -2,10 +2,16 @@
let let
poetry = pkgs.callPackage ../pkgs/poetry { python = pkgs.python3; inherit poetry2nix; }; poetry = pkgs.callPackage ../pkgs/poetry { python = pkgs.python3; inherit poetry2nix; };
poetry2nix = import ./.. { inherit pkgs; inherit poetry; }; poetry2nix = import ./.. { inherit pkgs; inherit poetry; };
pep425 = pkgs.callPackage ../pep425.nix {};
pep425Python37 = pkgs.callPackage ../pep425.nix { python = pkgs.python37; };
pep425OSX = pkgs.callPackage ../pep425.nix { isLinux = false;};
in in
{ {
trivial = pkgs.callPackage ./override-support { inherit poetry2nix; }; trivial = pkgs.callPackage ./override-support { inherit poetry2nix; };
override = pkgs.callPackage ./override-support { inherit poetry2nix; }; override = pkgs.callPackage ./override-support { inherit poetry2nix; };
top-packages-1 = pkgs.callPackage ./common-pkgs-1 { inherit poetry2nix; }; top-packages-1 = pkgs.callPackage ./common-pkgs-1 { inherit poetry2nix; };
top-packages-2 = pkgs.callPackage ./common-pkgs-2 { inherit poetry2nix; }; top-packages-2 = pkgs.callPackage ./common-pkgs-2 { inherit poetry2nix; };
bdist-filtering = pkgs.callPackage ./bdist-filtering { inherit poetry2nix; };
pep425 = pkgs.callPackage ./pep425 { inherit pep425; inherit pep425OSX; inherit pep425Python37; };
} }

146
tests/pep425/default.nix Normal file
View file

@ -0,0 +1,146 @@
{ writeText, stdenv, lib, pep425, pep425OSX, pep425Python37 }:
lib.debug.runTests {
testLinuxSimple =
let
cs = [
"grpcio-1.25.0-cp27-cp27m-macosx_10_10_x86_64.whl"
"grpcio-1.25.0-cp27-cp27m-manylinux2010_x86_64.whl"
];
in
{
expr = (pep425.select cs);
expected = ["grpcio-1.25.0-cp27-cp27m-manylinux2010_x86_64.whl"];
};
testOSXSimple =
let
cs = [
"grpcio-1.25.0-cp27-cp27m-macosx_10_10_x86_64.whl"
"grpcio-1.25.0-cp27-cp27m-manylinux2010_x86_64.whl"
];
in
{
expr = (pep425OSX.select cs);
expected = ["grpcio-1.25.0-cp27-cp27m-macosx_10_10_x86_64.whl"];
};
testLinuxPickPython37 =
let
cs = [
"grpcio-1.25.0-cp27-cp27m-macosx_10_10_x86_64.whl"
"grpcio-1.25.0-cp27-cp27m-macosx_10_9_x86_64.whl"
"grpcio-1.25.0-cp27-cp27m-manylinux1_i686.whl"
"grpcio-1.25.0-cp27-cp27m-manylinux2010_x86_64.whl"
"grpcio-1.25.0-cp37-cp37m-manylinux1_i686.whl"
"grpcio-1.25.0-cp37-cp37m-manylinux2010_x86_64.whl"
];
in
{
expr = (pep425Python37.select cs);
expected = ["grpcio-1.25.0-cp37-cp37m-manylinux2010_x86_64.whl"];
};
testOSXPreferNewer =
let
cs = [
"grpcio-1.25.0-cp27-cp27m-macosx_10_9_x86_64.whl"
"grpcio-1.25.0-cp27-cp27m-macosx_10_12_x86_64.whl"
];
in
{
expr = (pep425OSX.select cs);
expected = ["grpcio-1.25.0-cp27-cp27m-macosx_10_12_x86_64.whl"];
};
testOSXNoMatch =
let
cs = [
"grpcio-1.25.0-cp27-cp27m-manylinux1_x86_64.whl"
"grpcio-1.25.0-cp27-cp27m-manylinux2010_x86_64.whl"
];
in
{
expr = (pep425OSX.select cs);
expected = [];
};
testLinuxPreferOlder =
let
cs = [
"grpcio-1.25.0-cp27-cp27m-manylinux1_x86_64.whl"
"grpcio-1.25.0-cp27-cp27m-manylinux2010_x86_64.whl"
];
in
{
expr = (pep425.select cs);
expected = ["grpcio-1.25.0-cp27-cp27m-manylinux1_x86_64.whl"];
};
testLinuxNoMatch =
let
cs = [
"grpcio-1.25.0-cp27-cp27m-macosx_10_9_x86_64.whl"
"grpcio-1.25.0-cp27-cp27m-macosx_10_12_x86_64.whl"
];
in
{
expr = (pep425.select cs);
expected = [];
};
testLinuxEmptyList = {
expr = pep425.select [];
expected = [];
};
testOSXEmptyList = {
expr = pep425OSX.select [];
expected = [];
};
testLinuxCffiWhlFiles =
let
cs = [
"cffi-1.13.2-cp27-cp27m-macosx_10_6_intel.whl"
"cffi-1.13.2-cp27-cp27m-manylinux1_i686.whl"
"cffi-1.13.2-cp27-cp27m-manylinux1_x86_64.whl"
"cffi-1.13.2-cp27-cp27m-win32.whl"
"cffi-1.13.2-cp27-cp27m-win_amd64.whl"
"cffi-1.13.2-cp27-cp27mu-manylinux1_i686.whl"
"cffi-1.13.2-cp27-cp27mu-manylinux1_x86_64.whl"
"cffi-1.13.2-cp34-cp34m-macosx_10_6_intel.whl"
"cffi-1.13.2-cp34-cp34m-manylinux1_i686.whl"
"cffi-1.13.2-cp34-cp34m-manylinux1_x86_64.whl"
"cffi-1.13.2-cp34-cp34m-win32.whl"
"cffi-1.13.2-cp34-cp34m-win_amd64.whl"
"cffi-1.13.2-cp35-cp35m-macosx_10_6_intel.whl"
"cffi-1.13.2-cp35-cp35m-manylinux1_i686.whl"
"cffi-1.13.2-cp35-cp35m-manylinux1_x86_64.whl"
"cffi-1.13.2-cp35-cp35m-win32.whl"
"cffi-1.13.2-cp35-cp35m-win_amd64.whl"
"cffi-1.13.2-cp36-cp36m-macosx_10_6_intel.whl"
"cffi-1.13.2-cp36-cp36m-manylinux1_i686.whl"
"cffi-1.13.2-cp36-cp36m-manylinux1_x86_64.whl"
"cffi-1.13.2-cp36-cp36m-win32.whl"
"cffi-1.13.2-cp36-cp36m-win_amd64.whl"
"cffi-1.13.2-cp37-cp37m-macosx_10_6_intel.whl"
"cffi-1.13.2-cp37-cp37m-manylinux1_i686.whl"
"cffi-1.13.2-cp37-cp37m-manylinux1_x86_64.whl"
"cffi-1.13.2-cp37-cp37m-win32.whl"
"cffi-1.13.2-cp37-cp37m-win_amd64.whl"
"cffi-1.13.2-cp38-cp38-macosx_10_9_x86_64.whl"
"cffi-1.13.2-cp38-cp38-manylinux1_i686.whl"
"cffi-1.13.2-cp38-cp38-manylinux1_x86_64.whl"
"cffi-1.13.2-cp38-cp38-win32.whl"
"cffi-1.13.2-cp38-cp38-win_amd64.whl"
"cffi-1.13.2.tar.gz"
];
in
{
expr = pep425.select cs;
expected = ["cffi-1.13.2-cp27-cp27m-manylinux1_x86_64.whl"];
};
}