Nix: Over-riding Python Derivation Tests

As a result of using a Mac, I sometimes find that certain nix derivations don’t build successfully. Almost always this is because of failing tests of obscure corner cases due to some quirk of the operating system, compared to Linux. In every case so far, the package has turned out to be perfectly functional.

This has proven most frustrating with python packages, that often break for some unknown reason. Finding and fixing the specific test and then submitting a pull request on Github is very time consuming requiring masterful nix knowledge, and even then, it takes a while for changes to the nixpkgs tree to propagate through to the unstable channel.

Whilst nixpkgs is a collaborative, open source project and people should try and submit pull requests when they can; for quick local fixes, it would be easier to override the python package completely. This is non-trivial as a combination of the nix language, whose documentation can be a bit thin on the ground, and the python packages structure, which is also documented in a rather obtuse fashion, serve to frustrate the user.

Me and my PhD supervisor, Bojan Nikolic, (he made the breakthrough) came up with a fairly elegant way to fudge the tests in the python packages tree. This means that perfectly functional python packages are still able to build by skipping the tests, and allowing nix to work uninterrupted. An example of this override is shown below.

with import <nixpkgs> {};

with pkgs.python36Packages;

{ allowBroken = true; allowUnfree = true;

ignoreCollisions = true;

doCheck = false;

packageOverrides = pkgs: rec {

python36Packages = pkgs.python36Packages.override (oldAttrs: { overrides = self: super: {

simplejson = super.simplejson.overrideAttrs ( z : rec { doCheck=false; doInstallCheck = false; } );

pandas = super.pandas.overrideAttrs( z : rec{ doCheck=false; doInstallCheck = false; } );

scikitlearn = super.scikitlearn.overrideAttrs( z: rec{ doCheck=false; doInstallCheck = false; } ); } ; } ) ;

myPythonEnv = python36.buildEnv.override { extraLibs = with python36Packages; [ astropy cython ipython matplotlib numba numpy pandas scipy scikitimage scikitlearn sympy ]; ignoreCollisions = true; }; }; }

An example of this integrated into my working config.nix is in my workflow github repo: https://github.com/KentJames/workflow. Thanks to Bojan for hacking away at nix when I had lost all hope. He has also written about it on his blog here:

http://www.bnikolic.co.uk/nix-cheatsheet.html