How to add a python module/package to a nix/python overlay?

This overlay fixed an issue I was having with LD_LIBRARY_PATH:

  nixpkgs.overlays = [
    (self: super: rec {
      pythonldlibpath = lib.makeLibraryPath (with super; [
        zlib zstd stdenv.cc.cc curl openssl attr libssh bzip2 libxml2 acl libsodium util-linux xz systemd
      ]);
      # here we are overriding python program to add LD_LIBRARY_PATH to it's env
      python = super.stdenv.mkDerivation {
        name = "python";
        buildInputs = [ super.makeWrapper ];
        src = super.python312;
        installPhase = ''
          mkdir -p $out/bin
          cp -r $src/* $out/
          wrapProgram $out/bin/python3 --set LD_LIBRARY_PATH ${pythonldlibpath}
          wrapProgram $out/bin/python3.12 --set LD_LIBRARY_PATH ${pythonldlibpath}
        '';
      };
    })
  ];

But now I’m getting a new error when running a python script:

Reading inline script metadata from `/home/guttermonk/.local/share/whispernow/transcribe_gui.py`
warning: The requested interpreter resolved to Python 3.12.8, which is incompatible with the script's Python requirement: `==3.12`
Traceback (most recent call last):
  File "/home/guttermonk/.local/share/whispernow/transcribe_gui.py", line 13, in <module>
    import tkinter as tk
  File "/nix/store/chkqz1vrr3dhqzld9r8iv014i1anb0y4-python/lib/python3.12/tkinter/__init__.py", line 38, in <module>
    import _tkinter # If this fails your Python may not be configured for Tk
    ^^^^^^^^^^^^^^^
ModuleNotFoundError: No module named '_tkinter'

To no avail, I tried adding the tkinter package using:

  environment.systemPackages = [
    pkgs.python312Packages.tkinter
  ];

Any suggestions on how to add tkinter to my nix overlay?

Maybe I’m misremembering but it’s possible you want to use python312Full

That was a good thought. I tried switching my overlay to src = super.python312Full;, but got the same error.

Adding libraries to environment.systemPackages pretty much never works.

Seems like using python312.withPackages (ps: [ ps.tkinter ]) in place of python312 should work?

$ nix-shell -p python3 --run 'python3 -c "import tkinter"'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/nix/store/dzi9r3xn0ny4l4gwnyqpncljq40pdk6f-python3-3.12.8/lib/python3.12/tkinter/__init__.py", line 38, in <module>
    import _tkinter # If this fails your Python may not be configured for Tk
    ^^^^^^^^^^^^^^^
ModuleNotFoundError: No module named '_tkinter'
$ nix-shell -p 'python3.withPackages (ps: [ ps.tkinter ])' --run 'python3 -c "import tkinter"'
$ echo $?
0

See: python.withPackages function.

Thanks so much for the suggestion. I updated this line in my overlay as follows (and thought for sure it was going to work), but am still getting the same error.
src = super.python312.withPackages(ps: with ps; [ tkinter ]);

I’m inexperienced with python and wondering if the “warning” part of the error would cause the script to fail completely or if it’ll still run.
warning: The requested interpreter resolved to Python 3.12.8, which is incompatible with the script's Python requirement: ==3.12

I’m afraid I cannot reproduce your issue when using withPackages.

$ cat foo.nix
{ pkgs ? import (builtins.fetchTarball "https://github.com/NixOS/nixpkgs/archive/26d499fc9f1d567283d5d56fcf367edd815dba1d.tar.gz") { } }:
let
  pythonldlibpath = pkgs.lib.makeLibraryPath (with pkgs; [ zlib zstd stdenv.cc.cc curl openssl attr libssh bzip2 libxml2 acl libsodium util-linux xz systemd ]);
in
pkgs.stdenv.mkDerivation {
  name = "python";
  buildInputs = [ pkgs.makeWrapper ];
  src = pkgs.python312.withPackages (ps: with ps; [ tkinter ]);
  installPhase = ''
    mkdir -p $out/bin
    cp -r $src/* $out/
    wrapProgram $out/bin/python3 --set LD_LIBRARY_PATH ${pythonldlibpath}
    wrapProgram $out/bin/python3.12 --set LD_LIBRARY_PATH ${pythonldlibpath}
  '';
}
$ nix-build foo.nix
/nix/store/mli8r8rw33vhlnagc3im28lr2xkh7w8q-python
$ ./result/bin/python -c 'import tkinter; print("success")'
success

This is odd:


So the overlay is adding tkinter but the program isn’t finding it?

I wonder if the “underscore tkinter” in the error message (shown below) could hint towards a typo/bug in the WhisperNow program?
ModuleNotFoundError: No module named '_tkinter'

@justinas I marked your answer as the solution since it answers the original question. Thanks so much for the info. I really learned a lot here.

I also just figured out that when I add the “withPackages” to the src line of the overlay, it breaks the part in the installPhase where it sets the LD_LIBRARY_PATH.

You can test it by adding the “withPackages” suggested above and running whispernow in terminal, which should throw this libz.so.1 error. Then comment the withPackages out, and the error goes away.