I have a written a makefile to use to run Python code. The idea is it will allow me to run my linter, pytest, and run the code all in one command. Importantly, it will also spin up a python environment to use.
An excerpt of it looks like:
VENV := venv
all: venv
$(VENV)/bin/activate: requirements.txt
python3 -m venv $(VENV)
./$(VENV)/bin/pip install -r requirements.txt
# venv is a shortcut target
venv: $(VENV)/bin/activate
run: venv
flake8 --exclude=venv
pytest --ignore=venv
mypy advent_of_code/dayone.py
python advent_of_code/dayone.py
The rest of the code is found here: https://github.com/andrewblance/advent_of_code_2020
However, when I run my code I do not think it is using this environment. I think it still uses my default python environment. When I run this code I can see the version of Pytest and mypy that is being used depends on what is installed on the default python environment.
Have I done something wrong that means when I run flake & etc that I don't use the new environment? How can I change it so it only uses the environment specified in the makefile, and how do I "turn off" the environment once I am done with it?
Short: you can't.
Longer: every process has its own environment. Its environment is inherited from the process that started it. But, it's impossible for a child process to modify or change the environment of its parent.
Every command is a process. So the make program is a process, and each command line that make invokes is a process. So when you run the command python3 -m venv $(VENV) that starts a shell process, which runs python3 -m venv ... which is another process. Then whatever change to the environment python3 made is lost when python3 exits, and whatever change to the environment was made in the shell that started python3 is lost when the shell exits, and then other shells are started with other commands, and when all the commands are done make will exit and any changes made to its environment are lost when you get back to your shell prompt.
Related
I want to write a first_setup.py script, where users can run it for the first time and the script will do the entire setup automatically, namely it will create a virtual environment, activate it, and install the requirements with pip. Users can then start to use the program without worrying about any dependency issue.
Therefore, I used venv together with subprocess library. My Python version is 3.7.5. With the following command, it creates the virtual environment in the working directory:
env_name = ".venv"
subprocess.run(["python", "-m", "venv", env_name])
However, activation doesn't work. I tried to activate it in various ways, for example:
subprocess.run([f"{venv_name}\\Scripts\\Activate.ps1"], shell=True)
This just opens Activate.ps1 in Windows Text Editor like a .txt file (?). I also thought to add .../Scripts/python.exe to the PATH variable, but it didn't work actually.
Furthermore, when the venv created by the script, VS Code pops up a message saying a venv detected, do you want to use it? If I click on Yes, then it changes my interpreter to venv, which is exactly what I want to do, but automatically with the first_setup.py script.
How can I proceed?
Does this first_setup script need to be Python?
The problem is that the activate script sets environment variables for the shell, which is why it’s usually run with ‘source’.
try using bash file:
python3 -m venv venv
source venv/bin/activate
pip install your_library
When I first install packages to a virtual environment with pipenv install package and secondly try to open a subshell to operate in that environment with pipenv shell i receive the following:
"Shell for UNKNOWN_VIRTUAL_ENVIRONMENT already activated.
No action taken to avoid nested environments."
However, which python returns the file path of the system python, which indicated that actually the virtual environment is not activated.
ctr+D and recalling pipenv shell finally opens a subshell within the virtual environment. Can someone explain me what's going on there? Honestly, I am severely conufused.
just cd to the folder that has your venv (.venv, Pipfile, Pipfile.lock) and run exit.
it will exit the folder and now you can again cd to the same folder and use pipenv shell.
it will work
Exit the shell using exit and NOT deactivate.
As explained here, "deactivate will leave pipenv in a confused state because you will still be in that spawned shell instance but not in an activated virtualenv."
Once you exit properly, you can navigate back to the directory and use pipenv shell
I am new in PyCharm, I use the 2019 CE version.
I have set an environment variable in venv/bin/activate:
# User defined variables:
export DATABASE="postgresql://postgres:postgres#localhost:5432/postgres"
And I can access it using bash:
$ source venv/bin/activate
(venv) $ echo $DATABASE
postgresql://postgres:postgres#localhost:5432/postgres
And when running my script in this environment, it works as expected:
(venv) $ python3 newproject/settings.py
{'database': 'postgresql://postgres:postgres#localhost:5432/postgres'}
It is also automatically done for PyCharm Terminal that natively activates the environment, but I could not succeed in setting it when I run a script.
Anyway, when I specify a Run Configuration to execute a script that needs to access this environment variable, the environment is not loaded automatically before running the script. I have searched almost everywhere, the logical place should be there:
I have found no option (or documentation) to enable virtualenv before running a script. I even tried to add an external tool to manually activate it before it runs the script. But it is useless since executed environments are disjoint: the script does not run in the same environment that venv.
Looking at the python interpreter it seems it is the correct environment.
I know that I can set Environment Variable in this peculiar setup form, but then variables are no longer available when I run the virtual environment, so it is not a solution to me.
My question is then: How can I setup a Run Configuration that activate my environment and run the script within this environment?
I use python-mode.el and have just discovered Pipenv. I can start Python within a project environment from a terminal by first changing to the project directory and entering "pipenv run python". But python-mode wants to execute a process, not a command string.
I tried creating a shell script like this:
#!/bin/bash
cd ~/myprojectdir
pipenv run python
but got this complaint
Warning: the environment variable LANG is not set!
We recommend setting this in ~/.profile (or equivalent) for proper expected behavior.
This variable is set in my terminal environment: how do i ensure it's set for pipenv? But the bigger question is, how do i run this pipenv virtual environment python inside emacs to get a buffer with a Python process?
pipenv.el helps here, by setting the appropriate variables and providing a porcelain around Pipenv inside Emacs.
Looks like i have to explicitly source my .bashrc file (or equivalent). Changing the contents of my runpipenv.sh script to this
#!/bin/bash
source ~/.bashrc
cd ~/myprojectdir
pipenv run python
(where my .bashrc file sets LANG) and then calling
(setq py-shell-name "runpipenv.sh")
in Emacs seems to work.
If one defines which version of python to use in a bash script, it would be
export PYTHON = "/path/python/python-3.5.1/bin/python"
But for Python virtualenv's, one executes these commands in the command line
cd /path/pathto/virtualenv
source activate
cd another_directory
How does one "enter" a Python virtualenv in a bash script? What is the standard approach here?
We have to distinguish two cases here:
You want to use/call python (or python-based tools) in your bash script, but python or those tools should be taken from and run in a virtualenv
You want a script that, amongst other things, lets the shell from which you call it enter the virtualenv, so that you can interactively call python (or python-based tools) inside the virtualenv
Case 1: Using a virtualenv inside a script
How does one "enter" a Python virtualenv in a bash script?
Just like on the interactive bash command line:
source /path/to/the/virtual_env/bin/activate
What is the standard approach here?
The standard approach is not to enter the virtualenv in a bash script. Instead, call python and/or the python-based commands you want to use by their full path. To make this easier and less repetitive, you can use aliases and variables.
Case 2: Activating a virtualenv in an interactive bash session by calling a script
There already is such a script. It's called activate and it's located in the bin directory of the virtualenv. You have to source it rather than calling it like a normal command. Only then will it run in the same session instead of in a subshell, and thus only then can it make modifications to the session that won't be lost due to the subshell terminating at the end of the script.
So just do:
source /path/to/the/virtual_env/bin/activate
in your interactive shell session.
But what if you want to do more than the activate script does? You can put
source /path/to/the/virtual_env/bin/activate
into a shell script. But, due to the reason mentioned above, it won't have much effect when you call your script normally. Instead, source your script to use it from an interactive session.
Thus:
Content of my_activate.sh
#!/bin/bash
# Do something
# ...
# then
source /path/to/the/virtual_env/bin/activate
# Do more stuff
# ...
and in your interactive session
source my_activate.sh
I recommend using virtualenvwrapper. It provides some useful tools for managing your virtual environments.
pip install --user virtualenvwrapper
When you create the virtual environment, you specify which version of python should be used in the environment.
mkvirtualenv -p /usr/local/bin/python2.6 myproject.2.6
mkvirtualenv -p /usr/local/bin/python3.3 myproject.3.3
Then, "enter" the environment with the workon command.
workon myproject.2.6
Here are few steps to follow, one thing you can do is
export PYTHON = "/path/pathto/virtualenv/python"
Use this path in bashrc to use. Or you can do something like:-
vim ~/.bashrc
Go to end and set
alias python=/path/pathto/virtualenv/python
source ~/.bashrc