How to tell what's making a flake impure? Inherit macOS Security?

New to nix, I have a working nix flake. I notice that my Oh-My-Zsh/p10k status line is showing it as impure.

  inputs = { nixpkgs.url = "github:nixos/nixpkgs"; };

  outputs = { self, nixpkgs }:
      pkgs = nixpkgs.legacyPackages.x86_64-darwin;
      inherit (pkgs.darwin.apple_sdk.frameworks) Security;
    in {
      packages.x86_64-darwin.libtorch-bin = pkgs.libtorch-bin;

      devShells.x86_64-darwin.default = pkgs.mkShell {
        buildInputs = with pkgs;
          [ self.packages.x86_64-darwin.libtorch-bin iconv cowsay ]
          ++ lib.optionals stdenv.isDarwin [ Security ];

        shellHook = ''
          echo "libtorch-bin devShell active."


  1. Is there a way to ask nix to tell me what is impure?
  2. Is it that inherit line? If so, is there another way to define Security?
  3. Any other improvements?

Flakes are not pure or impure by themselves, it’s just that when they do things that are not available in pure evaluation mode, they’ll fail. Flakes are run in pure evaluation mode by default, which makes sense since their point is to define all the inputs beforehand and not have them depend on the environment they run in.
I don’t know about the p10k integration, but when it shows impure that probably means you’re running nix develop in impure evaluation mode. Could you maybe share how you are executing it?

Regarding your questions:

I don’t think so. But if you run nix develop / shell / whatever in pure evaluation mode on a flake that uses impure expressions, it will fail and print a helpful(!) error indicating why an expression can’t be run, for example:

error: in pure evaluation mode, 'fetchTarball' requires a 'sha256' argument

No, because the pkgs you’re inheriting from comes from the nixpkgs flake input, which is pure by definition.

You don’t really need the lib.optionals for the Security framework package, since your flake only provides a package and a devShell for x86-64-darwin anyway. Also, regarding the packages attribute, it’s not really much use if you just want to use the upstream package from nixpkgs plus some other packages in a dev shell via nix develop. But kudos for figuring out flakes and the fancy inherit statement as someone who is “new to nix”. It took me quite a while to figure those two things out :sweat_smile:

1 Like

The impure text from p10k is from the IN_NIX_SHELL environment variable, which is always set to impure IIRC if you are running nix develop, but if you run nix-shell with --pure it would be pure

TL’DR: You can ignore the impure and read it as nix shell.

To fully understand, we have to distinguish first between “pure shells” and “pure evaluation”.

The former is a development shell that ignores the surrounding environment when entered. You traditionally do this by nix-shell --pure. It won’t inherit your PATH, HOME, USER, etc.

Whenever you run that it is very unlikely that you get a zsh with p10k. So if you enter a pure shell, you probably will never get told this by your p10k prompt.

In contrast we have “pure evaluation” which restricts what nix “sees” while it calculates the “buildplan”. Pure evaluation does not allow arbitrary file system access, but only within a limited subset of the store.

So to answer the individual questions:

  1. As explained above you will probably never see it telling you when you are in a pure shell, as there p10k isn’t started.
  2. inherit x means x = x and inherit (x) y means y = x.y (there are subtle differences within a recursive set)
  3. yes
    1. As your only supported system is darwin, remove the conditional
    2. To ensure that hooks are run correctly, you should prefer the packages argument to mkShell
    3. usage of with is controversial.