This is particularly useful for numpy and scipy users who want to gain speed with other blas implementations.
Note that using `scipy = super.scipy.override { blas = super.pkgs.mkl; };` will likely result in
compilation issues, because scipy dependencies need to use the same blas implementation as well.
#### `buildPythonApplication` function {#buildpythonapplication-function}
The [`buildPythonApplication`](#buildpythonapplication-function) function is practically the same as
[`buildPythonPackage`](#buildpythonpackage-function). The main purpose of this function is to build a Python
package where one is interested only in the executables, and not importable
modules. For that reason, when adding this package to a [`python.buildEnv`](#python.buildenv-function), the
modules won't be made available.
Another difference is that [`buildPythonPackage`](#buildpythonpackage-function) by default prefixes the names of
the packages with the version of the interpreter. Because this is irrelevant for
applications, the prefix is omitted.
When packaging a Python application with [`buildPythonApplication`](#buildpythonapplication-function), it should be
called with `callPackage` and passed `python3` or `python3Packages` (possibly
specifying an interpreter version), like this:
```nix
{
lib,
python3Packages,
fetchPypi,
}:
python3Packages.buildPythonApplication rec {
pname = "luigi";
version = "2.7.9";
pyproject = true;
src = fetchPypi {
inherit pname version;
hash = "sha256-Pe229rT0aHwA98s+nTHQMEFKZPo/yw6sot8MivFDvAw=";
};
build-system = with python3Packages; [
setuptools
];
dependencies = with python3Packages; [
tornado
python-daemon
];
meta = {
# ...
};
}
```
This is then added to `pkgs/by-name` just as any other application would be.
Since the package is an application, a consumer doesn't need to care about
Python versions or modules, which is why they don't go in `python3Packages`.
#### `toPythonApplication` function {#topythonapplication-function}
A distinction is made between applications and libraries, however, sometimes a
package is used as both. In this case the package is added as a library to
`python-packages.nix` and as an application to `pkgs/by-name`. To reduce
duplication the `toPythonApplication` can be used to convert a library to an
application.
The Nix expression shall use [`buildPythonPackage`](#buildpythonpackage-function) and be called from
`python-packages.nix`. A reference shall be created from `pkgs/by-name` to
the attribute in `python-packages.nix`, and the `toPythonApplication` shall be
applied to the reference:
```nix
{
python3Packages,
}:
python3Packages.toPythonApplication python3Packages.youtube-dl
```
#### `toPythonModule` function {#topythonmodule-function}
In some cases, such as bindings, a package is created using
[`stdenv.mkDerivation`](#sec-using-stdenv) and added as attribute in `pkgs/by-name` or in `all-packages.nix`. The Python
bindings should be made available from `python-packages.nix`. The
`toPythonModule` function takes a derivation and makes certain Python-specific
modifications.
```nix
{
opencv = toPythonModule (
pkgs.opencv.override {
enablePython = true;
pythonPackages = self;
}
);
}
```
Do pay attention to passing in the right Python version!
#### `mkPythonMetaPackage` function {#mkpythonmetapackage-function}
This will create a meta package containing [metadata files](https://packaging.python.org/en/latest/specifications/recording-installed-packages/) to satisfy a dependency on a package, without it actually having been installed into the environment.
In nixpkgs this is used to package Python packages with split binary/source distributions such as [psycopg2](https://pypi.org/project/psycopg2/)/[psycopg2-binary](https://pypi.org/project/psycopg2-binary/).
```nix
mkPythonMetaPackage {
pname = "psycopg2-binary";
inherit (psycopg2) optional-dependencies version;
dependencies = [ psycopg2 ];
meta = {