Home Explore Blog Models CI



nixpkgs

6th chunk of `doc/languages-frameworks/python.section.md`
d1fe7098765aff2a1a70d02d77419949e90c0adf245b2b380000000100000faa
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 = { inherit (psycopg2.meta) description homepage; };
}
```

#### `mkPythonEditablePackage` function {#mkpythoneditablepackage-function}

When developing Python packages it's common to install packages in [editable mode](https://setuptools.pypa.io/en/latest/userguide/development_mode.html).
Like `mkPythonMetaPackage` this function exists to create an otherwise empty package, but also containing a pointer to an impure location outside the Nix store that can be changed without rebuilding.

The editable root is passed as a string. Normally `.pth` files contains absolute paths to the mutable location. This isn't always ergonomic with Nix, so environment variables are expanded at runtime.
This means that a shell hook setting up something like a `$REPO_ROOT` variable can be used as the relative package root.

As an implementation detail, the [PEP-518](https://peps.python.org/pep-0518/) `build-system` specified won't be used, but instead the editable package will be built using [hatchling](https://pypi.org/project/hatchling/).
The `build-system`'s provided will instead become runtime dependencies of the editable package.

Note that overriding packages deeper in the dependency graph _can_ work, but it's not the primary use case and overriding existing packages can make others break in unexpected ways.

```nix
{
  pkgs ? import <nixpkgs> { },
}:

let
  pyproject = pkgs.lib.importTOML ./pyproject.toml;

  myPython = pkgs.python.override {
    self = myPython;
    packageOverrides = pyfinal: pyprev: {
      # An editable package with a script that loads our mutable location
      my-editable = pyfinal.mkPythonEditablePackage {
        # Inherit project metadata from pyproject.toml
        pname = pyproject.project.name;
        inherit (pyproject.project) version;

        # The editable root passed as a string
        root = "$REPO_ROOT/src"; # Use environment variable expansion at runtime

        # Inject a script (other PEP-621 entrypoints are also accepted)
        inherit (pyproject.project) scripts;
      };
    };
  };

  pythonEnv = myPython.withPackages (ps: [ ps.my-editable ]);

in
pkgs.mkShell { packages = [ pythonEnv ]; }
```

#### `python.buildEnv` function {#python.buildenv-function}

Python environments can be created using the low-level `pkgs.buildEnv` function.
This example shows how to create an environment that has the Pyramid Web Framework.
Saving the following as `default.nix`

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

python3.buildEnv.override {
  extraLibs = [ python3Packages.pyramid ];
  ignoreCollisions = true;
}
```

and running `nix-build` will create

```
/nix/store/cf1xhjwzmdki7fasgr4kz6di72ykicl5-python-2.7.8-env
```

with wrapped binaries in `bin/`.

You can also use the `env` attribute to create local environments with needed
packages installed. This is somewhat comparable to `virtualenv`. For example,
running `nix-shell` with the following `shell.nix`

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

(python3.buildEnv.override {
  extraLibs = with python3Packages; [
    numpy
    requests
  ];
}).env
```

will drop you into a shell where Python will have the
specified packages in its path.

##### `python.buildEnv` arguments {#python.buildenv-arguments}


* `extraLibs`: List of packages installed inside the environment.

Title: Nixpkgs Python Packaging: Meta, Editable Packages, and Build Environments
Summary
This chunk details several Nixpkgs functions for Python packaging. The `mkPythonMetaPackage` function creates a metadata-only package to fulfill dependencies, particularly useful for split binary/source distributions like `psycopg2-binary`. The `mkPythonEditablePackage` function facilitates Python development by creating an empty package that points to an impure, mutable location outside the Nix store, supporting environment variable expansion in the `root` path. Finally, `python.buildEnv` is described as a function for creating isolated Python environments, similar to `virtualenv`, allowing users to specify `extraLibs` to include desired packages for either `nix-build` or `nix-shell` environments.