Home Explore Blog CI



nixpkgs

20th chunk of `doc/languages-frameworks/python.section.md`
fdbf85400b9d9a8943df97b8554aedce37db82afb96342180000000100000fad
We first create a function that builds `toolz` in `~/path/to/toolz/release.nix`

```nix
{
  lib,
  buildPythonPackage,
  fetchPypi,
  setuptools,
}:

buildPythonPackage rec {
  pname = "toolz";
  version = "0.10.0";
  pyproject = true;

  src = fetchPypi {
    inherit pname version;
    hash = "sha256-CP3V73yWSArRHBLUct4hrNMjWZlvaaUlkpm1QP66RWA=";
  };

  build-system = [
    setuptools
  ];

  meta = {
    changelog = "https://github.com/pytoolz/toolz/releases/tag/${version}";
    homepage = "https://github.com/pytoolz/toolz/";
    description = "List processing tools and functional utilities";
    license = lib.licenses.bsd3;
  };
}
```

It takes an argument [`buildPythonPackage`](#buildpythonpackage-function). We now call this function using
`callPackage` in the definition of our environment

```nix
with import <nixpkgs> { };

(
  let
    toolz = callPackage /path/to/toolz/release.nix {
      buildPythonPackage = python3Packages.buildPythonPackage;
    };
  in
  python3.withPackages (ps: [
    ps.numpy
    toolz
  ])
).env
```

Important to remember is that the Python version for which the package is made
depends on the `python` derivation that is passed to [`buildPythonPackage`](#buildpythonpackage-function). Nix
tries to automatically pass arguments when possible, which is why generally you
don't explicitly define which `python` derivation should be used. In the above
example we use [`buildPythonPackage`](#buildpythonpackage-function) that is part of the set `python3Packages`,
and in this case the `python3` interpreter is automatically used.

## FAQ {#faq}

### How to solve circular dependencies? {#how-to-solve-circular-dependencies}

Consider the packages `A` and `B` that depend on each other. When packaging `B`,
a solution is to override package `A` not to depend on `B` as an input. The same
should also be done when packaging `A`.

### How to override a Python package? {#how-to-override-a-python-package}

We can override the interpreter and pass `packageOverrides`. In the following
example we rename the `pandas` package and build it.

```nix
with import <nixpkgs> { };

(
  let
    python =
      let
        packageOverrides = self: super: {
          pandas = super.pandas.overridePythonAttrs (old: {
            name = "foo";
          });
        };
      in
      pkgs.python310.override {
        inherit packageOverrides;
      };

  in
  python.withPackages (ps: [
    ps.pandas
  ])
).env
```

Using `nix-build` on this expression will build an environment that contains the
package `pandas` but with the new name `foo`.

All packages in the package set will use the renamed package. A typical use case
is to switch to another version of a certain package. For example, in the
Nixpkgs repository we have multiple versions of `django` and `scipy`. In the
following example we use a different version of `scipy` and create an
environment that uses it. All packages in the Python package set will now use
the updated `scipy` version.

```nix
with import <nixpkgs> { };

(
  let
    packageOverrides = self: super: {
      scipy = super.scipy_0_17;
    };
  in
  (pkgs.python310.override {
    inherit packageOverrides;
  }).withPackages
    (ps: [
      ps.blaze
    ])
).env
```

The requested package `blaze` depends on `pandas` which itself depends on `scipy`.

If you want the whole of Nixpkgs to use your modifications, then you can use
`overlays` as explained in this manual. In the following example we build a
`inkscape` using a different version of `numpy`.

```nix
let
  pkgs = import <nixpkgs> { };
  newpkgs = import pkgs.path {
    overlays = [
      (self: super: {
        python310 =
          let
            packageOverrides = python-self: python-super: {
              numpy = python-super.numpy_1_18;
            };
          in
          super.python310.override { inherit packageOverrides; };
      })
    ];
  };
in
newpkgs.inkscape
```

### `python setup.py bdist_wheel` cannot create .whl {#python-setup.py-bdist_wheel-cannot-create-.whl}

Title: Using `callPackage` and Addressing FAQs
Summary
This section demonstrates how to use `callPackage` to build `toolz` and integrate it into a Python environment using Nix. It highlights the importance of the Python derivation passed to `buildPythonPackage` and provides solutions for common issues like circular dependencies and package overriding, including renaming packages and switching to different versions of packages like `scipy`. Additionally, it shows how to apply modifications globally using Nixpkgs overlays, such as building `inkscape` with a different version of `numpy`.