Home Explore Blog CI



nixpkgs

15th chunk of `doc/languages-frameworks/python.section.md`
e2fc1ad1f737ed89be6ef1aa415251a5fee825ad1e1e0ffe0000000100000fb4
    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

Title: LXML, FFTW, and Testing in Python Packages
Summary
This section further illustrates how to handle dependencies in Nix packages, focusing on the `lxml` and `pyfftw` examples. It demonstrates the use of `buildInputs` for `lxml`'s dependencies on `libxml2` and `libxslt`. The `pyfftw` example shows how to use `buildInputs` for multiple versions of FFTW, and how to set `LDFLAGS` and `CFLAGS` to ensure the bindings can find the necessary files. It also explains how to disable tests using `doCheck = false;`. Finally, it emphasizes the importance of including testing in package builds and mentions that the `checkPhase` in Python packages maps to the `installCheckPhase` in normal derivations.