license = lib.licenses.bsd2;
};
}
```
We can see several runtime dependencies, `numpy`, `multipledispatch`, and
`python-dateutil`. Furthermore, we have [`nativeCheckInputs`](#var-stdenv-nativeCheckInputs) with `pytestCheckHook`.
`pytestCheckHook` is a test runner hook and is only used during the [`checkPhase`](#ssec-check-phase) and is
therefore not added to `dependencies`.
In the previous case we had only dependencies on other Python packages to consider.
Occasionally you have also system libraries to consider. E.g., `lxml` provides
Python bindings to `libxml2` and `libxslt`. These libraries are only required
when building the bindings and are therefore added as [`buildInputs`](#var-stdenv-buildInputs).
```nix
{
lib,
buildPythonPackage,
fetchPypi,
setuptools,
libxml2,
libxslt,
}:
buildPythonPackage rec {
pname = "lxml";
version = "3.4.4";
pyproject = true;
src = fetchPypi {
inherit pname version;
hash = "sha256-s9NiusRxFydHzaNRMjjxFcvWxfi45jGb9ql6eJJyQJk=";
};
build-system = [
setuptools
];
buildInputs = [
libxml2
libxslt
];
# tests are meant to be ran "in-place" in the same directory as src
doCheck = false;
pythonImportsCheck = [
"lxml"
"lxml.etree"
];
meta = {
changelog = "https://github.com/lxml/lxml/releases/tag/lxml-${version}";
description = "Pythonic binding for the libxml2 and libxslt libraries";
homepage = "https://lxml.de";
license = lib.licenses.bsd3;
maintainers = with lib.maintainers; [ sjourdois ];
};
}
```
In this example `lxml` and Nix are able to work out exactly where the relevant
files of the dependencies are. This is not always the case.
The example below shows bindings to The Fastest Fourier Transform in the West,
commonly known as FFTW. On Nix we have separate packages of FFTW for the
different types of floats (`"single"`, `"double"`, `"long-double"`). The
bindings need all three types, and therefore we add all three as [`buildInputs`](#var-stdenv-buildInputs).
The bindings don't expect to find each of them in a different folder, and
therefore we have to set `LDFLAGS` and `CFLAGS`.
```nix
{
lib,
buildPythonPackage,
fetchPypi,
# build dependencies
setuptools,
# dependencies
fftw,
fftwFloat,
fftwLongDouble,
numpy,
scipy,
}:
buildPythonPackage rec {
pname = "pyfftw";
version = "0.9.2";
pyproject = true;
src = fetchPypi {
inherit pname version;
hash = "sha256-9ru2r6kwhUCaskiFoaPNuJCfCVoUL01J40byvRt4kHQ=";
};
build-system = [
setuptools
];
buildInputs = [
fftw
fftwFloat
fftwLongDouble
];
dependencies = [
numpy
scipy
];
preConfigure = ''
export LDFLAGS="-L${fftw.dev}/lib -L${fftwFloat.out}/lib -L${fftwLongDouble.out}/lib"
export CFLAGS="-I${fftw.dev}/include -I${fftwFloat.dev}/include -I${fftwLongDouble.dev}/include"
'';
# Tests cannot import pyfftw. pyfftw works fine though.
doCheck = false;
pythonImportsCheck = [ "pyfftw" ];
meta = {
changelog = "https://github.com/pyFFTW/pyFFTW/releases/tag/v${version}";
description = "Pythonic wrapper around FFTW, the FFT library, presenting a unified interface for all the supported transforms";
homepage = "http://hgomersall.github.com/pyFFTW";
license = with lib.licenses; [
bsd2
bsd3
];
};
}
```
Note also the line [`doCheck = false;`](#var-stdenv-doCheck), we explicitly disabled running the test-suite.
#### Testing Python Packages {#testing-python-packages}
It is highly encouraged to have testing as part of the package build. This
helps to avoid situations where the package was able to build and install,
but is not usable at runtime.
Your package should provide its own [`checkPhase`](#ssec-check-phase).
::: {.note}
The [`checkPhase`](#ssec-check-phase) for python maps to the `installCheckPhase` on a
normal derivation. This is due to many python packages not behaving well
to the pre-installed version of the package. Version info, and natively