poetry2nix: 1.7.1 -> 1.8.0

This commit is contained in:
adisbladis 2020-05-05 21:20:44 +01:00
parent 4ad2e1c92e
commit 36debc367e
No known key found for this signature in database
GPG Key ID: 110BFAD44C6249B7
13 changed files with 1328 additions and 1022 deletions

View File

@ -1,4 +1,4 @@
{ pkgs ? import <nixpkgs> {} { pkgs ? import <nixpkgs> { }
, lib ? pkgs.lib , lib ? pkgs.lib
, version , version
}: }:

View File

@ -1,22 +1,20 @@
{ pkgs ? import <nixpkgs> {} { pkgs ? import <nixpkgs> { }
, lib ? pkgs.lib , lib ? pkgs.lib
, poetry ? null , poetry ? null
, poetryLib ? import ./lib.nix { inherit lib pkgs; } , poetryLib ? import ./lib.nix { inherit lib pkgs; }
}: }:
let let
inherit (poetryLib) isCompatible readTOML; inherit (poetryLib) isCompatible readTOML moduleName;
# Poetry2nix version # Poetry2nix version
version = "1.7.1"; version = "1.8.0";
/* The default list of poetry2nix override overlays */ /* The default list of poetry2nix override overlays */
defaultPoetryOverrides = (import ./overrides.nix { inherit pkgs lib; }); defaultPoetryOverrides = (import ./overrides.nix { inherit pkgs lib; });
mkEvalPep508 = import ./pep508.nix { mkEvalPep508 = import ./pep508.nix {
inherit lib poetryLib; inherit lib poetryLib;
stdenv = pkgs.stdenv; stdenv = pkgs.stdenv;
}; };
getFunctorFn = fn: if builtins.typeOf fn == "set" then fn.__functor else fn; getFunctorFn = fn: if builtins.typeOf fn == "set" then fn.__functor else fn;
# Map SPDX identifiers to license names # Map SPDX identifiers to license names
@ -34,30 +32,33 @@ let
, overrides ? [ defaultPoetryOverrides ] , overrides ? [ defaultPoetryOverrides ]
, python ? pkgs.python3 , python ? pkgs.python3
, pwd ? projectDir , pwd ? projectDir
, preferWheels ? false
}@attrs: }@attrs:
let let
poetryPkg = poetry.override { inherit python; }; poetryPkg = poetry.override { inherit python; };
pyProject = readTOML pyproject; pyProject = readTOML pyproject;
poetryLock = readTOML poetrylock; poetryLock = readTOML poetrylock;
lockFiles = lib.getAttrFromPath [ "metadata" "files" ] poetryLock; lockFiles =
let
lockfiles = lib.getAttrFromPath [ "metadata" "files" ] poetryLock;
in
lib.listToAttrs (lib.mapAttrsToList (n: v: { name = moduleName n; value = v; }) lockfiles);
specialAttrs = [ specialAttrs = [
"overrides" "overrides"
"poetrylock" "poetrylock"
"projectDir" "projectDir"
"pwd" "pwd"
"preferWheels"
]; ];
passedAttrs = builtins.removeAttrs attrs specialAttrs; passedAttrs = builtins.removeAttrs attrs specialAttrs;
evalPep508 = mkEvalPep508 python; evalPep508 = mkEvalPep508 python;
# Filter packages by their PEP508 markers & pyproject interpreter version # Filter packages by their PEP508 markers & pyproject interpreter version
partitions = let partitions =
let
supportsPythonVersion = pkgMeta: if pkgMeta ? marker then (evalPep508 pkgMeta.marker) else true; supportsPythonVersion = pkgMeta: if pkgMeta ? marker then (evalPep508 pkgMeta.marker) else true;
in in
lib.partition supportsPythonVersion poetryLock.package; lib.partition supportsPythonVersion poetryLock.package;
compatible = partitions.right; compatible = partitions.right;
incompatible = partitions.wrong; incompatible = partitions.wrong;
@ -68,14 +69,16 @@ let
baseOverlay = self: super: baseOverlay = self: super:
let let
getDep = depName: self.${depName}; getDep = depName: self.${depName};
lockPkgs = builtins.listToAttrs
lockPkgs = builtins.listToAttrs ( (
builtins.map ( builtins.map
(
pkgMeta: rec { pkgMeta: rec {
name = pkgMeta.name; name = moduleName pkgMeta.name;
value = self.mkPoetryDep ( value = self.mkPoetryDep
(
pkgMeta // { pkgMeta // {
inherit pwd; inherit pwd preferWheels;
source = pkgMeta.source or null; source = pkgMeta.source or null;
files = lockFiles.${name}; files = lockFiles.${name};
pythonPackages = self; pythonPackages = self;
@ -87,12 +90,13 @@ let
); );
in in
lockPkgs; lockPkgs;
overlays = builtins.map getFunctorFn ( overlays = builtins.map getFunctorFn
(
[ [
( (
self: super: self: super:
let let
hooks = self.callPackage ./hooks {}; hooks = self.callPackage ./hooks { };
in in
{ {
mkPoetryDep = self.callPackage ./mk-poetry-dep.nix { mkPoetryDep = self.callPackage ./mk-poetry-dep.nix {
@ -102,24 +106,22 @@ let
# The canonical name is setuptools-scm # The canonical name is setuptools-scm
setuptools-scm = super.setuptools_scm; setuptools-scm = super.setuptools_scm;
inherit (hooks) removePathDependenciesHook poetry2nixFixupHook; inherit (hooks) pipBuildHook removePathDependenciesHook poetry2nixFixupHook;
} }
) )
# Null out any filtered packages, we don't want python.pkgs from nixpkgs # Null out any filtered packages, we don't want python.pkgs from nixpkgs
(self: super: builtins.listToAttrs (builtins.map (x: { name = x.name; value = null; }) incompatible)) (self: super: builtins.listToAttrs (builtins.map (x: { name = moduleName x.name; value = null; }) incompatible))
# Create poetry2nix layer # Create poetry2nix layer
baseOverlay baseOverlay
] ++ # User provided overrides ] ++ # User provided overrides
overrides overrides
); );
packageOverrides = lib.foldr lib.composeExtensions (self: super: { }) overlays;
packageOverrides = lib.foldr lib.composeExtensions (self: super: {}) overlays;
py = python.override { inherit packageOverrides; self = py; }; py = python.override { inherit packageOverrides; self = py; };
in in
{ {
python = py; python = py;
poetryPackages = map (pkg: py.pkgs.${pkg.name}) compatible; poetryPackages = map (pkg: py.pkgs.${moduleName pkg.name}) compatible;
poetryLock = poetryLock; poetryLock = poetryLock;
inherit pyProject; inherit pyProject;
}; };
@ -136,11 +138,13 @@ let
, overrides ? [ defaultPoetryOverrides ] , overrides ? [ defaultPoetryOverrides ]
, pwd ? projectDir , pwd ? projectDir
, python ? pkgs.python3 , python ? pkgs.python3
, preferWheels ? false
}: }:
let let
py = mkPoetryPackages ( py = mkPoetryPackages
(
{ {
inherit pyproject poetrylock overrides python pwd; inherit pyproject poetrylock overrides python pwd preferWheels;
} }
); );
in in
@ -153,56 +157,56 @@ let
, pyproject ? projectDir + "/pyproject.toml" , pyproject ? projectDir + "/pyproject.toml"
, poetrylock ? projectDir + "/poetry.lock" , poetrylock ? projectDir + "/poetry.lock"
, overrides ? [ defaultPoetryOverrides ] , overrides ? [ defaultPoetryOverrides ]
, meta ? {} , meta ? { }
, python ? pkgs.python3 , python ? pkgs.python3
, pwd ? projectDir , pwd ? projectDir
, preferWheels ? false
, ... , ...
}@attrs: }@attrs:
let let
poetryPython = mkPoetryPackages { poetryPython = mkPoetryPackages {
inherit pyproject poetrylock overrides python pwd; inherit pyproject poetrylock overrides python pwd preferWheels;
}; };
py = poetryPython.python; py = poetryPython.python;
inherit (poetryPython) pyProject; inherit (poetryPython) pyProject;
specialAttrs = [ specialAttrs = [
"overrides" "overrides"
"poetrylock" "poetrylock"
"projectDir" "projectDir"
"pwd" "pwd"
"pyproject" "pyproject"
"preferWheels"
]; ];
passedAttrs = builtins.removeAttrs attrs specialAttrs; passedAttrs = builtins.removeAttrs attrs specialAttrs;
# Get dependencies and filter out depending on interpreter version # Get dependencies and filter out depending on interpreter version
getDeps = depAttr: getDeps = depAttr:
let let
compat = isCompatible py.pythonVersion; compat = isCompatible (poetryLib.getPythonVersion py);
deps = pyProject.tool.poetry.${depAttr} or {}; deps = pyProject.tool.poetry.${depAttr} or { };
depAttrs = builtins.map (d: lib.toLower d) (builtins.attrNames deps); depAttrs = builtins.map (d: lib.toLower d) (builtins.attrNames deps);
in in
builtins.map ( builtins.map
(
dep: dep:
let let
pkg = py.pkgs."${dep}"; pkg = py.pkgs."${dep}";
constraints = deps.${dep}.python or ""; constraints = deps.${dep}.python or "";
isCompat = compat constraints; isCompat = compat constraints;
in in if isCompat then pkg else null
if isCompat then pkg else null
) depAttrs; ) depAttrs;
getInputs = attr: attrs.${attr} or [ ];
getInputs = attr: attrs.${attr} or [];
mkInput = attr: extraInputs: getInputs attr ++ extraInputs; mkInput = attr: extraInputs: getInputs attr ++ extraInputs;
buildSystemPkgs = poetryLib.getBuildSystemPkgs { buildSystemPkgs = poetryLib.getBuildSystemPkgs {
inherit pyProject; inherit pyProject;
pythonPackages = py.pkgs; pythonPackages = py.pkgs;
}; };
in in
py.pkgs.buildPythonApplication ( py.pkgs.buildPythonApplication
(
passedAttrs // { passedAttrs // {
pname = pyProject.tool.poetry.name; pname = moduleName pyProject.tool.poetry.name;
version = pyProject.tool.poetry.version; version = pyProject.tool.poetry.version;
inherit src; inherit src;

View File

@ -0,0 +1,24 @@
source $stdenv/setup
set -euo pipefail
curl="curl \
--location \
--max-redirs 20 \
--retry 2 \
--disable-epsv \
--cookie-jar cookies \
--insecure \
--speed-time 5 \
-# \
--fail \
$curlOpts \
$NIX_CURL_FLAGS"
echo "Trying to fetch wheel with predicted URL: $predictedURL"
$curl $predictedURL --output $out && exit 0
echo "Predicted URL '$predictedURL' failed, querying pypi.org"
$curl "https://pypi.org/pypi/$pname/json" | jq -r ".releases.\"$version\"[] | select(.filename == \"$file\") | .url" > url
url=$(cat url)
$curl -k $url --output $out

View File

@ -2,31 +2,48 @@
, callPackage , callPackage
, makeSetupHook , makeSetupHook
, yj , yj
, wheel
, pip
}: }:
let let
pythonInterpreter = python.pythonForBuild.interpreter; pythonInterpreter = python.pythonForBuild.interpreter;
pythonSitePackages = python.sitePackages;
in in
{ {
removePathDependenciesHook = callPackage ( removePathDependenciesHook = callPackage
(
{}: {}:
makeSetupHook { makeSetupHook {
name = "remove-path-dependencies.sh"; name = "remove-path-dependencies.sh";
deps = []; deps = [ ];
substitutions = { substitutions = {
inherit pythonInterpreter; inherit pythonInterpreter;
yj = "${yj}/bin/yj"; yj = "${yj}/bin/yj";
pyprojectPatchScript = "${./pyproject-without-path.py}"; pyprojectPatchScript = "${./pyproject-without-path.py}";
}; };
} ./remove-path-dependencies.sh } ./remove-path-dependencies.sh
) {}; ) { };
poetry2nixFixupHook = callPackage ( pipBuildHook = callPackage
(
{ pip, wheel }:
makeSetupHook {
name = "pip-build-hook.sh";
deps = [ pip wheel ];
substitutions = {
inherit pythonInterpreter pythonSitePackages;
};
} ./pip-build-hook.sh
) { };
poetry2nixFixupHook = callPackage
(
{}: {}:
makeSetupHook { makeSetupHook {
name = "fixup-hook.sh"; name = "fixup-hook.sh";
deps = []; deps = [ ];
} ./fixup-hook.sh } ./fixup-hook.sh
) {}; ) { };
} }

View File

@ -0,0 +1,50 @@
# Setup hook to use for pip projects
echo "Sourcing pip-build-hook"
pipBuildPhase() {
echo "Executing pipBuildPhase"
runHook preBuild
# Prefer using setup.py to avoid build-system dependencies if we have a setup.py
if [ -z "${dontPreferSetupPy-}" ]; then
if test -e setup.py && test -e pyproject.toml; then
echo "Removing pyproject.toml..."
rm -f pyproject.toml
fi
fi
mkdir -p dist
echo "Creating a wheel..."
@pythonInterpreter@ -m pip wheel --no-index --no-deps --no-clean --no-build-isolation --wheel-dir dist .
echo "Finished creating a wheel..."
runHook postBuild
echo "Finished executing pipBuildPhase"
}
pipShellHook() {
echo "Executing pipShellHook"
runHook preShellHook
# Long-term setup.py should be dropped.
if [ -e pyproject.toml ]; then
tmp_path=$(mktemp -d)
export PATH="$tmp_path/bin:$PATH"
export PYTHONPATH="$tmp_path/@pythonSitePackages@:$PYTHONPATH"
mkdir -p "$tmp_path/@pythonSitePackages@"
@pythonInterpreter@ -m pip install -e . --prefix "$tmp_path" >&2
fi
runHook postShellHook
echo "Finished executing pipShellHook"
}
if [ -z "${dontUsePipBuild-}" ] && [ -z "${buildPhase-}" ]; then
echo "Using pipBuildPhase"
buildPhase=pipBuildPhase
fi
if [ -z "${shellHook-}" ]; then
echo "Using pipShellHook"
shellHook=pipShellHook
fi

View File

@ -6,7 +6,14 @@ import sys
data = json.load(sys.stdin) data = json.load(sys.stdin)
for dep in data['tool']['poetry']['dependencies'].values():
def get_deep(o, path):
for p in path.split('.'):
o = o.get(p, {})
return o
for dep in get_deep(data, 'tool.poetry.dependencies').values():
if isinstance(dep, dict): if isinstance(dep, dict):
try: try:
del dep['path']; del dep['path'];

View File

@ -8,6 +8,20 @@ let
genList (i: if i == idx then value else (builtins.elemAt list i)) (length list) genList (i: if i == idx then value else (builtins.elemAt list i)) (length list)
); );
# Do some canonicalisation of module names
moduleName = name: lib.toLower (lib.replaceStrings [ "_" "." ] [ "-" "-" ] name);
# Get a full semver pythonVersion from a python derivation
getPythonVersion = python:
let
pyVer = lib.splitVersion python.pythonVersion ++ [ "0" ];
ver = lib.splitVersion python.version;
major = l: lib.elemAt l 0;
minor = l: lib.elemAt l 1;
joinVersion = v: lib.concatStringsSep "." v;
in
joinVersion ( if major pyVer == major ver && minor pyVer == minor ver then ver else pyVer);
# Compare a semver expression with a version # Compare a semver expression with a version
isCompatible = version: isCompatible = version:
let let
@ -31,13 +45,13 @@ let
state = operators."${operator}" acc.state (satisfiesSemver version v); state = operators."${operator}" acc.state (satisfiesSemver version v);
}; };
initial = { operator = "&&"; state = true; }; initial = { operator = "&&"; state = true; };
in in if expr == "" then true else (builtins.foldl' combine initial tokens).state;
if expr == "" then true else (builtins.foldl' combine initial tokens).state;
fromTOML = builtins.fromTOML or fromTOML = builtins.fromTOML or
( (
toml: builtins.fromJSON ( toml: builtins.fromJSON
builtins.readFile ( (
builtins.readFile
(
pkgs.runCommand "from-toml" pkgs.runCommand "from-toml"
{ {
inherit toml; inherit toml;
@ -66,7 +80,58 @@ let
if lib.strings.hasInfix "manylinux1" f then { pkg = [ ml.manylinux1 ]; str = "1"; } if lib.strings.hasInfix "manylinux1" f then { pkg = [ ml.manylinux1 ]; str = "1"; }
else if lib.strings.hasInfix "manylinux2010" f then { pkg = [ ml.manylinux2010 ]; str = "2010"; } else if lib.strings.hasInfix "manylinux2010" f then { pkg = [ ml.manylinux2010 ]; str = "2010"; }
else if lib.strings.hasInfix "manylinux2014" f then { pkg = [ ml.manylinux2014 ]; str = "2014"; } else if lib.strings.hasInfix "manylinux2014" f then { pkg = [ ml.manylinux2014 ]; str = "2014"; }
else { pkg = []; str = null; }; else { pkg = [ ]; str = null; };
# Predict URL from the PyPI index.
# Args:
# pname: package name
# file: filename including extension
# hash: SRI hash
# kind: Language implementation and version tag
predictURLFromPypi = lib.makeOverridable
(
{ pname, file, hash, kind }:
"https://files.pythonhosted.org/packages/${kind}/${lib.toLower (builtins.substring 0 1 file)}/${pname}/${file}"
);
# Fetch the wheels from the PyPI index.
# We need to first get the proper URL to the wheel.
# Args:
# pname: package name
# file: filename including extension
# hash: SRI hash
# kind: Language implementation and version tag
fetchWheelFromPypi = lib.makeOverridable
(
{ pname, file, hash, kind, curlOpts ? "" }:
let
version = builtins.elemAt (builtins.split "-" file) 2;
in
(pkgs.stdenvNoCC.mkDerivation {
name = file;
nativeBuildInputs = [
pkgs.curl
pkgs.jq
];
isWheel = true;
system = "builtin";
preferLocalBuild = true;
impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ [
"NIX_CURL_FLAGS"
];
predictedURL = predictURLFromPypi { inherit pname file hash kind; };
inherit pname file version curlOpts;
builder = ./fetch-wheel.sh;
outputHashMode = "flat";
outputHashAlgo = "sha256";
outputHash = hash;
})
);
# Fetch the artifacts from the PyPI index. Since we get all # Fetch the artifacts from the PyPI index. Since we get all
# info we need from the lock file we don't use nixpkgs' fetchPyPi # info we need from the lock file we don't use nixpkgs' fetchPyPi
@ -78,23 +143,25 @@ let
# file: filename including extension # file: filename including extension
# hash: SRI hash # hash: SRI hash
# kind: Language implementation and version tag https://www.python.org/dev/peps/pep-0427/#file-name-convention # kind: Language implementation and version tag https://www.python.org/dev/peps/pep-0427/#file-name-convention
fetchFromPypi = lib.makeOverridable ( fetchFromPypi = lib.makeOverridable
(
{ pname, file, hash, kind }: { pname, file, hash, kind }:
if lib.strings.hasSuffix "whl" file then fetchWheelFromPypi { inherit pname file hash kind; }
else
pkgs.fetchurl { pkgs.fetchurl {
url = "https://files.pythonhosted.org/packages/${kind}/${lib.toLower (builtins.substring 0 1 file)}/${pname}/${file}"; url = predictURLFromPypi { inherit pname file hash kind; };
inherit hash; inherit hash;
} }
); );
getBuildSystemPkgs = getBuildSystemPkgs =
{ pythonPackages { pythonPackages
, pyProject , pyProject
}: }:
let let
buildSystem = lib.getAttrFromPath [ "build-system" "build-backend" ] pyProject; buildSystem = lib.attrByPath [ "build-system" "build-backend" ] "" pyProject;
drvAttr = builtins.elemAt (builtins.split "\\.|:" buildSystem) 0; drvAttr = moduleName (builtins.elemAt (builtins.split "\\.|:" buildSystem) 0);
in in
if buildSystem == "" then [] else ( if buildSystem == "" then [ ] else (
[ pythonPackages.${drvAttr} or (throw "unsupported build system ${buildSystem}") ] [ pythonPackages.${drvAttr} or (throw "unsupported build system ${buildSystem}") ]
); );
@ -105,7 +172,7 @@ let
gitIgnore = path + "/.gitignore"; gitIgnore = path + "/.gitignore";
isGitRoot = builtins.pathExists (path + "/.git"); isGitRoot = builtins.pathExists (path + "/.git");
hasGitIgnore = builtins.pathExists gitIgnore; hasGitIgnore = builtins.pathExists gitIgnore;
gitIgnores = if hasGitIgnore then [ gitIgnore ] else []; gitIgnores = if hasGitIgnore then [ gitIgnore ] else [ ];
in in
lib.optionals (builtins.toString path != "/" && ! isGitRoot) (findGitIgnores parent) ++ gitIgnores; lib.optionals (builtins.toString path != "/" && ! isGitRoot) (findGitIgnores parent) ++ gitIgnores;
@ -135,11 +202,14 @@ in
{ {
inherit inherit
fetchFromPypi fetchFromPypi
fetchWheelFromPypi
getManyLinuxDeps getManyLinuxDeps
isCompatible isCompatible
readTOML readTOML
getBuildSystemPkgs getBuildSystemPkgs
satisfiesSemver satisfiesSemver
cleanPythonSources cleanPythonSources
moduleName
getPythonVersion
; ;
} }

View File

@ -10,62 +10,56 @@
, version , version
, files , files
, source , source
, dependencies ? {} , dependencies ? { }
, pythonPackages , pythonPackages
, python-versions , python-versions
, pwd , pwd
, sourceSpec , sourceSpec
, supportedExtensions ? lib.importJSON ./extensions.json , supportedExtensions ? lib.importJSON ./extensions.json
, preferWheels ? false
, ... , ...
}: }:
pythonPackages.callPackage ( pythonPackages.callPackage
{ preferWheel ? false (
{ preferWheel ? preferWheels
, ... , ...
}@args: }@args:
let let
inherit (poetryLib) isCompatible getManyLinuxDeps fetchFromPypi; inherit (poetryLib) isCompatible getManyLinuxDeps fetchFromPypi moduleName;
inherit (import ./pep425.nix { inherit (import ./pep425.nix {
inherit lib python; inherit lib python;
inherit (pkgs) stdenv; inherit (pkgs) stdenv;
}) selectWheel }) selectWheel
; ;
fileCandidates =
fileCandidates = let let
supportedRegex = ("^.*?(" + builtins.concatStringsSep "|" supportedExtensions + ")"); supportedRegex = ("^.*?(" + builtins.concatStringsSep "|" supportedExtensions + ")");
matchesVersion = fname: builtins.match ("^.*" + builtins.replaceStrings [ "." ] [ "\\." ] version + ".*$") fname != null; matchesVersion = fname: builtins.match ("^.*" + builtins.replaceStrings [ "." ] [ "\\." ] version + ".*$") fname != null;
hasSupportedExtension = fname: builtins.match supportedRegex fname != null; hasSupportedExtension = fname: builtins.match supportedRegex fname != null;
isCompatibleEgg = fname: ! lib.strings.hasSuffix ".egg" fname || lib.strings.hasSuffix "py${python.pythonVersion}.egg" fname; isCompatibleEgg = fname: ! lib.strings.hasSuffix ".egg" fname || lib.strings.hasSuffix "py${python.pythonVersion}.egg" fname;
in in
builtins.filter (f: matchesVersion f.file && hasSupportedExtension f.file && isCompatibleEgg f.file) files; builtins.filter (f: matchesVersion f.file && hasSupportedExtension f.file && isCompatibleEgg f.file) files;
toPath = s: pwd + "/${s}"; toPath = s: pwd + "/${s}";
isSource = source != null; isSource = source != null;
isGit = isSource && source.type == "git"; isGit = isSource && source.type == "git";
isLocal = isSource && source.type == "directory"; isLocal = isSource && source.type == "directory";
localDepPath = toPath source.url; localDepPath = toPath source.url;
pyProject = poetryLib.readTOML (localDepPath + "/pyproject.toml"); pyProject = poetryLib.readTOML (localDepPath + "/pyproject.toml");
buildSystemPkgs = poetryLib.getBuildSystemPkgs { buildSystemPkgs = poetryLib.getBuildSystemPkgs {
inherit pythonPackages pyProject; inherit pythonPackages pyProject;
}; };
fileInfo =
fileInfo = let let
isBdist = f: lib.strings.hasSuffix "whl" f.file; isBdist = f: lib.strings.hasSuffix "whl" f.file;
isSdist = f: ! isBdist f && ! isEgg f; isSdist = f: ! isBdist f && ! isEgg f;
isEgg = f: lib.strings.hasSuffix ".egg" f.file; isEgg = f: lib.strings.hasSuffix ".egg" f.file;
binaryDist = selectWheel fileCandidates; binaryDist = selectWheel fileCandidates;
sourceDist = builtins.filter isSdist fileCandidates; sourceDist = builtins.filter isSdist fileCandidates;
eggs = builtins.filter isEgg fileCandidates; eggs = builtins.filter isEgg fileCandidates;
entries = ( if preferWheel then binaryDist ++ sourceDist else sourceDist ++ binaryDist) ++ eggs;
entries = (if preferWheel then binaryDist ++ sourceDist else sourceDist ++ binaryDist) ++ eggs;
lockFileEntry = builtins.head entries; lockFileEntry = builtins.head entries;
_isEgg = isEgg lockFileEntry; _isEgg = isEgg lockFileEntry;
in in
rec { rec {
@ -74,10 +68,10 @@ pythonPackages.callPackage (
format = format =
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 "setuptools"; else "pyproject";
kind = kind =
if _isEgg then python.pythonVersion if _isEgg then python.pythonVersion
else if format == "setuptools" then "source" else if format == "pyproject" then "source"
else (builtins.elemAt (lib.strings.splitString "-" name) 2); else (builtins.elemAt (lib.strings.splitString "-" name) 2);
}; };
@ -88,12 +82,10 @@ pythonPackages.callPackage (
"toml" # Toml is an extra for setuptools-scm "toml" # Toml is an extra for setuptools-scm
]; ];
baseBuildInputs = lib.optional (! lib.elem name skipSetupToolsSCM) pythonPackages.setuptools-scm; baseBuildInputs = lib.optional (! lib.elem name skipSetupToolsSCM) pythonPackages.setuptools-scm;
format = if isLocal then "pyproject" else if isGit then "pyproject" else fileInfo.format;
format = if isLocal then "pyproject" else if isGit then "setuptools" else fileInfo.format;
in in
buildPythonPackage { buildPythonPackage {
pname = name; pname = moduleName name;
version = version; version = version;
inherit format; inherit format;
@ -116,10 +108,13 @@ pythonPackages.callPackage (
++ lib.optional isLocal buildSystemPkgs ++ lib.optional isLocal buildSystemPkgs
); );
propagatedBuildInputs = let propagatedBuildInputs =
compat = isCompatible python.pythonVersion; let
deps = lib.filterAttrs (n: v: v) ( compat = isCompatible (poetryLib.getPythonVersion python);
lib.mapAttrs ( deps = lib.filterAttrs (n: v: v)
(
lib.mapAttrs
(
n: v: n: v:
let let
constraints = v.python or ""; constraints = v.python or "";
@ -129,11 +124,11 @@ pythonPackages.callPackage (
); );
depAttrs = lib.attrNames deps; depAttrs = lib.attrNames deps;
in in
builtins.map (n: pythonPackages.${lib.toLower n}) depAttrs; builtins.map (n: pythonPackages.${moduleName n}) depAttrs;
meta = { meta = {
broken = ! isCompatible python.pythonVersion python-versions; broken = ! isCompatible (poetryLib.getPythonVersion python) python-versions;
license = []; license = [ ];
inherit (python.meta) platforms; inherit (python.meta) platforms;
}; };
@ -144,7 +139,8 @@ pythonPackages.callPackage (
# We need to retrieve kind from the interpreter and the filename of the package # 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) # Interpreters should declare what wheel types they're compatible with (python type + ABI)
# Here we can then choose a file based on that info. # Here we can then choose a file based on that info.
src = if isGit then ( src =
if isGit then (
builtins.fetchGit { builtins.fetchGit {
inherit (source) url; inherit (source) url;
rev = source.reference; rev = source.reference;
@ -155,5 +151,4 @@ pythonPackages.callPackage (
inherit (fileInfo) file hash kind; inherit (fileInfo) file hash kind;
}; };
} }
) { }
) {}

View File

@ -1,4 +1,4 @@
{ pkgs ? import <nixpkgs> {} { pkgs ? import <nixpkgs> { }
, lib ? pkgs.lib , lib ? pkgs.lib
, stdenv ? pkgs.stdenv , stdenv ? pkgs.stdenv
}: }:
@ -6,14 +6,16 @@
self: super: self: super:
{ {
astroid = super.astroid.overridePythonAttrs ( astroid = super.astroid.overridePythonAttrs
(
old: rec { old: rec {
buildInputs = old.buildInputs ++ [ self.pytest-runner ]; buildInputs = old.buildInputs ++ [ self.pytest-runner ];
doCheck = false; doCheck = false;
} }
); );
av = super.av.overridePythonAttrs ( av = super.av.overridePythonAttrs
(
old: { old: {
nativeBuildInputs = old.nativeBuildInputs ++ [ nativeBuildInputs = old.nativeBuildInputs ++ [
pkgs.pkgconfig pkgs.pkgconfig
@ -22,7 +24,8 @@ self: super:
} }
); );
bcrypt = super.bcrypt.overridePythonAttrs ( bcrypt = super.bcrypt.overridePythonAttrs
(
old: { old: {
buildInputs = old.buildInputs ++ [ pkgs.libffi ]; buildInputs = old.buildInputs ++ [ pkgs.libffi ];
} }
@ -31,14 +34,16 @@ self: super:
cffi = cffi =
# cffi is bundled with pypy # cffi is bundled with pypy
if self.python.implementation == "pypy" then null else ( if self.python.implementation == "pypy" then null else (
super.cffi.overridePythonAttrs ( super.cffi.overridePythonAttrs
(
old: { old: {
buildInputs = old.buildInputs ++ [ pkgs.libffi ]; buildInputs = old.buildInputs ++ [ pkgs.libffi ];
} }
) )
); );
cftime = super.cftime.overridePythonAttrs ( cftime = super.cftime.overridePythonAttrs
(
old: { old: {
buildInputs = old.buildInputs ++ [ buildInputs = old.buildInputs ++ [
self.cython self.cython
@ -46,22 +51,38 @@ self: super:
} }
); );
cryptography = super.cryptography.overridePythonAttrs ( configparser = super.configparser.overridePythonAttrs
(
old: {
buildInputs = old.buildInputs ++ [
self.toml
];
postPatch = ''
substituteInPlace setup.py --replace 'setuptools.setup()' 'setuptools.setup(version="${old.version}")'
'';
}
);
cryptography = super.cryptography.overridePythonAttrs
(
old: { old: {
buildInputs = old.buildInputs ++ [ pkgs.openssl ]; buildInputs = old.buildInputs ++ [ pkgs.openssl ];
} }
); );
django = ( django = (
super.django.overridePythonAttrs ( super.django.overridePythonAttrs
(
old: { old: {
propagatedNativeBuildInputs = (old.propagatedNativeBuildInputs or []) propagatedNativeBuildInputs = (old.propagatedNativeBuildInputs or [ ])
++ [ pkgs.gettext ]; ++ [ pkgs.gettext ];
} }
) )
); );
django-bakery = super.django-bakery.overridePythonAttrs ( django-bakery = super.django-bakery.overridePythonAttrs
(
old: { old: {
configurePhase = '' configurePhase = ''
if ! test -e LICENSE; then if ! test -e LICENSE; then
@ -71,7 +92,8 @@ self: super:
} }
); );
dlib = super.dlib.overridePythonAttrs ( dlib = super.dlib.overridePythonAttrs
(
old: { old: {
# Parallel building enabled # Parallel building enabled
inherit (pkgs.python.pkgs.dlib) patches; inherit (pkgs.python.pkgs.dlib) patches;
@ -87,14 +109,16 @@ self: super:
# Environment markers are not always included (depending on how a dep was defined) # Environment markers are not always included (depending on how a dep was defined)
enum34 = if self.pythonAtLeast "3.4" then null else super.enum34; enum34 = if self.pythonAtLeast "3.4" then null else super.enum34;
faker = super.faker.overridePythonAttrs ( faker = super.faker.overridePythonAttrs
(
old: { old: {
buildInputs = old.buildInputs ++ [ self.pytest-runner ]; buildInputs = old.buildInputs ++ [ self.pytest-runner ];
doCheck = false; doCheck = false;
} }
); );
fancycompleter = super.fancycompleter.overridePythonAttrs ( fancycompleter = super.fancycompleter.overridePythonAttrs
(
old: { old: {
postPatch = '' postPatch = ''
substituteInPlace setup.py \ substituteInPlace setup.py \
@ -104,44 +128,58 @@ self: super:
} }
); );
fastparquet = super.fastparquet.overridePythonAttrs ( fastparquet = super.fastparquet.overridePythonAttrs
(
old: { old: {
buildInputs = old.buildInputs ++ [ self.pytest-runner ]; buildInputs = old.buildInputs ++ [ self.pytest-runner ];
} }
); );
grandalf = super.grandalf.overridePythonAttrs ( grandalf = super.grandalf.overridePythonAttrs
(
old: { old: {
buildInputs = old.buildInputs ++ [ self.pytest-runner ]; buildInputs = old.buildInputs ++ [ self.pytest-runner ];
doCheck = false; doCheck = false;
} }
); );
h5py = super.h5py.overridePythonAttrs ( h5py = super.h5py.overridePythonAttrs
old: rec { (
old:
if old.format != "wheel" then rec {
nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.pkgconfig ]; nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.pkgconfig ];
buildInputs = old.buildInputs ++ [ pkgs.hdf5 self.pkgconfig self.cython ]; buildInputs = old.buildInputs ++ [ pkgs.hdf5 self.pkgconfig self.cython ];
configure_flags = "--hdf5=${pkgs.hdf5}"; configure_flags = "--hdf5=${pkgs.hdf5}";
postConfigure = '' postConfigure = ''
${self.python.executable} setup.py configure ${configure_flags} ${self.python.executable} setup.py configure ${configure_flags}
''; '';
} } else old
); );
horovod = super.horovod.overridePythonAttrs ( horovod = super.horovod.overridePythonAttrs
(
old: { old: {
propagatedBuildInputs = old.propagatedBuildInputs ++ [ pkgs.openmpi ]; propagatedBuildInputs = old.propagatedBuildInputs ++ [ pkgs.openmpi ];
} }
); );
# importlib-metadata has an incomplete dependency specification # importlib-metadata has an incomplete dependency specification
importlib-metadata = super.importlib-metadata.overridePythonAttrs ( importlib-metadata = super.importlib-metadata.overridePythonAttrs
(
old: { old: {
propagatedBuildInputs = old.propagatedBuildInputs ++ lib.optional self.python.isPy2 self.pathlib2; propagatedBuildInputs = old.propagatedBuildInputs ++ lib.optional self.python.isPy2 self.pathlib2;
} }
); );
jupyter = super.jupyter.overridePythonAttrs ( isort = super.isort.overridePythonAttrs
(
old: {
propagatedBuildInputs = old.propagatedBuildInputs ++ [ self.setuptools ];
}
);
jupyter = super.jupyter.overridePythonAttrs
(
old: rec { old: rec {
# jupyter is a meta-package. Everything relevant comes from the # jupyter is a meta-package. Everything relevant comes from the
# dependencies. It does however have a jupyter.py file that conflicts # dependencies. It does however have a jupyter.py file that conflicts
@ -150,7 +188,18 @@ self: super:
} }
); );
lap = super.lap.overridePythonAttrs ( kiwisolver = super.kiwisolver.overridePythonAttrs
(
old: {
buildInputs = old.buildInputs ++ [
# cppy is at the time of writing not in nixpkgs
(self.cppy or null)
];
}
);
lap = super.lap.overridePythonAttrs
(
old: { old: {
propagatedBuildInputs = old.propagatedBuildInputs ++ [ propagatedBuildInputs = old.propagatedBuildInputs ++ [
self.numpy self.numpy
@ -158,7 +207,8 @@ self: super:
} }
); );
llvmlite = super.llvmlite.overridePythonAttrs ( llvmlite = super.llvmlite.overridePythonAttrs
(
old: { old: {
nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.llvm ]; nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.llvm ];
@ -181,26 +231,30 @@ self: super:
} }
); );
lockfile = super.lockfile.overridePythonAttrs ( lockfile = super.lockfile.overridePythonAttrs
(
old: { old: {
propagatedBuildInputs = old.propagatedBuildInputs ++ [ self.pbr ]; propagatedBuildInputs = old.propagatedBuildInputs ++ [ self.pbr ];
} }
); );
lxml = super.lxml.overridePythonAttrs ( lxml = super.lxml.overridePythonAttrs
(
old: { old: {
nativeBuildInputs = with pkgs; old.nativeBuildInputs ++ [ pkgconfig libxml2.dev libxslt.dev ]; nativeBuildInputs = with pkgs; old.nativeBuildInputs ++ [ pkgconfig libxml2.dev libxslt.dev ];
buildInputs = with pkgs; old.buildInputs ++ [ libxml2 libxslt ]; buildInputs = with pkgs; old.buildInputs ++ [ libxml2 libxslt ];
} }
); );
markupsafe = super.markupsafe.overridePythonAttrs ( markupsafe = super.markupsafe.overridePythonAttrs
(
old: { old: {
src = old.src.override { pname = builtins.replaceStrings [ "markupsafe" ] [ "MarkupSafe" ] old.pname; }; src = old.src.override { pname = builtins.replaceStrings [ "markupsafe" ] [ "MarkupSafe" ] old.pname; };
} }
); );
matplotlib = super.matplotlib.overridePythonAttrs ( matplotlib = super.matplotlib.overridePythonAttrs
(
old: old:
let let
enableGhostscript = old.passthru.enableGhostscript or false; enableGhostscript = old.passthru.enableGhostscript or false;
@ -241,14 +295,16 @@ self: super:
preferWheel = true; preferWheel = true;
}; };
mccabe = super.mccabe.overridePythonAttrs ( mccabe = super.mccabe.overridePythonAttrs
(
old: { old: {
buildInputs = old.buildInputs ++ [ self.pytest-runner ]; buildInputs = old.buildInputs ++ [ self.pytest-runner ];
doCheck = false; doCheck = false;
} }
); );
netcdf4 = super.netcdf4.overridePythonAttrs ( netcdf4 = super.netcdf4.overridePythonAttrs
(
old: { old: {
buildInputs = old.buildInputs ++ [ buildInputs = old.buildInputs ++ [
self.cython self.cython
@ -271,19 +327,25 @@ self: super:
} }
); );
numpy = super.numpy.overridePythonAttrs ( numpy = super.numpy.overridePythonAttrs
(
old: old:
let let
blas = old.passthru.args.blas or pkgs.openblasCompat; blas = old.passthru.args.blas or pkgs.openblasCompat;
lapack = old.passthru.args.lapack or pkgs.openblasCompat; blasImplementation = lib.nameFromURL blas.name "-";
cfg = pkgs.writeTextFile { cfg = pkgs.writeTextFile {
name = "site.cfg"; name = "site.cfg";
text = (lib.generators.toINI {} { text = (
${blas.implementation} = { lib.generators.toINI { } {
include_dirs = "${blas}/include:${lapack}/include"; ${blasImplementation} = {
library_dirs = "${blas}/lib:${lapack}/lib"; include_dirs = "${blas}/include";
library_dirs = "${blas}/lib";
} // lib.optionalAttrs (blasImplementation == "mkl") {
mkl_libs = "mkl_rt";
lapack_libs = "";
}; };
}); }
);
}; };
in in
{ {
@ -294,20 +356,22 @@ self: super:
ln -s ${cfg} site.cfg ln -s ${cfg} site.cfg
''; '';
passthru = old.passthru // { passthru = old.passthru // {
blsaImplementation = blas.implementation; blas = blas;
inherit blas cfg; inherit blasImplementation cfg;
}; };
} }
); );
openexr = super.openexr.overridePythonAttrs ( openexr = super.openexr.overridePythonAttrs
(
old: rec { old: rec {
buildInputs = old.buildInputs ++ [ pkgs.openexr pkgs.ilmbase ]; buildInputs = old.buildInputs ++ [ pkgs.openexr pkgs.ilmbase ];
NIX_CFLAGS_COMPILE = [ "-I${pkgs.openexr.dev}/include/OpenEXR" "-I${pkgs.ilmbase.dev}/include/OpenEXR" ]; NIX_CFLAGS_COMPILE = [ "-I${pkgs.openexr.dev}/include/OpenEXR" "-I${pkgs.ilmbase.dev}/include/OpenEXR" ];
} }
); );
peewee = super.peewee.overridePythonAttrs ( peewee = super.peewee.overridePythonAttrs
(
old: old:
let let
withPostgres = old.passthru.withPostgres or false; withPostgres = old.passthru.withPostgres or false;
@ -321,41 +385,91 @@ self: super:
} }
); );
pillow = super.pillow.overridePythonAttrs ( pillow = super.pillow.overridePythonAttrs
(
old: { old: {
nativeBuildInputs = [ pkgs.pkgconfig ] ++ old.nativeBuildInputs; nativeBuildInputs = [ pkgs.pkgconfig ] ++ old.nativeBuildInputs;
buildInputs = with pkgs; [ freetype libjpeg zlib libtiff libwebp tcl lcms2 ] ++ old.buildInputs; buildInputs = with pkgs; [ freetype libjpeg zlib libtiff libwebp tcl lcms2 ] ++ old.buildInputs;
} }
); );
psycopg2 = super.psycopg2.overridePythonAttrs ( psycopg2 = super.psycopg2.overridePythonAttrs
(
old: { old: {
nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.postgresql ]; nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.postgresql ];
} }
); );
psycopg2-binary = super.psycopg2-binary.overridePythonAttrs ( psycopg2-binary = super.psycopg2-binary.overridePythonAttrs
(
old: { old: {
nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.postgresql ]; nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.postgresql ];
} }
); );
pyarrow = super.pyarrow.overridePythonAttrs ( pyarrow =
old: { if lib.versionAtLeast super.pyarrow.version "0.16.0" then super.pyarrow.overridePythonAttrs
(
old:
let
parseMinor = drv: lib.concatStringsSep "." (lib.take 2 (lib.splitVersion drv.version));
_arrow-cpp = pkgs.arrow-cpp.override { inherit (self) python; };
ARROW_HOME = _arrow-cpp;
arrowCppVersion = parseMinor pkgs.arrow-cpp;
pyArrowVersion = parseMinor super.pyarrow;
errorMessage = "arrow-cpp version (${arrowCppVersion}) mismatches pyarrow version (${pyArrowVersion})";
in
if arrowCppVersion != pyArrowVersion then throw errorMessage else {
nativeBuildInputs = old.nativeBuildInputs ++ [
self.cython
pkgs.pkgconfig
pkgs.cmake
];
preBuild = ''
export PYARROW_PARALLEL=$NIX_BUILD_CORES
'';
PARQUET_HOME = _arrow-cpp;
inherit ARROW_HOME;
buildInputs = old.buildInputs ++ [ buildInputs = old.buildInputs ++ [
pkgs.arrow-cpp
];
PYARROW_BUILD_TYPE = "release";
PYARROW_WITH_PARQUET = true;
PYARROW_CMAKE_OPTIONS = [
"-DCMAKE_INSTALL_RPATH=${ARROW_HOME}/lib"
# This doesn't use setup hook to call cmake so we need to workaround #54606
# ourselves
"-DCMAKE_POLICY_DEFAULT_CMP0025=NEW"
];
dontUseCmakeConfigure = true;
}
) else super.pyarrow.overridePythonAttrs
(
old: {
nativeBuildInputs = old.nativeBuildInputs ++ [
self.cython self.cython
]; ];
} }
); );
pycairo = ( pycairo =
(
drv: ( drv: (
drv.overridePythonAttrs ( drv.overridePythonAttrs
(
_: { _: {
format = "other"; format = "other";
} }
) )
).overridePythonAttrs ( ).overridePythonAttrs
(
old: { old: {
nativeBuildInputs = old.nativeBuildInputs ++ [ nativeBuildInputs = old.nativeBuildInputs ++ [
@ -369,12 +483,13 @@ self: super:
pkgs.xlibsWrapper pkgs.xlibsWrapper
]; ];
mesonFlags = [ "-Dpython=${if self.isPy3k then "python3" else "python"}" ]; mesonFlags = [ "-Dpython=${ if self.isPy3k then "python3" else "python"}" ];
} }
) )
) super.pycairo; ) super.pycairo;
pycocotools = super.pycocotools.overridePythonAttrs ( pycocotools = super.pycocotools.overridePythonAttrs
(
old: { old: {
buildInputs = old.buildInputs ++ [ buildInputs = old.buildInputs ++ [
self.cython self.cython
@ -383,34 +498,39 @@ self: super:
} }
); );
pygobject = super.pygobject.overridePythonAttrs ( pygobject = super.pygobject.overridePythonAttrs
(
old: { old: {
nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.pkgconfig ]; nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.pkgconfig ];
buildInputs = old.buildInputs ++ [ pkgs.glib pkgs.gobject-introspection ]; buildInputs = old.buildInputs ++ [ pkgs.glib pkgs.gobject-introspection ];
} }
); );
pylint = super.pylint.overridePythonAttrs ( pylint = super.pylint.overridePythonAttrs
(
old: { old: {
buildInputs = old.buildInputs ++ [ self.pytest-runner ]; buildInputs = old.buildInputs ++ [ self.pytest-runner ];
doCheck = false; doCheck = false;
} }
); );
pyopenssl = super.pyopenssl.overridePythonAttrs ( pyopenssl = super.pyopenssl.overridePythonAttrs
(
old: { old: {
buildInputs = old.buildInputs ++ [ pkgs.openssl ]; buildInputs = old.buildInputs ++ [ pkgs.openssl ];
} }
); );
pyqt5 = let pyqt5 =
let
drv = super.pyqt5; drv = super.pyqt5;
withConnectivity = drv.passthru.args.withConnectivity or false; withConnectivity = drv.passthru.args.withConnectivity or false;
withMultimedia = drv.passthru.args.withMultimedia or false; withMultimedia = drv.passthru.args.withMultimedia or false;
withWebKit = drv.passthru.args.withWebKit or false; withWebKit = drv.passthru.args.withWebKit or false;
withWebSockets = drv.passthru.args.withWebSockets or false; withWebSockets = drv.passthru.args.withWebSockets or false;
in in
super.pyqt5.overridePythonAttrs ( super.pyqt5.overridePythonAttrs
(
old: { old: {
format = "other"; format = "other";
@ -444,7 +564,7 @@ self: super:
; ;
# Fix dbus mainloop # Fix dbus mainloop
patches = pkgs.python3.pkgs.pyqt5.patches or []; patches = pkgs.python3.pkgs.pyqt5.patches or [ ];
configurePhase = '' configurePhase = ''
runHook preConfigure runHook preConfigure
@ -477,7 +597,8 @@ self: super:
EOF EOF
''; '';
installCheckPhase = let installCheckPhase =
let
modules = [ modules = [
"PyQt5" "PyQt5"
"PyQt5.QtCore" "PyQt5.QtCore"
@ -490,7 +611,6 @@ self: super:
++ lib.optional withMultimedia "PyQt5.QtMultimedia" ++ lib.optional withMultimedia "PyQt5.QtMultimedia"
++ lib.optional withConnectivity "PyQt5.QtConnectivity" ++ lib.optional withConnectivity "PyQt5.QtConnectivity"
; ;
imports = lib.concatMapStrings (module: "import ${module};") modules; imports = lib.concatMapStrings (module: "import ${module};") modules;
in in
'' ''
@ -504,7 +624,8 @@ self: super:
} }
); );
pytest-datadir = super.pytest-datadir.overridePythonAttrs ( pytest-datadir = super.pytest-datadir.overridePythonAttrs
(
old: { old: {
postInstall = '' postInstall = ''
rm -f $out/LICENSE rm -f $out/LICENSE
@ -512,7 +633,8 @@ self: super:
} }
); );
pytest = super.pytest.overridePythonAttrs ( pytest = super.pytest.overridePythonAttrs
(
old: { old: {
doCheck = false; doCheck = false;
} }
@ -520,7 +642,18 @@ self: super:
pytest-runner = super.pytest-runner or super.pytestrunner; pytest-runner = super.pytest-runner or super.pytestrunner;
python-prctl = super.python-prctl.overridePythonAttrs ( python-jose = super.python-jose.overridePythonAttrs
(
old: {
postPath = ''
substituteInPlace setup.py --replace "'pytest-runner'," ""
substituteInPlace setup.py --replace "'pytest-runner'" ""
'';
}
);
python-prctl = super.python-prctl.overridePythonAttrs
(
old: { old: {
buildInputs = old.buildInputs ++ [ buildInputs = old.buildInputs ++ [
pkgs.libcap pkgs.libcap
@ -528,14 +661,16 @@ self: super:
} }
); );
pyzmq = super.pyzmq.overridePythonAttrs ( pyzmq = super.pyzmq.overridePythonAttrs
(
old: { old: {
nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.pkgconfig ]; nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.pkgconfig ];
propagatedBuildInputs = old.propagatedBuildInputs ++ [ pkgs.zeromq ]; propagatedBuildInputs = old.propagatedBuildInputs ++ [ pkgs.zeromq ];
} }
); );
rockset = super.rockset.overridePythonAttrs ( rockset = super.rockset.overridePythonAttrs
(
old: rec { old: rec {
postPatch = '' postPatch = ''
cp ./setup_rockset.py ./setup.py cp ./setup_rockset.py ./setup.py
@ -543,7 +678,8 @@ self: super:
} }
); );
scaleapi = super.scaleapi.overridePythonAttrs ( scaleapi = super.scaleapi.overridePythonAttrs
(
old: { old: {
postPatch = '' postPatch = ''
substituteInPlace setup.py --replace "install_requires = ['requests>=2.4.2', 'enum34']" "install_requires = ['requests>=2.4.2']" || true substituteInPlace setup.py --replace "install_requires = ['requests>=2.4.2', 'enum34']" "install_requires = ['requests>=2.4.2']" || true
@ -551,7 +687,8 @@ self: super:
} }
); );
pandas = super.pandas.overridePythonAttrs ( pandas = super.pandas.overridePythonAttrs
(
old: { old: {
nativeBuildInputs = old.nativeBuildInputs ++ [ self.cython ]; nativeBuildInputs = old.nativeBuildInputs ++ [ self.cython ];
} }
@ -559,17 +696,20 @@ self: super:
# Pybind11 is an undeclared dependency of scipy that we need to pick from nixpkgs # Pybind11 is an undeclared dependency of scipy that we need to pick from nixpkgs
# Make it not fail with infinite recursion # Make it not fail with infinite recursion
pybind11 = super.pybind11.overridePythonAttrs ( pybind11 = super.pybind11.overridePythonAttrs
(
old: { old: {
cmakeFlags = (old.cmakeFlags or []) ++ [ cmakeFlags = (old.cmakeFlags or [ ]) ++ [
"-DPYBIND11_TEST=off" "-DPYBIND11_TEST=off"
]; ];
doCheck = false; # Circular test dependency doCheck = false; # Circular test dependency
} }
); );
scipy = super.scipy.overridePythonAttrs ( scipy = super.scipy.overridePythonAttrs
old: { (
old:
if old.format != "wheel" then {
nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.gfortran ]; nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.gfortran ];
propagatedBuildInputs = old.propagatedBuildInputs ++ [ self.pybind11 ]; propagatedBuildInputs = old.propagatedBuildInputs ++ [ self.pybind11 ];
setupPyBuildFlags = [ "--fcompiler='gnu95'" ]; setupPyBuildFlags = [ "--fcompiler='gnu95'" ];
@ -582,10 +722,11 @@ self: super:
preBuild = '' preBuild = ''
ln -s ${self.numpy.cfg} site.cfg ln -s ${self.numpy.cfg} site.cfg
''; '';
} } else old
); );
scikit-learn = super.scikit-learn.overridePythonAttrs ( scikit-learn = super.scikit-learn.overridePythonAttrs
(
old: { old: {
buildInputs = old.buildInputs ++ [ buildInputs = old.buildInputs ++ [
pkgs.gfortran pkgs.gfortran
@ -602,22 +743,26 @@ self: super:
} }
); );
shapely = super.shapely.overridePythonAttrs ( shapely = super.shapely.overridePythonAttrs
(
old: { old: {
buildInputs = old.buildInputs ++ [ pkgs.geos self.cython ]; buildInputs = old.buildInputs ++ [ pkgs.geos self.cython ];
inherit (pkgs.python3.pkgs.shapely) patches GEOS_LIBRARY_PATH; inherit (pkgs.python3.pkgs.shapely) patches GEOS_LIBRARY_PATH;
} }
); );
shellingham = if lib.versionAtLeast super.shellingham.version "1.3.2" then ( shellingham =
super.shellingham.overridePythonAttrs ( if lib.versionAtLeast super.shellingham.version "1.3.2" then (
super.shellingham.overridePythonAttrs
(
old: { old: {
format = "pyproject"; format = "pyproject";
} }
) )
) else super.shellingham; ) else super.shellingham;
tables = super.tables.overridePythonAttrs ( tables = super.tables.overridePythonAttrs
(
old: { old: {
HDF5_DIR = "${pkgs.hdf5}"; HDF5_DIR = "${pkgs.hdf5}";
nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.pkgconfig ]; nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.pkgconfig ];
@ -625,7 +770,8 @@ self: super:
} }
); );
tensorpack = super.tensorpack.overridePythonAttrs ( tensorpack = super.tensorpack.overridePythonAttrs
(
old: { old: {
postPatch = '' postPatch = ''
substituteInPlace setup.cfg --replace "# will call find_packages()" "" substituteInPlace setup.cfg --replace "# will call find_packages()" ""
@ -633,7 +779,8 @@ self: super:
} }
); );
urwidtrees = super.urwidtrees.overridePythonAttrs ( urwidtrees = super.urwidtrees.overridePythonAttrs
(
old: { old: {
propagatedBuildInputs = old.propagatedBuildInputs ++ [ propagatedBuildInputs = old.propagatedBuildInputs ++ [
self.urwid self.urwid
@ -641,7 +788,8 @@ self: super:
} }
); );
vose-alias-method = super.vose-alias-method.overridePythonAttrs ( vose-alias-method = super.vose-alias-method.overridePythonAttrs
(
old: { old: {
postInstall = '' postInstall = ''
rm -f $out/LICENSE rm -f $out/LICENSE
@ -649,7 +797,8 @@ self: super:
} }
); );
uvloop = super.uvloop.overridePythonAttrs ( uvloop = super.uvloop.overridePythonAttrs
(
old: { old: {
buildInputs = old.buildInputs ++ lib.optionals stdenv.isDarwin [ buildInputs = old.buildInputs ++ lib.optionals stdenv.isDarwin [
pkgs.darwin.apple_sdk.frameworks.ApplicationServices pkgs.darwin.apple_sdk.frameworks.ApplicationServices
@ -663,8 +812,10 @@ self: super:
pkgs.python3.pkgs.override { pkgs.python3.pkgs.override {
python = self.python; python = self.python;
} }
).wheel.overridePythonAttrs ( ).wheel.overridePythonAttrs
_: { (
old:
if old.format == "other" then old else {
inherit (super.wheel) pname name version src; inherit (super.wheel) pname name version src;
} }
); );
@ -672,7 +823,8 @@ self: super:
zipp = zipp =
( (
if lib.versionAtLeast super.zipp.version "2.0.0" then ( if lib.versionAtLeast super.zipp.version "2.0.0" then (
super.zipp.overridePythonAttrs ( super.zipp.overridePythonAttrs
(
old: { old: {
prePatch = '' prePatch = ''
substituteInPlace setup.py --replace \ substituteInPlace setup.py --replace \
@ -682,7 +834,8 @@ self: super:
} }
) )
) else super.zipp ) else super.zipp
).overridePythonAttrs ( ).overridePythonAttrs
(
old: { old: {
propagatedBuildInputs = old.propagatedBuildInputs ++ [ propagatedBuildInputs = old.propagatedBuildInputs ++ [
self.toml self.toml

View File

@ -13,7 +13,6 @@ let
minor = builtins.elemAt ver 1; minor = builtins.elemAt ver 1;
in in
"cp${major}${minor}"; "cp${major}${minor}";
abiTag = "${pythonTag}m"; abiTag = "${pythonTag}m";
# #
@ -43,7 +42,7 @@ let
vs = lib.lists.tail versions; vs = lib.lists.tail versions;
in in
if (builtins.length versions == 0) if (builtins.length versions == 0)
then [] then [ ]
else (builtins.filter (x: hasInfix v x.file) candidates) ++ (findBestMatches vs candidates); else (builtins.filter (x: hasInfix v x.file) candidates) ++ (findBestMatches vs candidates);
# pyver = "cpXX" # pyver = "cpXX"
@ -61,12 +60,10 @@ let
selectWheel = files: selectWheel = files:
let let
filesWithoutSources = (builtins.filter (x: hasSuffix ".whl" x.file) files); filesWithoutSources = (builtins.filter (x: hasSuffix ".whl" x.file) files);
isPyAbiCompatible = pyabi: x: x == "none" || pyabi == x; isPyAbiCompatible = pyabi: x: x == "none" || pyabi == x;
withPython = ver: abi: x: (isPyVersionCompatible ver x.pyVer) && (isPyAbiCompatible abi x.abi); withPython = ver: abi: x: (isPyVersionCompatible ver x.pyVer) && (isPyAbiCompatible abi x.abi);
withPlatform =
withPlatform = if isLinux if isLinux
then ( then (
x: x.platform == "manylinux1_${stdenv.platform.kernelArch}" x: x.platform == "manylinux1_${stdenv.platform.kernelArch}"
|| x.platform == "manylinux2010_${stdenv.platform.kernelArch}" || x.platform == "manylinux2010_${stdenv.platform.kernelArch}"
@ -74,28 +71,25 @@ let
|| x.platform == "any" || x.platform == "any"
) )
else (x: hasInfix "macosx" x.platform || x.platform == "any"); else (x: hasInfix "macosx" x.platform || x.platform == "any");
filterWheel = x: filterWheel = x:
let let
f = toWheelAttrs x.file; f = toWheelAttrs x.file;
in in
(withPython pythonTag abiTag f) && (withPlatform f); (withPython pythonTag abiTag f) && (withPlatform f);
filtered = builtins.filter filterWheel filesWithoutSources; filtered = builtins.filter filterWheel filesWithoutSources;
choose = files: choose = files:
let let
osxMatches = [ "10_12" "10_11" "10_10" "10_9" "any" ]; osxMatches = [ "10_12" "10_11" "10_10" "10_9" "any" ];
linuxMatches = [ "manylinux1_" "manylinux2010_" "manylinux2014_" "any" ]; linuxMatches = [ "manylinux1_" "manylinux2010_" "manylinux2014_" "any" ];
chooseLinux = x: lib.singleton (builtins.head (findBestMatches linuxMatches x)); chooseLinux = x: lib.take 1 (findBestMatches linuxMatches x);
chooseOSX = x: lib.singleton (builtins.head (findBestMatches osxMatches x)); chooseOSX = x: lib.take 1 (findBestMatches osxMatches x);
in in
if isLinux if isLinux
then chooseLinux files then chooseLinux files
else chooseOSX files; else chooseOSX files;
in in
if (builtins.length filtered == 0) if (builtins.length filtered == 0)
then [] then [ ]
else choose (filtered); else choose (filtered);
in in
{ {

View File

@ -7,7 +7,6 @@ let
# Strip leading/trailing whitespace from string # Strip leading/trailing whitespace from string
stripStr = s: lib.elemAt (builtins.split "^ *" (lib.elemAt (builtins.split " *$" s) 0)) 2; stripStr = s: lib.elemAt (builtins.split "^ *" (lib.elemAt (builtins.split " *$" s) 0)) 2;
findSubExpressionsFun = acc: c: ( findSubExpressionsFun = acc: c: (
if c == "(" then ( if c == "(" then (
let let
@ -39,7 +38,7 @@ let
findSubExpressions = expr: findSubExpressions = expr:
let let
acc = builtins.foldl' findSubExpressionsFun { acc = builtins.foldl' findSubExpressionsFun {
exprs = []; exprs = [ ];
expr = expr; expr = expr;
pos = 0; pos = 0;
openP = 0; openP = 0;
@ -47,18 +46,16 @@ let
startPos = 0; startPos = 0;
} (lib.stringToCharacters expr); } (lib.stringToCharacters expr);
tailExpr = (substr acc.exprPos acc.pos expr); tailExpr = (substr acc.exprPos acc.pos expr);
tailExprs = if tailExpr != "" then [ tailExpr ] else []; tailExprs = if tailExpr != "" then [ tailExpr ] else [ ];
in in
acc.exprs ++ tailExprs; acc.exprs ++ tailExprs;
parseExpressions = exprs: parseExpressions = exprs:
let let
splitCond = ( splitCond = (
s: builtins.map s: builtins.map
(x: stripStr (if builtins.typeOf x == "list" then (builtins.elemAt x 0) else x)) (x: stripStr ( if builtins.typeOf x == "list" then (builtins.elemAt x 0) else x))
(builtins.split " (and|or) " (s + " ")) (builtins.split " (and|or) " (s + " "))
); );
mapfn = expr: ( mapfn = expr: (
if (builtins.match "^ ?$" expr != null) then null # Filter empty if (builtins.match "^ ?$" expr != null) then null # Filter empty
else if (builtins.elem expr [ "and" "or" ]) then { else if (builtins.elem expr [ "and" "or" ]) then {
@ -70,14 +67,12 @@ let
value = expr; value = expr;
} }
); );
parse = expr: builtins.filter (x: x != null) (builtins.map mapfn (splitCond expr)); parse = expr: builtins.filter (x: x != null) (builtins.map mapfn (splitCond expr));
in in
builtins.foldl' ( builtins.foldl'
acc: v: acc ++ ( (
if builtins.typeOf v == "string" then parse v else [ (parseExpressions v) ] acc: v: acc ++ ( if builtins.typeOf v == "string" then parse v else [ (parseExpressions v) ])
) ) [ ] exprs;
) [] exprs;
# Transform individual expressions to structured expressions # Transform individual expressions to structured expressions
# This function also performs variable substitution, replacing environment markers with their explicit values # This function also performs variable substitution, replacing environment markers with their explicit values
@ -94,7 +89,8 @@ let
else throw "Unsupported platform" else throw "Unsupported platform"
); );
platform_machine = stdenv.platform.kernelArch; platform_machine = stdenv.platform.kernelArch;
platform_python_implementation = let platform_python_implementation =
let
impl = python.passthru.implementation; impl = python.passthru.implementation;
in in
( (
@ -115,9 +111,7 @@ let
implementation_version = python.version; implementation_version = python.version;
extra = ""; extra = "";
}; };
substituteVar = value: if builtins.hasAttr value variables then (builtins.toJSON variables."${value}") else value; substituteVar = value: if builtins.hasAttr value variables then (builtins.toJSON variables."${value}") else value;
processVar = value: builtins.foldl' (acc: v: v acc) value [ processVar = value: builtins.foldl' (acc: v: v acc) value [
stripStr stripStr
substituteVar substituteVar
@ -165,7 +159,8 @@ let
let let
parts = builtins.splitVersion c; parts = builtins.splitVersion c;
pruned = lib.take ((builtins.length parts) - 1) parts; pruned = lib.take ((builtins.length parts) - 1) parts;
upper = builtins.toString ( upper = builtins.toString
(
(lib.toInt (builtins.elemAt pruned (builtins.length pruned - 1))) + 1 (lib.toInt (builtins.elemAt pruned (builtins.length pruned - 1))) + 1
); );
upperConstraint = builtins.concatStringsSep "." (ireplace (builtins.length pruned - 1) upper pruned); upperConstraint = builtins.concatStringsSep "." (ireplace (builtins.length pruned - 1) upper pruned);

View File

@ -1,8 +1,8 @@
{ lib, ireplace }: { lib, ireplace }:
let let
inherit (builtins) elemAt match; inherit (builtins) elemAt match;
operators =
operators = let let
matchWildCard = s: match "([^\*])(\.[\*])" s; matchWildCard = s: match "([^\*])(\.[\*])" s;
mkComparison = ret: version: v: builtins.compareVersions version v == ret; mkComparison = ret: version: v: builtins.compareVersions version v == ret;
mkIdxComparison = idx: version: v: mkIdxComparison = idx: version: v:
@ -39,7 +39,8 @@ let
# Prune constraint # Prune constraint
parts = builtins.splitVersion c; parts = builtins.splitVersion c;
pruned = lib.take ((builtins.length parts) - 1) parts; pruned = lib.take ((builtins.length parts) - 1) parts;
upper = builtins.toString ( upper = builtins.toString
(
(lib.toInt (builtins.elemAt pruned (builtins.length pruned - 1))) + 1 (lib.toInt (builtins.elemAt pruned (builtins.length pruned - 1))) + 1
); );
upperConstraint = builtins.concatStringsSep "." (ireplace (builtins.length pruned - 1) upper pruned); upperConstraint = builtins.concatStringsSep "." (ireplace (builtins.length pruned - 1) upper pruned);
@ -51,12 +52,10 @@ let
"===" = v: c: v == c; "===" = v: c: v == c;
# #
}; };
re = { re = {
operators = "([=><!~\^]+)"; operators = "([=><!~\^]+)";
version = "([0-9\.\*x]+)"; version = "([0-9\.\*x]+)";
}; };
parseConstraint = constraint: parseConstraint = constraint:
let let
constraintStr = builtins.replaceStrings [ " " ] [ "" ] constraint; constraintStr = builtins.replaceStrings [ " " ] [ "" ] constraint;
@ -80,11 +79,9 @@ let
} }
else throw "Constraint \"${constraintStr}\" could not be parsed" else throw "Constraint \"${constraintStr}\" could not be parsed"
); );
satisfiesSemver = version: constraint: satisfiesSemver = version: constraint:
let let
inherit (parseConstraint constraint) op v; inherit (parseConstraint constraint) op v;
in in if constraint == "*" then true else operators."${op}" version v;
if constraint == "*" then true else operators."${op}" version v;
in in
{ inherit satisfiesSemver; } { inherit satisfiesSemver; }

View File

@ -14,7 +14,7 @@ curl -L -s https://github.com/nix-community/poetry2nix/archive/master.tar.gz | t
mv poetry2nix-master/* . mv poetry2nix-master/* .
mkdir build mkdir build
cp *.nix *.json *.py build/ cp *.* build/
cp -r hooks bin build/ cp -r hooks bin build/
rm build/shell.nix build/generate.py build/overlay.nix build/flake.nix rm build/shell.nix build/generate.py build/overlay.nix build/flake.nix