I am new to nix and as part of learning it I am trying to setup my proejcts dependencies through flake.nix in the proejct root and activating it through direnv.
Two packages which are used for development are python312Full
and pre-commit
. I am now working on a task to upgrade to python313Full
but when I change the package from 312 to 313, rebuild and run python --version
I am still getting python 3.12
. I have noticed that removing the pre-commit
package fixes this. So my conclusion is that pre-commit
is putting python312
in path. Can I somehow use pre-commit
without it putting another python version in the path?
I’m not sure why you are getting this issue, a minimal reproducible example would help but consider installing pre-commit by overriding which pythonPackages it uses like so: pre-commit.override { python3Packages = python313Packages;}
Also, I’d like to note that this exists, but probably is not helpful:
nix-repl> python313Packages.pre-commit-hooks.meta.description
"Some out-of-the-box hooks for pre-commit"
@gytis-ivaskevicius hey. Thanks for your reply. The override suggestion has worked indeed.
Regarding the minimal snippet you can find it below. I have a directory with 3 files. flake.nix, flake.lock, .envrc.
The .envrc has the following
# shellcheck shell=bash
use flake
The flake.nix
{
description = "example shell of pre-commit getting python 3.12";
inputs.systems.url = "github:nix-systems/default";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
inputs.flake-utils = {
url = "github:numtide/flake-utils";
inputs.systems.follows = "systems";
};
outputs = { nixpkgs, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = import nixpkgs { inherit system; };
in
{
devShells.default = with pkgs; pkgs.mkShell {
nativeBuildInputs = [
pre-commit # python --version prints 3.12
# (pre-commit.override { python3Packages = python313Packages; }) # python --version prints 3.13
];
shellHook = ''
echo '--PYTHON VERSION--'
python --version
echo '--PYTHON VERSION--'
'';
};
}
);
}
I created a directory, put these two files in and ran direnv allow
. After it compiles I get the python version printed.
Now I am expecting that pre-commit is an executable but python is not, maybe this is the wrong expectation here?
Okay, I figured it out, it loads python from propagated build inputs which is part of the pre-commit. What I suggested is still required even if you used numtide/devshell (which i recommend using as well as flake-parts) since otherwise it would load additional python in the background
Just to clarify. You are talking about the override bit, right?
yes I am
Extra words so I could reply
1 Like