vendor: Bump pyproject.nix

This commit is contained in:
adisbladis 2023-11-08 17:53:51 +13:00
parent 7a001e012c
commit 4ccb4976e9
10 changed files with 155 additions and 56 deletions

View file

@ -244,7 +244,7 @@ lib.makeScope pkgs.newScope (self: {
super) super)
( (
self: super: self: _super:
{ {
mkPoetryDep = self.callPackage ./mk-poetry-dep.nix { mkPoetryDep = self.callPackage ./mk-poetry-dep.nix {
inherit lib python poetryLib pep508Env pyVersion; inherit lib python poetryLib pep508Env pyVersion;

View file

@ -30,7 +30,7 @@ let
wheelFiles = builtins.filter (fileEntry: pypa.isWheelFileName fileEntry.file) files; wheelFiles = builtins.filter (fileEntry: pypa.isWheelFileName fileEntry.file) files;
# Group wheel files by their file name # Group wheel files by their file name
wheelFilesByFileName = lib.listToAttrs (map (fileEntry: lib.nameValuePair fileEntry.file fileEntry) wheelFiles); wheelFilesByFileName = lib.listToAttrs (map (fileEntry: lib.nameValuePair fileEntry.file fileEntry) wheelFiles);
selectedWheels = pypa.selectWheels python (map (fileEntry: pypa.parseWheelFileName fileEntry.file) wheelFiles); selectedWheels = pypa.selectWheels python.stdenv.targetPlatform python (map (fileEntry: pypa.parseWheelFileName fileEntry.file) wheelFiles);
in map (wheel: wheelFilesByFileName.${wheel.filename}) selectedWheels); in map (wheel: wheelFilesByFileName.${wheel.filename}) selectedWheels);
in in
@ -102,10 +102,6 @@ pythonPackages.callPackage
if _isEgg then "egg" if _isEgg then "egg"
else if lib.strings.hasSuffix ".whl" name then "wheel" else if lib.strings.hasSuffix ".whl" name then "wheel"
else "pyproject"; else "pyproject";
kind =
if _isEgg then python.pythonVersion
else if format == "pyproject" then "source"
else (builtins.elemAt (lib.strings.splitString "-" name) 2);
}; };
format = if isWheelUrl then "wheel" else if isDirectory || isGit || isUrl then "pyproject" else fileInfo.format; format = if isWheelUrl then "wheel" else if isDirectory || isGit || isUrl then "pyproject" else fileInfo.format;
@ -234,7 +230,7 @@ pythonPackages.callPackage
else else
pyproject-nix.fetchers.fetchFromPypi { pyproject-nix.fetchers.fetchFromPypi {
pname = name; pname = name;
inherit (fileInfo) file hash kind; inherit (fileInfo) file hash;
inherit version; inherit version;
}; };
in in

View file

@ -1,5 +1,5 @@
{ pkgs, lib }: { pkgs, lib }:
{ {
lib = import ./lib { inherit lib; }; lib = import ./lib { inherit lib; };
fetchers = import ./fetchers { inherit pkgs lib; }; fetchers = pkgs.callPackage ./fetchers { };
} }

View file

@ -1,11 +1,16 @@
{ pkgs { curl
, jq
, lib , lib
, , python3
, runCommand
, stdenvNoCC
}: }:
let let
inherit (builtins) substring filter head nixPath; inherit (builtins) substring filter head nixPath elemAt;
inherit (lib) toLower; inherit (lib) toLower;
pyproject = import ../lib { inherit lib; };
# Predict URL from the PyPI index. # Predict URL from the PyPI index.
# Args: # Args:
# pname: package name # pname: package name
@ -18,10 +23,16 @@ let
pname pname
, # filename including extension , # filename including extension
file file
, # Language implementation and version tag }:
kind let
, matchedWheel = pyproject.pypa.matchWheelFileName file;
}: "https://files.pythonhosted.org/packages/${kind}/${toLower (substring 0 1 file)}/${pname}/${file}"; matchedEgg = pyproject.pypa.matchEggFileName file;
kind =
if matchedWheel != null then "wheel"
else if matchedEgg != null then elemAt matchedEgg 2
else "source";
in
"https://files.pythonhosted.org/packages/${kind}/${toLower (substring 0 1 file)}/${pname}/${file}";
in in
lib.mapAttrs (_: func: lib.makeOverridable func) { lib.mapAttrs (_: func: lib.makeOverridable func) {
/* /*
@ -42,20 +53,18 @@ lib.mapAttrs (_: func: lib.makeOverridable func) {
version version
, # SRI hash , # SRI hash
hash hash
, # Language implementation and version tag
kind
, # Options to pass to `curl` , # Options to pass to `curl`
curlOpts ? "" curlOpts ? ""
, ,
}: }:
let let
predictedURL = predictURLFromPypi { inherit pname file kind; }; predictedURL = predictURLFromPypi { inherit pname file; };
in in
pkgs.stdenvNoCC.mkDerivation { stdenvNoCC.mkDerivation {
name = file; name = file;
nativeBuildInputs = [ nativeBuildInputs = [
pkgs.buildPackages.curl curl
pkgs.buildPackages.jq jq
]; ];
isWheel = lib.strings.hasSuffix "whl" file; isWheel = lib.strings.hasSuffix "whl" file;
system = "builtin"; system = "builtin";
@ -106,9 +115,9 @@ lib.mapAttrs (_: func: lib.makeOverridable func) {
then (head pathParts).path then (head pathParts).path
else ""; else "";
in in
pkgs.runCommand file runCommand file
{ {
nativeBuildInputs = [ pkgs.buildPackages.python3 ]; nativeBuildInputs = [ python3 ];
impureEnvVars = lib.fetchers.proxyImpureEnvVars; impureEnvVars = lib.fetchers.proxyImpureEnvVars;
outputHashMode = "flat"; outputHashMode = "flat";
outputHashAlgo = "sha256"; outputHashAlgo = "sha256";

View file

@ -1,7 +1,8 @@
{ lib, ... }: { lib, ... }:
let let
inherit (builtins) split filter match length elemAt head tail foldl' fromJSON typeOf; inherit (builtins) split filter match length elemAt head foldl' fromJSON typeOf;
inherit (lib) fix isString toInt toLower sublist; inherit (lib) fix isString toInt toLower sublist;
inherit (import ./util.nix { inherit lib; }) splitComma;
filterNull = filter (x: x != null); filterNull = filter (x: x != null);
filterEmpty = filter (x: length x > 0); filterEmpty = filter (x: length x > 0);
@ -54,19 +55,19 @@ let
parseLocal = parseReleaseSuffix "\\+"; parseLocal = parseReleaseSuffix "\\+";
# Compare the release fields from the parsed version # Compare the release fields from the parsed version
compareRelease = ra: rb: compareRelease = offset: ra: rb:
let let
x = head ra; x = elemAt ra offset;
y = head rb; y = elemAt rb offset;
in in
if length ra == 0 || length rb == 0 then 0 else if length ra == offset || length rb == offset then 0 else
( (
if x == "*" || y == "*" then 0 # Wildcards are always considered equal if x == "*" || y == "*" then 0 # Wildcards are always considered equal
else else
( (
if x > y then 1 if x > y then 1
else if x < y then -1 else if x < y then -1
else compareRelease (tail ra) (tail rb) else compareRelease (offset + 1) ra rb
) )
); );
@ -160,6 +161,42 @@ fix (self: {
} }
); );
/* Parse a list of version conditionals separated by commas.
Type: parseVersionConds :: string -> [AttrSet]
Example:
# parseVersionConds ">=3.0.0rc1,<=4.0"
[
{
op = ">=";
version = {
dev = null;
epoch = 0;
local = null;
post = null;
pre = {
type = "rc";
value = 1;
};
release = [ 3 0 0 ];
};
}
{
op = "<=";
version = {
dev = null;
epoch = 0;
local = null;
post = null;
pre = null;
release = [ 4 0 ];
};
}
]
*/
parseVersionConds = conds: map self.parseVersionCond (splitComma conds);
/* Compare two versions as parsed by `parseVersion` according to PEP-440. /* Compare two versions as parsed by `parseVersion` according to PEP-440.
Returns: Returns:
@ -180,7 +217,7 @@ fix (self: {
# is valid and we need to consider them all. # is valid and we need to consider them all.
# Compare release field # Compare release field
(compareRelease a.release b.release) (compareRelease 0 a.release b.release)
# Compare pre release # Compare pre release
( (

View file

@ -350,7 +350,7 @@ fix (self:
m2 = match "([a-zA-Z0-9_\\.-]+)(.*)" tokens.packageSegment; m2 = match "([a-zA-Z0-9_\\.-]+)(.*)" tokens.packageSegment;
# The version conditions as a list of strings # The version conditions as a list of strings
conditions = map pep440.parseVersionCond (splitComma (if m1 != null then elemAt m1 2 else elemAt m2 1)); conditions = pep440.parseVersionConds (if m1 != null then elemAt m1 2 else elemAt m2 1);
# Extras as a list of strings # Extras as a list of strings
# #

View file

@ -31,13 +31,19 @@ fix (self: {
/* Check if a manylinux tag is compatible with a given stdenv. /* Check if a manylinux tag is compatible with a given stdenv.
Type: manyLinuxTagCompatible :: AttrSet -> string -> bool Type: manyLinuxTagCompatible :: AttrSet -> derivation -> string -> bool
Example: Example:
# manyLinuxTagCompatible pkgs.stdenv "manylinux_2_5_x86_64" # manyLinuxTagCompatible pkgs.stdenv.targetPlatform pkgs.stdenv.cc.libc "manylinux_2_5_x86_64"
true true
*/ */
manyLinuxTagCompatible = stdenv: tag: manyLinuxTagCompatible =
# Platform attrset (`lib.systems.elaborate "x86_64-linux"`)
platform:
# Libc derivation
libc:
# Platform tag string
tag:
let let
tag' = self.legacyAliases.${tag} or tag; tag' = self.legacyAliases.${tag} or tag;
m = match "manylinux_([0-9]+)_([0-9]+)_(.*)" tag'; m = match "manylinux_([0-9]+)_([0-9]+)_(.*)" tag';
@ -45,14 +51,15 @@ fix (self: {
tagMajor = mAt 0; tagMajor = mAt 0;
tagMinor = mAt 1; tagMinor = mAt 1;
tagArch = mAt 2; tagArch = mAt 2;
sysVersion' = elemAt (splitVersion stdenv.cc.libc.version); sysVersion' = elemAt (splitVersion libc.version);
sysMajor = sysVersion' 0; sysMajor = sysVersion' 0;
sysMinor = sysVersion' 1; sysMinor = sysVersion' 1;
in in
if m == null then throw "'${tag'}' is not a valid manylinux tag." if m == null then throw "'${tag'}' is not a valid manylinux tag."
else if stdenv.cc.libc.pname != "glibc" then false else if platform.libc != "glibc" then false
else if libc.pname != "glibc" then false
else if compareVersions "${sysMajor}.${sysMinor}" "${tagMajor}.${tagMinor}" < 0 then false else if compareVersions "${sysMajor}.${sysMinor}" "${tagMajor}.${tagMinor}" < 0 then false
else if pep599.manyLinuxTargetMachines.${tagArch} != stdenv.targetPlatform.parsed.cpu.name then false else if pep599.manyLinuxTargetMachines.${tagArch} != platform.parsed.cpu.name then false
else true; else true;
}) })

View file

@ -46,7 +46,7 @@ fix (self: {
# parseRequiresPython (lib.importTOML ./pyproject.toml) # parseRequiresPython (lib.importTOML ./pyproject.toml)
[ ] # List of conditions as returned by `lib.pep440.parseVersionCond` [ ] # List of conditions as returned by `lib.pep440.parseVersionCond`
*/ */
parseRequiresPython = pyproject: map pep440.parseVersionCond (filter isString (split "," (pyproject.project.requires-python or ""))); parseRequiresPython = pyproject: pep440.parseVersionConds (pyproject.project.requires-python or "");
/* Takes a dependency structure as returned by `lib.pep621.parseDependencies` and transforms it into /* Takes a dependency structure as returned by `lib.pep621.parseDependencies` and transforms it into
a structure with it's package names. a structure with it's package names.

View file

@ -7,27 +7,34 @@ in
{ {
/* Check if a musllinux tag is compatible with a given stdenv. /* Check if a musllinux tag is compatible with a given stdenv.
Type: muslLinuxTagCompatible :: AttrSet -> string -> bool Type: muslLinuxTagCompatible :: AttrSet -> derivation -> string -> bool
Example: Example:
# muslLinuxTagCompatible pkgs.stdenv "musllinux_1_1_x86_64" # muslLinuxTagCompatible pkgs.stdenv.targetPlatform pkgs.stdenv.cc.libc "musllinux_1_1_x86_64"
true true
*/ */
muslLinuxTagCompatible = stdenv: tag: muslLinuxTagCompatible =
# Platform attrset (`lib.systems.elaborate "x86_64-linux"`)
platform:
# Libc derivation
libc:
# Platform tag string
tag:
let let
m = match "musllinux_([0-9]+)_([0-9]+)_(.*)" tag; m = match "musllinux_([0-9]+)_([0-9]+)_(.*)" tag;
mAt = elemAt m; mAt = elemAt m;
tagMajor = mAt 0; tagMajor = mAt 0;
tagMinor = mAt 1; tagMinor = mAt 1;
tagArch = mAt 2; tagArch = mAt 2;
sysVersion' = elemAt (splitVersion stdenv.cc.libc.version); sysVersion' = elemAt (splitVersion libc.version);
sysMajor = sysVersion' 0; sysMajor = sysVersion' 0;
sysMinor = sysVersion' 1; sysMinor = sysVersion' 1;
in in
if m == null then throw "'${tag}' is not a valid musllinux tag." if m == null then throw "'${tag}' is not a valid musllinux tag."
else if stdenv.cc.libc.pname != "musl" then false else if platform.libc != "musl" then false
else if libc.pname != "musl" then false
else if compareVersions "${sysMajor}.${sysMinor}" "${tagMajor}.${tagMinor}" < 0 then false else if compareVersions "${sysMajor}.${sysMinor}" "${tagMajor}.${tagMinor}" < 0 then false
else if pep599.manyLinuxTargetMachines.${tagArch} != stdenv.targetPlatform.parsed.cpu.name then false else if pep599.manyLinuxTargetMachines.${tagArch} != platform.parsed.cpu.name then false
else true; else true;
} }

View file

@ -6,6 +6,9 @@ let
matchWheelFileName = match "([^-]+)-([^-]+)(-([[:digit:]][^-]*))?-([^-]+)-([^-]+)-(.+).whl"; matchWheelFileName = match "([^-]+)-([^-]+)(-([[:digit:]][^-]*))?-([^-]+)-([^-]+)-(.+).whl";
# PEP-625 only specifies .tar.gz as valid extension but .zip is also fairly widespread.
matchSdistFileName = match "([^-]+)-(.+)(\.tar\.gz|\.zip)";
# Tag normalization documented in # Tag normalization documented in
# https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/#details # https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/#details
normalizedImpls = { normalizedImpls = {
@ -92,6 +95,39 @@ lib.fix (self: {
rest = mAt 2; rest = mAt 2;
}; };
/* Check whether string is a sdist file or not.
Type: isSdistFileName :: string -> bool
Example:
# isSdistFileName "cryptography-41.0.1.tar.gz"
true
*/
isSdistFileName =
# The filename string
name: matchSdistFileName name != null;
/* Regex match a wheel file name, returning a list of match groups. Returns null if no match.
Type: matchWheelFileName :: string -> [ string ]
*/
matchWheelFileName = name:
let
m = match "([^-]+)-([^-]+)(-([[:digit:]][^-]*))?-([^-]+)-([^-]+)-(.+).whl" name;
in
if m != null then filter isString m else null;
/* Regex match an egg file name, returning a list of match groups. Returns null if no match.
Type: matchEggFileName :: string -> [ string ]
*/
matchEggFileName = name:
let
m = match "([^-]+)-([^-]+)-(.+)\\.egg" name;
in
if m != null then filter isString m else null;
/* Check whether string is a wheel file or not. /* Check whether string is a wheel file or not.
Type: isWheelFileName :: string -> bool Type: isWheelFileName :: string -> bool
@ -100,7 +136,9 @@ lib.fix (self: {
# isWheelFileName "cryptography-41.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" # isWheelFileName "cryptography-41.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl"
true true
*/ */
isWheelFileName = name: matchWheelFileName name != null; isWheelFileName =
# The filename string
name: matchWheelFileName name != null;
/* Parse PEP-427 wheel file names. /* Parse PEP-427 wheel file names.
@ -179,23 +217,22 @@ lib.fix (self: {
/* Check whether a platform tag is compatible with this python interpreter. /* Check whether a platform tag is compatible with this python interpreter.
Type: isPlatformTagCompatible :: derivation -> string -> bool Type: isPlatformTagCompatible :: AttrSet -> derivation -> string -> bool
Example: Example:
# isPlatformTagCompatible pkgs.python3 "manylinux2014_x86_64" # isPlatformTagCompatible pkgs.python3 "manylinux2014_x86_64"
true true
*/ */
isPlatformTagCompatible = isPlatformTagCompatible =
# Python interpreter derivation # Platform attrset (`lib.systems.elaborate "x86_64-linux"`)
python: platform:
# Libc derivation
libc:
# Python tag # Python tag
platformTag: platformTag:
let
platform = python.stdenv.targetPlatform;
in
if platformTag == "any" then true if platformTag == "any" then true
else if hasPrefix "manylinux" platformTag then pep600.manyLinuxTagCompatible python.stdenv platformTag else if hasPrefix "manylinux" platformTag then pep600.manyLinuxTagCompatible platform libc platformTag
else if hasPrefix "musllinux" platformTag then pep656.muslLinuxTagCompatible python.stdenv platformTag else if hasPrefix "musllinux" platformTag then pep656.muslLinuxTagCompatible platform libc platformTag
else if hasPrefix "macosx" platformTag then else if hasPrefix "macosx" platformTag then
( (
let let
@ -245,7 +282,7 @@ lib.fix (self: {
Type: isPythonTagCompatible :: derivation -> AttrSet -> bool Type: isPythonTagCompatible :: derivation -> AttrSet -> bool
Example: Example:
# isPlatformTagCompatible pkgs.python3 (pypa.parsePythonTag "py3") # isPythonTagCompatible pkgs.python3 (pypa.parsePythonTag "py3")
true true
*/ */
isPythonTagCompatible = isPythonTagCompatible =
@ -277,6 +314,10 @@ lib.fix (self: {
true true
*/ */
isWheelFileCompatible = isWheelFileCompatible =
# Platform attrset (`lib.systems.elaborate "x86_64-linux"`)
platform:
# Libc derivation
libc:
# Python interpreter derivation # Python interpreter derivation
python: python:
# The parsed wheel filename # The parsed wheel filename
@ -286,7 +327,7 @@ lib.fix (self: {
&& &&
lib.any (self.isPythonTagCompatible python) file.languageTags lib.any (self.isPythonTagCompatible python) file.languageTags
&& &&
lib.any (self.isPlatformTagCompatible python) file.platformTags lib.any (self.isPlatformTagCompatible platform libc) file.platformTags
); );
/* Select compatible wheels from a list and return them in priority order. /* Select compatible wheels from a list and return them in priority order.
@ -298,6 +339,8 @@ lib.fix (self: {
[ (pypa.parseWheelFileName "Pillow-9.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl") ] [ (pypa.parseWheelFileName "Pillow-9.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl") ]
*/ */
selectWheels = selectWheels =
# Platform attrset (`lib.systems.elaborate "x86_64-linux"`)
platform:
# Python interpreter derivation # Python interpreter derivation
python: python:
# List of files as parsed by parseWheelFileName # List of files as parsed by parseWheelFileName
@ -317,7 +360,7 @@ lib.fix (self: {
in in
{ {
bestLanguageTag = head (sort (x: y: x > y) languageTags'); bestLanguageTag = head (sort (x: y: x > y) languageTags');
compatible = abiCompatible && length languageTags > 0 && lib.any (self.isPlatformTagCompatible python) file.platformTags; compatible = abiCompatible && length languageTags > 0 && lib.any (self.isPlatformTagCompatible platform python.stdenv.cc.libc) file.platformTags;
inherit file; inherit file;
}) })
files; files;