You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
The PATH variable is not set properly for Gui Git clients #1465
For Gui Git clients like SmartGit, the PATH variable isn't set correctly to locate the current virtualenv, and when it runs the Git hook it will give errors as it locates the wrong Python executable.
To make it work, I need to modify my .git/hooks/pre-commit and add the following line:
I suspect you're talking about a local + system hook which is the escape hatch and not the supported golden path -- local + system is "I promise I'll be responsible for making these tools available, trust me pre-commit and will not be receiving features like virtualenv activation, etc.
if you depend on project-specific virtualenvs being on the PATH, you should write your hook entries as such (utilizing tools like tox or poetry or even just a script which knows how to modify the PATH and/or set up your environment)
which on second read it sounds exactly like #1412 / #950
please next time describe your actual problem instead of some vague solution to your problem -- this is what's called an XY problem and is a very easy trap to fall into (especially when you're not 100% familiar with the space you're working in)
@asottile It's not just isort, but also prospector, black. I would like to install these into the local virtualenv instead of system-wide. This is my actual problem.
the whole point of pre-commit is it manages your tools, if you're using language: system you're escaping the supported path and things will be rocky (language: system is "I will provide the tools" instead of "pre-commit will provide the tools"). kinda the whole point of the framework is that it installs stuff for you
pre-commit will install your tools in isolated environments and not globally if configured according to the documentation and examples
and again, I can't see what you have because you still haven't shown your configuration or versions or logs or output
Maybe I can add one thing to this discussion because I was dealing with the same thing. I read few issues on it and I fully understand @asottile position not to modify the behavior of system language that is supposed to be unmanaged, system environment. The issue is that with current implementation the pre-commit run and git commit is actually behaving differently.
I decided to not open another issue with the whole description above, because there is already too many of them, I believe that we can discuss it here and if you decide that we have a problem just reopen. I am also glad to help you implementing changes if we agree that some can be done.
Problem
In my opinion problem is that Python system language hooks do not run in the same environment as pre-commit when git commit is executed. Which causes pre-commit run and git commit to behave differently.
Reproduction
## Pre-test configuration
# create new poetry project
poetry new temp_repo; cd temp_repo
# initialize its git repository
git init
# add flake8 as dependency
poetry add -D flake8
# commit what you have
git add .; git commit -m "initial commit"
## Test steps
# (step 1) add pre-commit as developer dependency and install it to venv
poetry add -D pre-commit
# (step 2) create got hooks
poetry run pre-commit install
# (step 3) configure the hook
# The example is simplified and runs flake8, but is actually important when running things that requires
# all project dependencies, which as documentation states is one of the reasons to use local hooks with system language
Set-Content .\.pre-commit-config.yaml -Value "repos: `
- repo: local `
hooks: `
- id: flake8 `
name: flake8 `
entry: python -mflake8 `
language: system `
types: [python] `
require_serial: true `
"
# (step 4) introduce flake error to the code
Set-Content .\temp_repo\__init__.py -Value "__version__='0.1.0'"
# (step 5) stage the changes
git add .
# (step 6) run pre-commit manually
pre-commit run --all-files
# (step 7) commit changes
git commit
Expected result
The last two commands behave the same, they both fail, because pre-commit is not installed when venv is not activated.
Actual result
The pre-commit run (step 6) fails to find pre-commit command as expected.
The git commit (step 7) runs pre-commit properly, but the hook itself fails, because of non-existing module.
If there were non-local hooks, the first command would not run them of course, but the second would and they could even pass.
Additional explanation
I understand that the question is "Why the hell are you running commands outside of virtualenv if you need it?". The answer is that a lot of tools is doing it for me. For example VS Code SCM is running git commands as its own subprocess which usually does not have venv activated (the venv is activated by extension in integrated terminal).
Cause
The .git/hooks/pre-commit script runs the pre-commit application in hardcoded python virtualenv, but the application itself is executing system hooks outside of it.
Workarounds that can be applied locally
As stated in this issue already, one can modify the .git/hooks/pre-commit to append the virtualenv path to PATH env var, before running pre-commit application.
As stated in this issue already, one can modify the entry of the hook, to first run a script that will actually activate the venv and then run the command.
Proposed solution no. 1 (not good one, but proposed above and worth pointing why it is not good)
Since the .git/hooks/pre-commit is bound to run the pre-commit in virtualenv, the system language hooks that are run, should also be run there.
It can be achieved either by modifying the system language implementation or by just implementing workaround number one.
Why not
I understand the we are reluctant to do it, because pre-commit is not a Python-only tool and the system language is supposed (as the name states) to run in default system environment. The whole responsibility on providing proper system environment is on a user (and it is great).
Proposed solution no. 2
Since the issue with virtualenv is a Python problem, we can implement another language called for example python-local-env that would prepend the PATH env var with the absolute path to a folder holding python interpreter that is executing pre-commit code.
Activity
asottile commentedon May 21, 2020
can you show an example and what's happening and what you expect?
asottile commentedon May 21, 2020
I suspect you're talking about a
local+systemhook which is the escape hatch and not the supported golden path --local+systemis "I promise I'll be responsible for making these tools available, trust me pre-commit and will not be receiving features like virtualenv activation, etc.if you depend on project-specific virtualenvs being on the PATH, you should write your hook entries as such (utilizing tools like
toxorpoetryor even just a script which knows how to modify thePATHand/or set up your environment)which on second read it sounds exactly like #1412 / #950
stevenxxiu commentedon May 22, 2020
Ok I added an
.env.shand included:with the
.pre-commit-config.yamlentries of:This appeared to work. Is it the recommended approach?
asottile commentedon May 22, 2020
no, you should use https://github.com/asottile/seed-isort-config or an import sorter which doesn't need everything installed such as https://github.com/asottile/reorder_python_imports
please next time describe your actual problem instead of some vague solution to your problem -- this is what's called an XY problem and is a very easy trap to fall into (especially when you're not 100% familiar with the space you're working in)
stevenxxiu commentedon May 22, 2020
@asottile It's not just
isort, but alsoprospector,black. I would like to install these into the local virtualenv instead of system-wide. This is my actual problem.asottile commentedon May 22, 2020
the whole point of pre-commit is it manages your tools, if you're using
language: systemyou're escaping the supported path and things will be rocky (language: systemis "I will provide the tools" instead of "pre-commit will provide the tools"). kinda the whole point of the framework is that it installs stuff for youpre-commit will install your tools in isolated environments and not globally if configured according to the documentation and examples
and again, I can't see what you have because you still haven't shown your configuration or versions or logs or output
KRunchPL commentedon Nov 20, 2021
Maybe I can add one thing to this discussion because I was dealing with the same thing. I read few issues on it and I fully understand @asottile position not to modify the behavior of
systemlanguage that is supposed to be unmanaged, system environment. The issue is that with current implementation thepre-commit runandgit commitis actually behaving differently.I decided to not open another issue with the whole description above, because there is already too many of them, I believe that we can discuss it here and if you decide that we have a problem just reopen. I am also glad to help you implementing changes if we agree that some can be done.
Problem
In my opinion problem is that Python
systemlanguage hooks do not run in the same environment as pre-commit whengit commitis executed. Which causespre-commit runandgit committo behave differently.Reproduction
Expected result
The last two commands behave the same, they both fail, because
pre-commitis not installed when venv is not activated.Actual result
The
pre-commit run(step 6) fails to findpre-commitcommand as expected.The
git commit(step 7) runspre-commitproperly, but the hook itself fails, because of non-existing module.If there were non-local hooks, the first command would not run them of course, but the second would and they could even pass.
Additional explanation
I understand that the question is "Why the hell are you running commands outside of virtualenv if you need it?". The answer is that a lot of tools is doing it for me. For example VS Code SCM is running git commands as its own subprocess which usually does not have venv activated (the venv is activated by extension in integrated terminal).
Cause
The
.git/hooks/pre-commitscript runs thepre-commitapplication in hardcoded python virtualenv, but the application itself is executing system hooks outside of it.Workarounds that can be applied locally
As stated in this issue already, one can modify the
.git/hooks/pre-committo append the virtualenv path to PATH env var, before runningpre-commitapplication.As stated in this issue already, one can modify the entry of the hook, to first run a script that will actually activate the venv and then run the command.
Proposed solution no. 1 (not good one, but proposed above and worth pointing why it is not good)
Since the
.git/hooks/pre-commitis bound to run thepre-commitin virtualenv, thesystemlanguage hooks that are run, should also be run there.It can be achieved either by modifying the
systemlanguage implementation or by just implementing workaround number one.Why not
I understand the we are reluctant to do it, because
pre-commitis not a Python-only tool and thesystemlanguage is supposed (as the name states) to run in default system environment. The whole responsibility on providing proper system environment is on a user (and it is great).Proposed solution no. 2
Since the issue with virtualenv is a Python problem, we can implement another language called for example
python-local-envthat would prepend the PATH env var with the absolute path to a folder holding python interpreter that is executingpre-commitcode.Of course we need to consider reverting the change made to PATH env var after the hook finishes.
asottile commentedon Nov 20, 2021
the answer is still no,
language: systemis "I will make sure things are set up properly" and is the unsupported pathasottile commentedon Nov 20, 2021
and in the future, please do not bump year-old threads with off topic comments