-
-
Notifications
You must be signed in to change notification settings - Fork 14.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pre-commit: fixing import bug for built-in hooks #251418
pre-commit: fixing import bug for built-in hooks #251418
Conversation
Pre-commit has a "language" called By setting the pythonpath in the wrapper, we've fixed what we set out to fix. But we're clobbering pre-commit's idea of what's available in "system". In my case, I've got python311 in the calling shell, but my Perhaps the wrapper needs to either:
To reproduce: # flake.nix
{
inputs = {
flake-utils.url = "github:numtide/flake-utils";
nixpkgs.url = "github:MatrixManAtYrService/nixpkgs?ref=fix-pre-commit";
};
outputs = { self, nixpkgs, flake-utils,}:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
};
in rec
{
devShells.default = pkgs.mkShell {
packages = [
pkgs.python311
pkgs.pre-commit
];
};
});
} # .pre-commit-hooks.yaml
---
repos:
- repo: local
hooks:
- id: print-python-version
name: print-python-version
language: system
entry: python --version
pass_filenames: false
default_language_version:
python: python3.11
|
f094a29
to
8b29a67
Compare
Ok, I fixed it by patching pre-commit to only expose the calling environment's
meta hooks are hard-coded into pre-commit. So far as I know, nobody is extending them. So this distinction need not be thought about by users (:crossed_fingers:). |
pandas has a nontrivial {
inputs = {
flake-utils.url = "github:numtide/flake-utils";
# switch the comment below to activate the other codebase
nixpkgs.url = "github:MatrixManAtYrService/nixpkgs?ref=fix-pre-commit";
# nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
};
in
{
devShells.default = pkgs.mkShell {
packages = [
pkgs.pre-commit
pkgs.nodejs
];
};
});
} Ruff is still a problem, but it's not a problem for this PR. As for everything else, this PR fixes a wide swath of hooks, all of which previously failed with errors like:
Also, it introduces no new failures. It seems pretty clear that it's much better than it was before. I think it can be merged. |
@FRidh you made a very helpful comment on my previous attempt to address this issue, thanks for that. Unfortunately I introduced problems with that PR. It's a little more invasive, but I think this actually does trick while also preventing those problems. Can I get your thoughts and/or review on it? |
Thanks to @anund for pointing me at the wrapper script as a place to address this kind of problem. I've had to go a bit further than you recommended but thanks to that help I think I'm on the right path here. If you have any thoughts about this approach, they'd be valued. |
@MatrixManAtYrService I think you may be able to just define the python version your dev shell uses rather than patching To reproduce I had to adjust somethings in the example #flake.nix
{
inputs = {
flake-utils.url = "github:numtide/flake-utils";
nixpkgs.url = "github:nixos/nixpkgs?rev=a4832e490d62bdb1e60cab751a9ae38b4431934e";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs { inherit system; };
in rec
{
devShells.default = pkgs.mkShell {
packages = [
pkgs.python311
(pkgs.pre-commit.overrideAttrs (previousAttrs: {
makeWrapperArgs = ''--set PYTHONPATH $PYTHONPATH'';
}))
];
};
});
}
This gets us to the mismatch behaviour if we create Updating the python version is ~easy since #flake.nix
{
inputs = {
flake-utils.url = "github:numtide/flake-utils";
nixpkgs.url = "github:nixos/nixpkgs?rev=a4832e490d62bdb1e60cab751a9ae38b4431934e";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs { inherit system; };
in rec
{
devShells.default = pkgs.mkShell {
packages = [
pkgs.python311
# example getting the parens right, you should probably define pre-commit above in the let
((pkgs.pre-commit.override{ python3Packages = pkgs.python311Packages; }).overrideAttrs (previousAttrs: {
makeWrapperArgs = ''--set PYTHONPATH $PYTHONPATH'';
}))
];
};
});
} Note you'll probably use |
Hmm, looking a bit closer at the suggested fix the way the python path is built is a bit wrong. It captures the --prefix PYTHONPATH ${pkgs.python311Packages.python}/${pkgs.python311Packages.python.sitePackages}` |
I finally got a chance to meditate on @anund's comments. For the particular repo I'm most worried about (work stuff), this seems pretty close:
The above overrides won't work for everyone. Your hooks may need different paths, but the I'm now considering just closing this PR and writing a blog post about how to make pre-commit work inside of nix. |
@anund's approach almost solves the problem. The last hurdle for me was that the propagated build inputs needed to be injected to the environment: pkgs.pre-commit.overrideAttrs(prevAttrs:
with pkgs.python3Packages;
let depsPath = makePythonPath prevAttrs.propagatedBuildInputs;
in {
makeWrapperArgs = (prevAttrs.makeWrapperArgs or []) ++ [
"--prefix PYTHONPATH : ${depsPath}"
"--prefix PYTHONPATH : $out/${python.sitePackages}"
];
}
); I'm not sure whether a difference between |
Thanks for the fix! I've written a test for a different issue which might've been caused by the same underlying problem. Feel free to cherry-pick it. |
Thanks for the test! I'm unaccustomed to nixpkgs development so it'll be good for me to look that over. It's been a little while since I've thought about this PR, but it's very nice to see it pop back up. I was feeling a little bit alone in my struggles against pre-commit. |
Result of 4 packages failed to build:
2 packages built:
|
I didn't know about that tool, that's pretty cool. I'll investigate how those packages are using pre-commit so I can avoid breaking them. |
Just ran into this while working on a flake. I used the override from #251418 (comment) for now and it works, but think it would be nice when this gets in rather than having to manually update every flake that uses pre-commit. I've never used nix-shell -p nixpkgs-review.out --run 'nixpkgs-review pr 251418'
this path will be fetched (0.06 MiB download, 0.32 MiB unpacked):
/nix/store/rx6laqr63fhb15sysy8z4magbijb8g0i-nixpkgs-review-2.10.4
copying path '/nix/store/rx6laqr63fhb15sysy8z4magbijb8g0i-nixpkgs-review-2.10.4' from 'https://cache.nixos.org'...
$ git -c fetch.prune=false fetch --no-tags --force https://github.com/NixOS/nixpkgs master:refs/nixpkgs-review/0 pull/251418/head:refs/nixpkgs-review/1
remote: Enumerating objects: 183036, done.
remote: Counting objects: 100% (29281/29281), done.
remote: Compressing objects: 100% (1251/1251), done.
remote: Total 183036 (delta 28476), reused 28580 (delta 27952), pack-reused 153755
Receiving objects: 100% (183036/183036), 109.76 MiB | 6.52 MiB/s, done.
Resolving deltas: 100% (108115/108115), completed with 7618 local objects.
From ssh://github.com/NixOS/nixpkgs
* [new branch] master -> refs/nixpkgs-review/0
* [new ref] refs/pull/251418/head -> refs/nixpkgs-review/1
$ git worktree add /home/aa/.cache/nixpkgs-review/pr-251418/nixpkgs 971ea0a28ad94b23d221c8377120340a303fc736
Preparing worktree (detached HEAD 971ea0a28ad9)
Updating files: 100% (41726/41726), done.
HEAD is now at 971ea0a28ad9 Merge pull request #320833 from matteo-pacini/easytag-resurrection
$ git merge --no-commit --no-ff ed76e4ddcfde2f8b2891455e7e61b71cfc6da502
Auto-merging pkgs/tools/misc/pre-commit/default.nix
Automatic merge went well; stopped before committing as requested
$ nix build --file /nix/store/rx6laqr63fhb15sysy8z4magbijb8g0i-nixpkgs-review-2.10.4/lib/python3.11/site-packages/nixpkgs_review/nix/review-shell.nix --nix-path nixpkgs=/home/aa/.cache/nixpkgs-review/pr-251418/nixpkgs nixpkg
s-overlays=/run/user/1000/tmpbsohbw02 --extra-experimental-features nix-command no-url-literals --no-link --keep-going --no-allow-import-from-derivation --option build-use-sandbox relaxed --argstr system x86_64-linux --argst
r nixpkgs-path /home/aa/.cache/nixpkgs-review/pr-251418/nixpkgs --argstr nixpkgs-config-path /run/user/1000/tmpufvqw8fw.nix --argstr attrs-path /home/aa/.cache/nixpkgs-review/pr-251418/attrs.nix
Link to currently reviewing PR:
https://github.com/NixOS/nixpkgs/pull/251418
6 packages built:
pre-commit pre-commit.dist python311Packages.asteroid-filterbanks python311Packages.asteroid-filterbanks.dist python311Packages.pyannote-audio python311Packages.pyannote-audio.dist
$ /nix/store/j7rp0y3ii1w3dlbflbxlv4g7hbaaz3bs-nix-2.18.2/bin/nix-shell --argstr system x86_64-linux --argstr nixpkgs-path /home/aa/.cache/nixpkgs-review/pr-251418/nixpkgs --argstr nixpkgs-config-path /run/user/1000/tmpufvqw8
fw.nix --argstr attrs-path /home/aa/.cache/nixpkgs-review/pr-251418/attrs.nix --nix-path nixpkgs=/home/aa/.cache/nixpkgs-review/pr-251418/nixpkgs nixpkgs-overlays=/run/user/1000/tmpbsohbw02 /nix/store/rx6laqr63fhb15sysy8z4ma
gbijb8g0i-nixpkgs-review-2.10.4/lib/python3.11/site-packages/nixpkgs_review/nix/review-shell.nix |
Pre-commit's "system" language is a sort of escape hach from the encapsulation which pre-commit typically provides. It just runs commands without thinking too hard about setting up or tearing down environments. But it is used for two things: user-provided hooks which reference things in calling environment, and pre-commit-provided hooks which live in the pre-commit package (I'm calling these "meta" hooks). The challenge becomes: which PATH and PYTHONPATH variables do we expose to pre-commit? If it's the calling environment, the meta hooks break, and if it's the packaged environment, the external-facing system hooks break. In order to make both of these work at the same time, this commit separates 'system' into two languages: 'system', and 'meta'. System hooks get access to the calling environment, and meta hooks get access to the packaged environment.
ed76e4d
to
423b0dd
Compare
@imincik, I wonder if something has changed, because like @fidgetingbits, I also find that I spent a bit of time with I also tested this change with
I'm not sure if these are cases where pre-commit is failing to be as deterministic as it aims to, or whether they're cases where maintainers have pushed commits without first running their pre-commit hooks, but as far as I can see, there's no indication that this change makes things any worse in those repos. |
I'm getting errors from |
Closes NixOS#270805 by verifying that NixOS#251418 fixes the issue.
Closes NixOS#270805 by verifying that NixOS#251418 fixes the issue.
Context
Pre-commit has built-in "meta" hooks. If they are isolated from pre-commit itself, they don't work.
#235123 prevented pre-commit's dependencies from propagating into devshells. This was necessary because those dependencies were clobbering others in the devshell definition.
This increased isolation broke the "meta" hooks. A workaround emerged (see comments below) which involved configuring the pre-commit wrapper script to always run with its PYTHONPATH set such that the pre-commit internals are accessible.
The workaround clutters up the devshell definition, and it needlessly exposes
system
type hooks to pre-commit internals. Really, only themeta
type hooks need to see pre-commit internals.Description of changes
This PR patches pre-commit so that it treats
meta
andsystem
hook types separately, ensuring that pre-commit itself (viaPYTHONPATH
) is available only to themeta
hooks. This allows users to just addpkgs.pre-commit
to their devshell without thinking aboutPYTHONPATH
at all.Things done
sandbox = true
set innix.conf
? (See Nix manual)nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)