-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
More granular control over PIPENV_VENV_IN_PROJECT variable. #5026
Conversation
…is set to False that it does not use .venv directory.
@matteius I'm not able to test atm, but from a casual glance, it looks like that should fix the issue. Moreover, I think switching from booleans to constants may be a better approach to avoid confusion (but this may introduce breakages): I propose the following values:
The Actually, this may not break anything, because Anyways, yea that looks like a good fix for the issue |
pipenv/environments.py
Outdated
self.PIPENV_VENV_IN_PROJECT = os.environ.get("PIPENV_VENV_IN_PROJECT") | ||
if self.PIPENV_VENV_IN_PROJECT is not None: | ||
self.PIPENV_VENV_IN_PROJECT = self.PIPENV_VENV_IN_PROJECT.lower() in ( | ||
"true", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that some of these are already defined above with _true_values
@@ -1 +0,0 @@ | |||
Internal to pipenv, the utils.py was split into a utils module with unused code removed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I duplicated this news fragment in main.
@@ -92,14 +92,9 @@ def test_proper_names_unamanged_virtualenv(PipenvInstance): | |||
def test_directory_with_leading_dash(raw_venv, PipenvInstance): | |||
with temp_environ(): | |||
with PipenvInstance(chdir=True, venv_in_project=False, name="-project-with-dash") as p: | |||
if "PIPENV_VENV_IN_PROJECT" in os.environ: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests aren't about this variable and shouldn't impact the test run since it use with temp_environ()
.
@@ -405,8 +405,6 @@ def test_install_venv_project_directory(PipenvInstance): | |||
prefix="pipenv-", suffix="temp_workon_home" | |||
) as workon_home: | |||
os.environ["WORKON_HOME"] = workon_home | |||
if "PIPENV_VENV_IN_PROJECT" in os.environ: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests aren't about this variable and shouldn't impact the test run since it use with temp_environ()
.
c = p.pipenv('run pip freeze') | ||
assert c.returncode == 0 | ||
c = p.pipenv('--venv') | ||
assert c.returncode == 0 | ||
venv_path = c.stdout.strip() | ||
assert os.path.isdir(venv_path) | ||
# Manually clean up environment, since PipenvInstance assumes that | ||
# the virutalenv is in the project directory. | ||
p.pipenv('--rm') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None of the other tests do this kind of cleanup.
I made some updates and made it safer with respect to the allowed true and false values. If we want to expand that list at some point to include enable(d)/disable(d) we can but I mostly just wanted to put out a patch for the issue at hand. |
if self.PIPENV_VENV_IN_PROJECT.lower() in _true_values: | ||
self.PIPENV_VENV_IN_PROJECT = True | ||
elif self.PIPENV_VENV_IN_PROJECT.lower() in _false_values: | ||
self.PIPENV_VENV_IN_PROJECT = False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does one need both False
and None
here? I see you documented it, but why do we need this feature?
If this is only for backward compatibility, I suggest considering supporting it but also to issue a warning that only false
should be used in the future.
If someone needs .venv
they could specify it specifically. Otherwise, IMHO .venv
is like magic. It's hidden at first when you ls
a directory, and this behavior is kind of opposite to Python's own: Explicit it better than implicit.
This is a great principle for any software project too...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None indicates that you haven't set the variable, so in this case the behavior is use the .venv if it is present. However if you want to definitely ignore a present .venv you would se it to be False. This is helpful for those doing development locally and building docker containers, that sometimes the .venv directory exists locally and gets copied into their container but is different system installed versions than the OS the container is running on. They want to be able to explicitly state in the .env not to ever use a .venv directory in the project, even if it exists because it got copied into the container. For additional context: #2763 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you want to definitely ignore a present .venv you would se it to be False.
I thought this should be the default, always ignore. Even if the variable isn't set.
A solution to @smac89's problem could done with .dockerignore
. They probably have something like this:
in project source:
$ ls -a
setup.py
Pipfile
Pipfile.lock
src/<many-python-files-here>
.venv
Dockerfile
Now, they (naively) do something in Dockerfile
ADD . /usr/src/app
WORKDIR /usr/src/app
RUN pipenv install
And viola, this thing is broken, because it uses an existing venv
. The solution is to create .dockerignore
file, and then add .venv
in it. This will prevent the ADD directive from copying .venv
into the docker container.
The real problem is however, the decision to default to the name .venv
. This should have been named either pipenv
venv
without the leading dot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I mentioned in my comment, we use docker-compose
, and as far as I can tell, docker-compose does not give one the option of filtering out certain files from a mounted volume. Therefore, once we mount the volume inside the build container, it includes everything in that volume.
.dockerignore
only comes into play when building a container. We don't build containers during development because that would just be a massive waste of time.
This change is not 100% backwards compatible and broke one of our docker builds: # Dockerfile
RUN PIPENV_VENV_IN_PROJECT="enabled" pipenv sync Previously, "enabled" was parsed as |
From a quick search on github it seems that most people are using |
We were also using "enabled" and this broke all our project builds (40+ projects in Bitbucket) and took me a long while to debug as the error I was initially receiving was |
While this is certainly annoying that so many builds are broken, I think this 'enabled' work was wrong to use. This probably would also work if you wrote 'disabled', since the previous code only checked if the variable was set, not if it was truthy.
This was an accident waiting to happen. Sorry, for breaking your builds, maybe we could have done this in a more graceful way. |
I suggest you pin your version of |
Allow PIPENV_VENV_IN_PROJECT to be read in as None, and ensure if it is set to False that it does not use .venv directory.
The issue
Fixes #2763
The fix
The variable was being cast to a boolean so it would be False even if it was not set, this allows a user to explicitly set the variable to a non-truthy value and ensure that the .venv directory gets ignored.
The checklist
news/
directory to describe this fix with the extension.bugfix
,.feature
,.behavior
,.doc
..vendor
. or.trivial
(this will appear in the release changelog). Use semantic line breaks and name the file after the issue number or the PR #.