How to add custom python package?

I want to add a custom python package to my system and it would be nice to be able to switch between python versions like python35Packages.x.

Using overlays is probably the right way, so i tried this in my configuration.nix:

  nixpkgs.overlays = [
  (self: super:
  {
    gvm-tools = super.callPackage ../../packages/gvm-tools { };
  }
  )];

and this to install the package on the system:

  environment.systemPackages = with pkgs; [ python35Packages.gvm-tools ];

It don’t work and i get crazy error messages!

default.nix
nixos-rebuild switch --show-trace

2 Likes

attribute 'gvm-tools' missing is the key thing.

Your overlay adds gvm-tools as a top level package. You need to do something like

python35Packages = {
  gvm-tools = super.callPackage #...
};

I think Nix will merge the sets in the overlays.

Even better, if it’s appropriate, would be to add your package to nixpkgs and use the instructions in Nixpkgs 23.11 manual | Nix & NixOS to build and install locally until the PR is merged.

Thanks for your help!

It seems not to merge. Now every other python35Packages are missing.

  environment.systemPackages = with pkgs; [
    python35Packages.youtube-dl
  ];

attribute ‘youtube-dl’ missing, at /root/nixos-config/profiles/desktop.nix:39:5

nixpkgs does some kind of magic with the python packages, so they are available as python35Packages or pypyPackages. It would be great to have that also with the overlay. It probably would get very complex.

The manual says:

Based on the packages defined in pkgs/top-level/python-packages.nix an attribute set is created for each available Python interpreter.

It would be easier to just add it to nixpkgs, but that’s not possible at this point in time. It’s not even on PyPI yet.

Unfortunately, it’s a bit complicated.
Here’s a full example that shows how to extend pythonPackages with a custom package for various python versions.

nix-build --no-out-link - <<'EOF'
let
  overlay = (self: super:
    let
      myOverride = {
        packageOverrides = self: super: {
          inotify_simple = super.buildPythonPackage rec {
            pname = "inotify_simple";
            version = "1.1.7";
            doCheck = false;
            src = super.fetchPypi {
              inherit pname version;
              sha256 = "1jvivp84cyp4x4rsw4g6bzbzqka7gaqhk4k4jqifyxnqqmbdgvcq";
            };
          };
        };
      };
    in {
      # Add an override for each required python version. 
      # There’s currently no way to add a package that’s automatically picked up by 
      # all python versions, besides editing python-packages.nix
      python2 = super.python2.override myOverride;
      python3 = super.python3.override myOverride;
      python35 = super.python35.override myOverride;
    }
  );

  pkgs = import <nixpkgs> { overlays = [ overlay ]; };
in
  with pkgs; [
    pythonPackages.inotify_simple
    python3Packages.inotify_simple
    python35Packages.inotify_simple
  ]
EOF
2 Likes

There is an example for exactly this in the Nixpkgs manual. Note, though, that the rec should be removed and self.python.pkgs be used instead.

1 Like

Edit: Ah, got it now, you mean 9.11.3.8. This has been fixed upstream.

But the line pythonPackages = self.python.pkgs; is not needed at all, see my example.
I’ll file a PR.