mirror of
https://github.com/nix-community/dream2nix.git
synced 2024-11-22 15:04:46 +03:00
selectWheel: init
This commit is contained in:
parent
0c6910060f
commit
19fce43579
147
lib/internal/python/selectWheel.nix
Normal file
147
lib/internal/python/selectWheel.nix
Normal file
@ -0,0 +1,147 @@
|
||||
# MIT Licensed by @adisbladis
|
||||
# this is vendored from poetry2nix atm, because it uses pyprojects pep599 instead of poetryLib,
|
||||
# to get going while testing the design.
|
||||
# FIXME: just port selectWheel to pyproject.nix
|
||||
# https://github.com/nix-community/poetry2nix/blame/master/pep425.nix
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
pep599,
|
||||
python,
|
||||
isLinux ? stdenv.isLinux,
|
||||
}: let
|
||||
inherit (lib.strings) escapeRegex hasPrefix hasSuffix hasInfix splitString removeSuffix;
|
||||
targetMachine = pep599.manyLinuxTargetMachines.${stdenv.targetPlatform.parsed.cpu.name} or null;
|
||||
|
||||
pythonVer = let
|
||||
ver = builtins.splitVersion python.version;
|
||||
major = builtins.elemAt ver 0;
|
||||
minor = builtins.elemAt ver 1;
|
||||
tags = ["cp" "py"];
|
||||
in {inherit major minor tags;};
|
||||
# Builds with and without pymalloc (m) are ABI compatible since python 3.8 (bpo-36707)
|
||||
abiTag =
|
||||
"cp${pythonVer.major}${pythonVer.minor}"
|
||||
+ lib.optionalString (builtins.compareVersions python.version "3.8" < 0) "m";
|
||||
|
||||
#
|
||||
# Parses wheel file returning an attribute set
|
||||
#
|
||||
toWheelAttrs = str: let
|
||||
entries' = splitString "-" str;
|
||||
el = builtins.length entries';
|
||||
entryAt = builtins.elemAt entries';
|
||||
|
||||
# Hack: Remove version "suffixes" like 2.11.4-1
|
||||
entries =
|
||||
if el == 6
|
||||
then [
|
||||
(entryAt 0) # name
|
||||
(entryAt 1) # version
|
||||
# build tag is skipped
|
||||
(entryAt (el - 3)) # python version
|
||||
(entryAt (el - 2)) # abi
|
||||
(entryAt (el - 1)) # platform
|
||||
]
|
||||
else entries';
|
||||
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;
|
||||
};
|
||||
|
||||
#
|
||||
# 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 (file: hasInfix v file) candidates) ++ (findBestMatches vs candidates);
|
||||
|
||||
# x = "cpXX" | "py2" | "py3" | "py2.py3"
|
||||
isPyVersionCompatible = pyver @ {
|
||||
major,
|
||||
minor,
|
||||
tags,
|
||||
}: x: let
|
||||
isCompat = m:
|
||||
builtins.elem m.tag tags
|
||||
&& m.major == major
|
||||
&& builtins.compareVersions minor m.minor >= 0;
|
||||
parseMarker = v: let
|
||||
tag = builtins.substring 0 2 v;
|
||||
major = builtins.substring 2 1 v;
|
||||
end = builtins.substring 3 3 v;
|
||||
minor =
|
||||
if builtins.stringLength end > 0
|
||||
then end
|
||||
else "0";
|
||||
in {inherit major minor tag;};
|
||||
markers = splitString "." x;
|
||||
in
|
||||
lib.lists.any isCompat (map parseMarker markers);
|
||||
|
||||
#
|
||||
# Selects the best matching wheel file from a list of files
|
||||
#
|
||||
selectWheel = files: let
|
||||
filesWithoutSources = builtins.filter (file: hasSuffix ".whl" file) files;
|
||||
isPyAbiCompatible = pyabi: x:
|
||||
x
|
||||
== "none"
|
||||
|| hasPrefix pyabi x
|
||||
|| hasPrefix x pyabi
|
||||
|| (
|
||||
# The CPython stable ABI is abi3 as in the shared library suffix.
|
||||
python.passthru.implementation
|
||||
== "cpython"
|
||||
&& builtins.elemAt (lib.splitString "." python.version) 0 == "3"
|
||||
&& x == "abi3"
|
||||
);
|
||||
withPython = ver: abi: x: (isPyVersionCompatible ver x.pyVer) && (isPyAbiCompatible abi x.abi);
|
||||
withPlatform =
|
||||
if isLinux
|
||||
then
|
||||
if targetMachine != null
|
||||
then
|
||||
# See PEP 600 for details.
|
||||
(
|
||||
p:
|
||||
builtins.match "any|(linux|manylinux(1|2010|2014))_${escapeRegex targetMachine}|manylinux_[0-9]+_[0-9]+_${escapeRegex targetMachine}" p != null
|
||||
)
|
||||
else (p: p == "any")
|
||||
else if stdenv.isDarwin
|
||||
then
|
||||
if stdenv.targetPlatform.isAarch64
|
||||
then (p: p == "any" || (hasInfix "macosx" p && lib.lists.any (e: hasSuffix e p) ["arm64" "aarch64"]))
|
||||
else (p: p == "any" || (hasInfix "macosx" p && hasSuffix "x86_64" p))
|
||||
else (p: p == "any");
|
||||
withPlatforms = x: lib.lists.any withPlatform (splitString "." x.platform);
|
||||
filterWheel = file: let
|
||||
f = toWheelAttrs file;
|
||||
in
|
||||
(withPython pythonVer abiTag f) && (withPlatforms f);
|
||||
filtered = builtins.filter filterWheel filesWithoutSources;
|
||||
choose = files: let
|
||||
osxMatches = ["12_0" "11_0" "10_15" "10_14" "10_12" "10_11" "10_10" "10_9" "10_8" "10_7" "any"];
|
||||
linuxMatches = ["manylinux1_" "manylinux2010_" "manylinux2014_" "manylinux_" "linux_" "any"];
|
||||
chooseLinux = x: lib.head (findBestMatches linuxMatches x);
|
||||
chooseOSX = x: lib.head (findBestMatches osxMatches x);
|
||||
in
|
||||
if isLinux
|
||||
then chooseLinux files
|
||||
else chooseOSX files;
|
||||
in
|
||||
if (builtins.length filtered == 0)
|
||||
then null
|
||||
else choose filtered;
|
||||
in
|
||||
selectWheel
|
@ -10,9 +10,16 @@
|
||||
|
||||
libpyproject = import (dream2nix.inputs.pyproject-nix + "/lib") {inherit lib;};
|
||||
|
||||
selectWheel = import ../../../lib/internal/python/selectWheel.nix {
|
||||
inherit lib;
|
||||
pep599 = libpyproject.pep599;
|
||||
python = config.deps.python3;
|
||||
stdenv = config.deps.stdenv;
|
||||
};
|
||||
|
||||
lock_data = lib.importTOML config.pdm.lockfile;
|
||||
environ = libpyproject.pep508.mkEnviron config.deps.python3;
|
||||
selector = libpdm.preferWheelSelector;
|
||||
selector = config.pdm.sourceSelector;
|
||||
|
||||
pyproject = libpdm.loadPdmPyProject (lib.importTOML config.pdm.pyproject);
|
||||
|
||||
@ -33,16 +40,20 @@ in {
|
||||
../core/deps
|
||||
./interface.nix
|
||||
];
|
||||
pdm.sourceSelector = lib.mkDefault selectWheel;
|
||||
deps = {nixpkgs, ...}: {
|
||||
inherit
|
||||
(nixpkgs)
|
||||
curl
|
||||
jq
|
||||
stdenvNoCC
|
||||
python3
|
||||
stdenv
|
||||
;
|
||||
};
|
||||
commonModule = {
|
||||
options.sourceSelector = import ./sourceSelectorOption.nix {inherit lib;};
|
||||
# TODO: per dependency selector isn't yet respected
|
||||
config.sourceSelector = lib.mkOptionDefault config.pdm.sourceSelector;
|
||||
};
|
||||
groups = let
|
||||
|
Loading…
Reference in New Issue
Block a user