user3416536
user3416536

Reputation: 1469

How to globally override a pythonPackage in nix

I'm trying to override a python package (uvloop) globally, in nix, such that black sees the override.

uvloop (python package) tests fail for me because I'm working behind a firewall. I can build things that use uvloop by editing the nixpkgs derivation directly (ugh) to set doCheck = false.

I'm trying to encode this in an overlay, but without success - the overlay is read (e.g., syntax errors cause failure), but nothing I do in the overlay actually stop the tests from running.

I've tried following tips from https://nixos.wiki/wiki/Overlays, https://nixos.org/manual/nixpkgs/stable/#how-to-override-a-python-package-using-overlays and How to use custom python with existing packages - nix derivation? (overlaying python using packageOverrides; with pythonOverrides; and with and without using overridePythonAttrs); both for python3 and python39; but with no success.

E.g.,

self: super: {
  python3 = super.python3.override {
    packageOverrides = pyself: pysuper: {
      uvloop = pysuper.uvloop.overrideAttrs (_: {
        doCheck = false;
      });
    };
  };
}
    

For bonus points, I'd like to achieve this for all instances of python package uvloop - not just the one in 3.9 - but I'll take any help I can get.

Thanks,

Upvotes: 7

Views: 4353

Answers (2)

Isaac van Bakel
Isaac van Bakel

Reputation: 1862

Ran into the same issue with the same package. I wasn't able to source an answer from the Nix docs, but I think this is what's happening, and why your example doesn't work.

python3 is just an alias of python39, in the same way that python3Packages is an alias of python39Packages (see this doc page.) When overriding python3, you're overriding the value of python39, but the result is then stored back in the python3 variable instead of the alias - so other Nix code which goes directly through python39 instead of the python3 alias still sees the non-overridden package set.

A working way

The way that worked for me was to override the value of python39 specifically, and leave python3 as an alias pointing to the new overridden package set:

self: super: {
  python39 = super.python39.override {
    packageOverrides = pyself: pysuper: {
      uvloop = pysuper.uvloop.overrideAttrs (_: {
        doCheck = false;
      });
    };
  };
}

Upvotes: 2

strager
strager

Reputation: 90072

The following worked for me. It applies a patch to twitch-chat-downloader (Python app) and a patch to twitch-python (Python library used by twitch-chat-downloader). nix-env -iA nixpkgs.twitch-chat-downloader installed a patch copy of twitch-chat-downloader which uses a patched copy of twitch-python.

{
  packageOverrides = pkgs: {
    python3 = pkgs.python3.override {
      packageOverrides = python-self: python-super: {
        twitch-python = python-super.twitch-python.overrideAttrs (attrs: {
          patches = (attrs.patches or []) ++ [
            ./twitch-allow-no-token.patch
          ];
        });
      };
    };

    twitch-chat-downloader = pkgs.twitch-chat-downloader.overrideAttrs (attrs: {
      patches = (attrs.patches or []) ++ [
        ./twitch-chat-downloader-no-oauth.patch
      ];
    });
  };
}

Upvotes: 2

Related Questions