Understand python package overlay with flakes

Hi,
In my nixos flake, I pin the version of a python package (wagtail) to a specific nixpkgs commit with an overlay. My final version works, but I would like to understand why another one didn’t.

For reference, I mostly used : Downgrading or Upgrading Packages | NixOS & Flakes Book, How to override a Python package using callPackage from an overlay - #4 by APCodes, Overriding Python Modules.

The flake.nix:

{
  description = "A flake";
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/24.05";
    # Pinned nixpkgs with Wagtail 5.2.2.
    nixpkgs-6425843.url = "github:nixos/nixpkgs/6425843adacfa1f8a61f3e0fc3e903f333cc1f94";
    disko.url = "github:nix-community/disko";
  };

  outputs = { self, nixpkgs, disko, nixpkgs-6425843 }:
    let
      pkgs = import nixpkgs {
        system = "x86_64-linux";
      };
    in
    {
      nixosConfigurations."machine" = nixpkgs.lib.nixosSystem rec {
        system = "x86_64-linux";
        specialArgs = {
          nixpkgs-6425843 = import nixpkgs-6425843 { inherit system; };
        };
        modules = [
          disko.nixosModules.disko
          ./nixos/configuration.nix
        ];
      };
    };
}

The overlay that works uses callPackage on a raw copy of the wagtail package from the nixpkgs repo. It does not use the pinned nixpkgs flake input :

{ config, pkgs, nixpkgs-6425843, ... }:
{
  nixpkgs.overlays = [ 
    (final: prev: {
      pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [ (pyfinal: pyprev: {
        wagtail = pyfinal.callPackage ./wagtail-6425843.nix {};
      })];
    }) 
  ];
}

Attempt using the pinned nixpkgs input failed. The configuration builds, but wagtail is not added to the site packages (used by uwsgi).

{ config, pkgs, nixpkgs-6425843, ... }:
{
  nixpkgs.overlays = [ 
    (final: prev: {
      pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [ (pyfinal: pyprev: {
        wagtail = nixpkgs-6425843.python3Packages.wagtail;
      })];
    }) 
  ];

Could someone explain why these two overlays are not equivalent ?

That is one of many problems that raise because nix has not static typing + there is no runtime check that verifies the supplied inputs.

The assigned value for wagtail on the overlay is not expected to be a python package derivation. If you assign any invalid value to the package overlay, the package will disappear.

The overlay must be called using pyfinal.callPackage only, even if you supply other callPackage it will provably fail again since the overlay expects the return type/structure of the callPackage supplied on pyfinal.

e.g. these also fail (causes the package to be missing)

  • wagtail = pkgs-stable.python312Packages.callPackage ./scikit_learn.nix {};
  • wagtail = "something"
  • wagtail = 99