Skip to content

Instantly share code, notes, and snippets.

@twidi
Last active April 10, 2023 06:24
Show Gist options
  • Save twidi/049c1eb6ed359d3e9e7f to your computer and use it in GitHub Desktop.
Save twidi/049c1eb6ed359d3e9e7f to your computer and use it in GitHub Desktop.
Pycharm and virtualenvwrapper, with postactivate

The problem

PyCharm has support for virtual environment.

But there are two problems:

  1. the virtual environment is not activated in the terminal (it is only in the python console)
  2. it doesn't support virtualenvwrapper and so doesn't run the postactivate file.

This gist is the solution I found to resolve these two problems.

The solution explained

To make this work, the simplest solution I found was to create a file .venv in a directory with the name of the virtualenv to auto-activate inside. Then, when you will be in this directory, or any sub-directory, by invoking the commands explained below, the virtualenv will be auto-activated. This works with PyCharm because when it calls bash for the terminal or python for the python-console, it uses the PyCharm project directory as current working directory/

The solution is based on calling bash with a rc-file that will find the .venv file, read it, and activate the virtualenv based on the name just read (This rc-file will also check for a VENV environment variable, or will be able to find the venv if the current directory is a subdirectory of a venv directory)

For bash it's something like

/bin/bash --rcfile /path/to/rcfile

For python it's the same, we just tell bash to run the python command:

/bin/bash --rcfile /path/to/rcfile --ci python [args for python]

As the virtualenv will be set by the rcfile, we are sure that the python will be the one of the virtualenv.

This gist include a script to call for python instead of this whole line.

The files

Start by copying the others file in this Gist:

  • .bashrc-autovenv in ~/
  • python-autovenv in ~/bin/

Then make the python files executable:

chmod +x ~/bin/python-autovenv

Configure your project

Start by creating a .venv file in your PyCharm project directory (ie the same directory that holds the .idea directory), and simple add the name of the virtualenv on the first line (nothing else on the first line, it's important)

Now we can configure PyCharm.

What's magic here is that we can do this "by default" for all our PyCharm python project, because it relies on this .venv file and if not found, it will simply work without activating any virtualenv. Now we can adapt a pycharm project for which you want your virtualenv activated everywhere, with its postactivate script executed.

We'll have to change two default settings in PyCharm:

Changing the python console interpreter

By default, PyCharm use the python binary from your virtualenv. It allows to work with default virtualenv, with the correct path for modules, but it's not enough to execute the postactivate file.

Open File > Default settings then go to Default project > Project interpreter.

On the Project interpreter line, click on the icon on the right, then Add local, and enter ~/bin/python-autovenv then click OK.

Now you'll want to select this python-autovenv interpreter for the default python console. Open File > Default settings then Build, Execution, Deployment > Console > Python console and in the Python interpreter field, select the one with python-autovenv in it.

When done, you may want to check for each of your python project if it's the correct one, and set it the same way if not (idem for Django console)

Changing the shell to use in the terminal

By default, PyCharm use /bin/bash to open a new terminal. This doesn't activate your virtualenv. You man want it to be activated and your postactivate file execute.

Open File > Default settings then go to Tools > Terminal.

In the Shell path field, enter /bin/bash --rcfile ~/.bashrc-autovenv

Then in PyCharm, you can open a new terminal, it will work as expected.

You may want to restart PyCharm one these settings are changed.

Final words

It may not be the better way to do this, I'm not at all a bash ninja, and there is a little overhead for python as instead of running python directly, we launch a script in bash that will launch another instance of bash. But It works for me, and I'm happy.

This trick allows two little things not mentioned above:

  • for a django project using environment variable in configurations, needed for the settings file to work, it now works and the PyCharm python console is now able to run it for django.
  • you can use this outside of PyCharm, by calling python-autovenv instead of python and it will run in your virtualenv, assuming you have in the directory (or a parent one), a .venv file.
PWD=`pwd`
source ~/.bashrc
# Do nothing more if venv already activated
if [ ! "$VIRTUAL_ENV" ]
then
# If $VENV not defined try to guess it
if [ ! "$VENV" ]
then
# Check if we are in a venv folder
if [ "$WORKON_HOME" ]
then
if [[ $PWD = $WORKON_HOME/* ]]
then
VENV=`echo "$PWD" | sed -e "s|^$WORKON_HOME/\([^/]\+\)\(/.*\)\?$|\1|"`
fi
fi
# Still no venv, search for a .venv file
if [ ! "$VENV" ]
then
CUR_DIR="$PWD"
while [ "$CUR_DIR" != "/" ]
do
VENV_FILE="$CUR_DIR/.venv"
if [ -e "$VENV_FILE" ]
then
read -r VENV < "$VENV_FILE"
if [ "$VENV" ]
then
break
fi
fi
CUR_DIR=`dirname "$CUR_DIR"`
done
fi
fi
if [ "$VENV" ]
then
workon "$VENV"
else
echo "No VENV env var defined, path not in WORKON_HONE and no valid `.venv` file found!"
fi
fi
cd "$PWD"
#!/bin/bash
ARGS=''
for i in "$@"
do
ARGS="$ARGS \"${i//\"/\\\"}\""
done
COMMAND="python $ARGS"
if [ "$VIRTUAL_ENV" ]
then
$COMMAND
else
/bin/bash --rcfile ~/.bashrc-autovenv -ci "$COMMAND"
fi
@nikoladang
Copy link

@sandervalcke Can you explain more detail about your solution?

@zborowa
Copy link

zborowa commented Feb 10, 2016

@nikoladang I don't see any explanation from Sander so let me simply explain it. Start a terminal -> activate your virtuelenv (for me it would be 'workon projecta') -> 'open -a Pycharm' (again in my situation I have created a Command-line Launcher through PyCharms tools menu so I just activate that). By starting PyCharm through the correct environment, it will use your virtuelenv settings and not your system settings.

@vinnyricciardi
Copy link

@zborowa Your solution worked for me! thanks for the easy work around

@Vadorequest
Copy link

Vadorequest commented Nov 24, 2017

If the goal is to have the virtualenv loaded in PyCharm Terminal, then I've got a most straight-forward solution:

Put this into your .bashrc/.zshrc file.

# Load virtualenvwrapper commands and enables default env
source /etc/bash_completion.d/virtualenvwrapper
export WORKON_HOME=~/virtualenvs # Optionnal
workon your-venv-name

Then, configure PyCharm for using the right shell. Or just change your OS default shell (zsh for me)

But this doesn't fix my current issue, which is Webstorm not finding the package requirements. But I don't think the solution proposed here does either.

@raulqf
Copy link

raulqf commented Feb 16, 2018

What do you mean with pycharm is not supporting virtualenvwrapper? By setting correctly the project interpreter, pycharm works flawlessly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment