New install - same old problem with Python modules

Linux veteran, NixOS noob. After referencing this previous topic - Python3 not importing modules - I figured that a complete rebuild of my system would fix this. But I was wrong. I’ve tested this from a console login, with no user accounts. The modules I’m adding are there, it’s just that the link created for python is not in the same store as the installed modules.

Here is my configuration.nix:

# Edit this configuration file to define what should be installed on
# your system.  Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).

{ config, pkgs, ... }:

  imports =
    [ # Include the results of the hardware scan.

  # GRUB bootloader
  boot.loader = {
    efi = {
      canTouchEfiVariables = true;
      efiSysMountPoint = "/boot/efi";
    grub = {
      efiSupport = true;
      device = "nodev";

  # Networking
  networking = {
    hostName = "nixos-kde";
    networkmanager.enable = true;
    firewall = {
      enable = true;
      allowedTCPPorts = [ 22 ];
  fileSystems."/media/host" = {
    device = "dss-endeavouros:/";
    fsType = "nfs";
    options = [ "nfsvers=4.2" "x-systemd.automount" "noauto" ];

  # locale
  time.timeZone = "America/Los_Angeles";
  i18n.defaultLocale = "en_US.UTF-8";
  i18n.extraLocaleSettings = {
    LC_ADDRESS = "en_US.UTF-8";
    LC_MONETARY = "en_US.UTF-8";
    LC_NAME = "en_US.UTF-8";
    LC_NUMERIC = "en_US.UTF-8";
    LC_PAPER = "en_US.UTF-8";
    LC_TELEPHONE = "en_US.UTF-8";
    LC_TIME = "en_US.UTF-8";

  # X11 with KDE
  services.xserver = {
    enable = true;
    layout = "us";
    xkbVariant = "";
    displayManager.sddm.enable = true;
    desktopManager.plasma5.enable = true;
    videoDrivers = [ "virtio" ];

  # Enable sound with pipewire.
  sound.enable = true;
  hardware.pulseaudio.enable = false;
  security.rtkit.enable = true;
  services.pipewire = {
    enable = true;
    alsa.enable = true;
    alsa.support32Bit = true;
    pulse.enable = true;

  # Allow unfree packages
  nixpkgs.config.allowUnfree = true;

  # Global packages
  environment.systemPackages = with pkgs; [
  # system
    # firewalld
  # development
    (python311.withPackages (ps: with ps; [ ipython distro pyaml ]))

  # utilities

  programs = {
      fish.enable = true;
      less.enable = true;
      nano.syntaxHighlight = true;
      nano.nanorc = ''
        set atblanks
        set autoindent
        set boldtext
        set breaklonglines
        set casesensitive
        set constantshow
        set historylog
        set indicator
        set linenumbers
        set locking
        set matchbrackets "(<[{)>]}"
        set mouse
        set nonewlines
        set softwrap
        set tabsize 4
        set tabstospaces
        set trimblanks

        set titlecolor bold,white,magenta
        set promptcolor black,yellow
        set statuscolor bold,white,magenta
        set errorcolor bold,white,red
        set spotlightcolor black,orange
        set selectedcolor lightwhite,cyan
        set stripecolor ,yellow
        set scrollercolor magenta
        set numbercolor magenta
        set keycolor lightmagenta
        set functioncolor magenta

        extendsyntax python tabgives "    "
        extendsyntax makefile tabgives "	"

        bind ^X cut main
        bind ^C copy main
        bind ^V paste all
        bind ^Q exit all
        bind ^S savefile main
        bind ^F whereis all
        bind ^G findnext all
        bind ^R replace main
        unbind ^U all
        unbind ^N main
        unbind ^Y all
        unbind M-J main
        unbind M-T main
        bind ^Z undo main
      partition-manager.enable = true;
      vim.package = pkgs.vim-full;

  # List services that you want to enable:
  services = {
    fstrim.enable = true;
    openssh.enable = true;
    qemuGuest.enable = true;
    printing.enable = true;  
    spice-vdagentd.enable = true;

  # This value determines the NixOS release from which the default
  # settings for stateful data, like file locations and database versions
  # on your system were taken. It‘s perfectly fine and recommended to leave
  # this value at the release version of the first install of this system.
  # Before changing this value read the documentation for this option
  # (e.g. man configuration.nix or on
  system.stateVersion = "23.05"; # Did you read the comment?


Everything else that I’ve tested seems to be working OK. As you can see, though, my python link points to the wrong store:

/run/current-system/sw/bin/python -> /nix/store/3k7is7nc2xbav8a48vx7arad522d8czx-python3-3.11.4/bin/python

installed pyaml module

pyaml -> /nix/store/wmbcmrrhni2pv2x1zfvwmvpr7saycbv3-python3-3.11.4-env/lib/python3.11/site-packages/pyaml

I’ve tried python3 and python311Full, both with the same results. I feel like I’m sooooo close to actually getting NixOS to work. What am I doing wrong?

Can you clarify what you mean by this and what the symptom is?

From a quick skim, it looks like you just need to remove the first python3 11 from your packages. But also, globally installing a python with a set of packages isn’t really ~ideal…

1 Like

The store link of python is different than the store link of pyaml, which is where the global site-packages are installed, thus I can’t use them.

Are you saying that I don’t need the python311 package, only the one that includes the modules? Maybe that’s where I’m going wrong.

I really need these packages installed globally so that all users can run my scripts; I have 20+ systems all setup this way and would hate to have to make something completely different just for NixOS.

Thank you so much for this hint! I’m not sure when/why I added this, maybe an old online doc.

withPackages is synthesizing a python with all of the specified modules in its site-packages. When there’s another python earlier in your PATH, you end up running the wrong one.

This is basically the nix/nixos version of the problem people run into when some packages get installed with the system python and then they install conda or something and end up with new python on PATH and their installed packages split between them.

This might or might not be the right thing in your case, but the reason I say it isn’t ~ideal is because Nix enables us to do things like package the scripts with their dependencies without installing their modules globally.