3faddeaaa9
Fixes some trivial typos, mostly in comments, except for in `mach_nix/resolver/__init__.py`, the scope is a context manager, so there shouldn't be arbitrary sideffects by the rename.
171 lines
7 KiB
Nix
171 lines
7 KiB
Nix
{ condaChannelsExtra, condaDataRev, condaDataSha256, pkgs, pypiData, ... }:
|
|
|
|
with builtins;
|
|
with pkgs.lib;
|
|
let
|
|
l = import ./lib.nix { inherit (pkgs) lib; inherit pkgs; };
|
|
|
|
buildPythonPackageBase = (import ./buildPythonPackage.nix {
|
|
inherit condaChannelsExtra condaDataRev condaDataSha256 pkgs pypiData;
|
|
});
|
|
|
|
mkPython = pythonGlobal:
|
|
{
|
|
cudaVersion ? pkgs.cudatoolkit.version, # max allowed cuda version for conda packages
|
|
ignoreCollisions ? false, # ignore collisions on the environment level.
|
|
ignoreDataOutdated ? false, # don't fail if pypi data is older than nixpkgs
|
|
overridesPre ? [], # list of pythonOverrides to apply before the machnix overrides
|
|
overridesPost ? [], # list of pythonOverrides to apply after the machnix overrides
|
|
packagesExtra ? [], # add R-Packages, pkgs from nixpkgs, pkgs built via mach-nix.buildPythonPackage
|
|
providers ? {}, # define provider preferences
|
|
python ? pythonGlobal, # define python version
|
|
requirements ? "", # content from a requirements.txt file
|
|
tests ? false, # Disable tests wherever possible to decrease build time.
|
|
_ ? {}, # simplified overrides
|
|
_providerDefaults ? l.makeProviderDefaults requirements,
|
|
_fixes ? import ../fixes.nix {pkgs = pkgs;},
|
|
postBuild ? "", # Commands to run after building environment
|
|
}:
|
|
let
|
|
python_pkg = l.selectPythonPkg pkgs python requirements;
|
|
pyver = l.get_py_ver python_pkg;
|
|
# and separate pkgs into groups
|
|
extra_pkgs_python = map (p:
|
|
# check if element is a package built via mach-nix
|
|
if p ? pythomModule && ! p ? passthru._ then
|
|
throw ''
|
|
python packages from nixpkgs cannot be passed via `packagesExtra`.
|
|
Instead, add the package's name to your `requirements` and set `providers.{package} = "nixpkgs"`
|
|
''
|
|
else if p ? passthru._ then
|
|
let
|
|
pkg_pyver = l.get_py_ver p.pythonModule;
|
|
in
|
|
if pkg_pyver != pyver then
|
|
throw ''
|
|
${p.pname} from 'packagesExtra' is built with python ${p.pythonModule.version},
|
|
but the environment is based on python ${pyver.major}.${pyver.minor}.
|
|
Please build ${p.pname} with 'python = "python${pyver.major}${pyver.minor}"'.
|
|
''
|
|
else
|
|
p
|
|
# translate sources to python packages
|
|
else
|
|
buildPythonPackageBase python "buildPythonPackage" {
|
|
inherit condaDataRev condaDataSha256 pkgs providers python
|
|
pypiData tests _providerDefaults;
|
|
src = p;
|
|
}
|
|
) (filter (p: l.is_src p || p ? pythonModule) packagesExtra);
|
|
extra_pkgs_r = filter (p: p ? rCommand) packagesExtra;
|
|
extra_pkgs_other = filter (p: ! (p ? rCommand || p ? pythonModule || l.is_src p)) packagesExtra;
|
|
|
|
# gather requirements of extra pkgs
|
|
extra_pkgs_py_reqs =
|
|
map (p:
|
|
if hasAttr "requirements" p then p.pname
|
|
else throw "Packages passed via 'packagesExtra' must be built via mach-nix.buildPythonPackage"
|
|
) extra_pkgs_python;
|
|
extra_pkgs_r_reqs = if extra_pkgs_r == [] then "" else ''
|
|
rpy2
|
|
ipython
|
|
jinja2
|
|
pytz
|
|
pandas
|
|
numpy
|
|
cffi
|
|
tzlocal
|
|
simplegeneric
|
|
'';
|
|
|
|
# gather overrides necessary by extra_pkgs
|
|
extra_pkgs_python_attrs = foldl' (a: b: a // b) {} (map (p: { "${p.pname}" = p; }) extra_pkgs_python);
|
|
extra_pkgs_py_overrides = [ (pySelf: pySuper: extra_pkgs_python_attrs) ];
|
|
extra_pkgs_r_overrides = l.simple_overrides {
|
|
rpy2.buildInputs.add = extra_pkgs_r;
|
|
};
|
|
overrides_simple_extra = flatten (
|
|
(map l.simple_overrides (
|
|
map (p: if hasAttr "_" p then p._ else {}) extra_pkgs_python
|
|
))
|
|
);
|
|
overrides_pre_extra = flatten (map (p: p.passthru.overridesPre) extra_pkgs_python);
|
|
overrides_post_extra = flatten (map (p: p.passthru.overridesPost) extra_pkgs_python);
|
|
extra_pkgs_providers = builtins.mapAttrs (n: p: "nixpkgs") extra_pkgs_python_attrs;
|
|
|
|
py = python_pkg.override { packageOverrides = l.mergeOverrides overridesPre; };
|
|
result = l.compileOverrides {
|
|
inherit condaChannelsExtra condaDataRev condaDataSha256 pkgs pypiData tests _providerDefaults;
|
|
overrides = overridesPre ++ overrides_pre_extra ++ extra_pkgs_py_overrides;
|
|
providers = providers // extra_pkgs_providers;
|
|
python = py;
|
|
requirements = l.concat_reqs ([requirements] ++ extra_pkgs_py_reqs ++ [extra_pkgs_r_reqs]);
|
|
};
|
|
selectPkgs = ps:
|
|
(result.select_pkgs ps);
|
|
|
|
override_selectPkgs = pySelf: pySuper: {
|
|
inherit selectPkgs;
|
|
};
|
|
|
|
all_overrides = l.mergeOverrides (
|
|
overridesPre ++ overrides_pre_extra
|
|
++ extra_pkgs_py_overrides
|
|
++ [ result.overrides ]
|
|
++ (l.fixes_to_overrides _fixes)
|
|
++ overrides_post_extra ++ overridesPost
|
|
++ extra_pkgs_r_overrides
|
|
++ overrides_simple_extra ++ (l.simple_overrides _)
|
|
++ [ override_selectPkgs ]
|
|
);
|
|
py_final = python_pkg.override { packageOverrides = all_overrides;};
|
|
py_final_with_pkgs = (py_final.withPackages (ps: selectPkgs ps)).overrideAttrs (oa:{
|
|
postBuild = ''
|
|
${l.condaSymlinkJoin (flatten (map (p: p.allCondaDeps or []) (selectPkgs py_final.pkgs))) }
|
|
'' + oa.postBuild + postBuild;
|
|
});
|
|
final_env = py_final_with_pkgs.override (oa: {
|
|
inherit ignoreCollisions;
|
|
makeWrapperArgs =
|
|
(map (p: "--suffix PATH : ${p}/bin") extra_pkgs_other)
|
|
++ [''--set QT_PLUGIN_PATH ${py_final_with_pkgs}/plugins''];
|
|
});
|
|
in let
|
|
self = final_env.overrideAttrs (oa: {
|
|
passthru = oa.passthru // rec {
|
|
inherit selectPkgs;
|
|
expr = result.expr;
|
|
pythonOverrides = all_overrides;
|
|
python = py_final;
|
|
overlay = self: super:
|
|
let
|
|
py_attr_name = "python${pyver.major}${pyver.minor}";
|
|
in
|
|
{
|
|
"${py_attr_name}" = super."${py_attr_name}".override {
|
|
packageOverrides = pythonOverrides;
|
|
};
|
|
};
|
|
nixpkgs = import pkgs.path { config = pkgs.config; overlays = pkgs.overlays ++ [ overlay ]; };
|
|
dockerImage = makeOverridable
|
|
(args: pkgs.dockerTools.buildLayeredImage args)
|
|
{
|
|
name = "mach-nix-python";
|
|
tag = "latest";
|
|
contents = [
|
|
self
|
|
] ++ extra_pkgs_other
|
|
++ pkgs.lib.optional (pkgs.stdenv.isLinux) pkgs.busybox
|
|
# Even though the docker container is always linux, the nix
|
|
# closure is built locally and busybox won't evaluate on macOS
|
|
++ pkgs.lib.optionals (pkgs.stdenv.isDarwin) [ pkgs.coreutils ];
|
|
config = {
|
|
Cmd = [ "${self}/bin/python" ];
|
|
};
|
|
};
|
|
};
|
|
});
|
|
in self;
|
|
in
|
|
|
|
python: args: mkPython python (l.translateDeprecatedArgs args)
|