I had a brain fart today. I was developing a personal project in Python and I had some library issues that I was trying to wrap my head around. It turns out, I didn’t even have my virtual environment running. I completely forgot.
So then I activated it.
source .venv/bin/activate
Then I thought to myself…
I don’t want to type that out every single damn time.
I’m lazy. I don’t like to type unnecessary things. I switch projects mid-day on multiple occasions at work so there’s a bit of a context switch to deal with. If I have to write automation scripts and aliases now to prevent me from typing even the smallest of words, I’ll take the time to try to solve that.
Context issues
So I did just that. I set aside some time to try to automate things.
I wanted a command I could execute (venv
). This command would run a script that creates a virtual environment via python3 -m venv .venv
. Then it would run source .venv/bin/activate
to start the virtual environment.
Well, every time I ran this script, the directory would be created at the current working directory and the source
line ran without error but the virtual environment did not start. The Python interpreter my environment was running was still global at /usr/local/bin/python3
. So something is amiss!
After doing a bit of research it turns out that when you want to enter a virtual environment, the virtual environment modifies my shell’s variables. An example of this would be modifying my shell’s variables to point to the correct Python interpreter.
Also, when you run a Bash script, it executes in a different context/subshell. The file and directory changes stuck after the script ran, but the necessary variables I needed for my virtual environment were thrown away as soon as the script finished running.
Solution
I removed the source
line from my venv.sh
script and just left the script to create the needed files and directories. I would then need to run that source
command to enter the virtual environment.
Then I thought: Why don’t I just string the commands together into one alias on my shell? Perfect.
|
|
Running the venv
alias would execute the venv.sh
then run the source
command in the context of the shell I am currently in.
#!/bin/bash
# venv.sh
# create venv if not exists
if [ -d ".venv" ]; then
echo "Found .venv. Activating..."
else
read -p ".venv does not exist. Would you like to \
create a venv for this directory? (y/n) " response
if [ "$response" == "y" ]; then
echo "Creating .venv directory @ $PWD"
python3 -m venv .venv
fi
fi
If venv.sh
finds an existing .venv
directory, it does nothing. If the script does not find the .venv
directory it prompts the user asking if the script has permission to create it. I know I could probably do without the prompt and just have the script create it. I decided to leave it in for now.
I guess my issue was with Bash and not venv. Anyway, I think I have to be careful. I’ve been getting sidetracked and spending a lot of time configuring my environment. Off to building something!
Be sure to follow me @chrisparaiso.