pyvenv-activate.sh
is a POSIX shell script containing functions to manually
or automatically activate and deactivate the Python virtual environment of
projects within the current shell.
It currently supports Pipenv, Poetry, and manual virtual environment projects.
Unlike pipenv shell
or poetry shell
, the virtual environment is directly
loaded in the current Shell environment and thus it doe not start a new
sub-shell when the virtual environment is activated.
For Pipenv projects, similarly to
pipenv run
or pipenv shell
, when a .env
is present, it is loaded when
the virtual environment is activated.
Of course, in order to load the different environments, Pipenv or Poetry must be installed first.
- Load the virtual environment within the current shell
- Simple functions for virtual environment activation/deactivation
- Automatic virtual environment activation/deactivation when entering or exiting a Python virtual environment project
- For Pipenv projects:
- Automatically load
.env
file - Respect Pipenv configuration environment variables
(
PIPENV_MAX_DEPTH
,PIPENV_DOTENV_LOCATION
, ...)
- Automatically load
- Works with every POSIX shells (bash, zsh, ksh, ...)
pyvenv-activate
can be used as a plugin for shells that support plugin
managers.
zplug "Intersec/pipenv-activate"
pyvenv_auto_activate_enable # Optional, enable auto activate, see below
antigen bundle "Intersec/pipenv-activate"
pyvenv_auto_activate_enable # Optional, enable auto activate, see below
zgen load "Intersec/pipenv-activate"
pyvenv_auto_activate_enable # Optional, enable auto activate, see below
Copy this repository to $ZSH_CUSTOM/plugins
, where $ZSH_CUSTOM
is the directory with custom plugins of oh-my-zsh (read more):
git clone "https://github.com/Intersec/pipenv-activate.git" "$ZSH_CUSTOM/plugins/pyvenv-activate"
Then, add pyvenv-activate
to the list of plugins in your .zshrc
.
Make sure you insert it before the line source $ZSH/oh-my-zsh.sh
:
plugins=(... pyvenv-activate)
To enable automatic activation, add this line after the line
source $ZSH/oh-my-zsh.sh
:
pyvenv_auto_activate_enable # Optional, enable auto activate, see below
Copy this repository to $OSH_CUSTOM/plugins
, where $OSH_CUSTOM
is the directory with custom plugins of oh-my-bash (read more):
git clone "https://github.com/Intersec/pipenv-activate.git" "$OSH_CUSTOM/plugins/pyvenv-activate"
Then, add pyvenv-activate
to the list of plugins in your .bashrc
.
Make sure you insert it before the line source $OSH/oh-my-bash.sh
:
plugins=(... pyvenv-activate)
To enable automatic activation, add this line after the line
source $ZSH/oh-my-bash.sh
:
pyvenv_auto_activate_enable # Optional, enable auto activate, see below
pyvenvactivate.sh
can be sourced directly without any dependency.
First, clone the repository:
mkdir -p "$HOME/.sh-plugins"
git clone "https://github.com/Intersec/pipenv-activate.git" "$HOME/.sh-plugins/pyvenv-activate"
Next, you need to source pyvenv-activate.sh
in the interactive
configuration file for your shell (.bashrc
for bash, .zshrc
for zsh, ...):
. $HOME/.sh-plugins/pyvenv-activate/pyvenv-activate.sh
pyvenv_auto_activate_enable # Optional, enable auto activate, see below
The virtual environment of a Python environment project can be activated in
the current shell manually with the function pyvenv_activate
.
This works the same way as running pipenv shell
, but no sub-shells are
created.
To deactivate the virtual environment, you need to run pyvenv_deactivate
.
Example:
pauss@home: envs$ . ~/dev/pyvenv-activate/pyvenv-activate.sh
pauss@home: envs$ python --version
Python 2.7.18rc1
pauss@home: envs$ which python
/usr/bin/python
pauss@home: envs$ cd A
pauss@home: envs/A$ python --version
Python 2.7.18rc1
pauss@home: envs/A$ which python
/usr/bin/python
pauss@home: envs/A$ pyvenv_activate
(A) pauss@home: envs/A$ python --version
Python 3.8.2
(A) pauss@home: envs/A$ which python
/home/pauss/.local/share/virtualenvs/A-1baQ-YWx/bin/python
(A) pauss@home: envs/A$ python -c 'import six; print(six.__version__)'
1.15.0
(A) pauss@home: envs/A$ cd ..
(A) pauss@home: envs$ python --version
Python 3.8.2
(A) pauss@home: envs$ which python
/home/pauss/.local/share/virtualenvs/A-1baQ-YWx/bin/python
(A) pauss@home: envs$ pyvenv_deactivate
pauss@home: envs$ python --version
Python 2.7.18rc1
pauss@home: envs$ which python
/usr/bin/python
pauss@home: envs$ cd B
pauss@home: envs/B$ pyvenv_activate
(B) pauss@home: envs/B$ python --version
Python 3.8.2
(B) pauss@home: envs/B$ which python
/home/pauss/.local/share/virtualenvs/B-XFzaNdvP/bin/python
(B) pauss@home: envs/B$ python -c 'import six; print(six.__version__)'
Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'six'
(B) pauss@home:(1) envs/B$ cd ../C
(B) pauss@home: envs/C$ pyvenv_deactivate
pauss@home: envs/C$ echo $VAR_A
pauss@home: envs/C$ pyvenv_activate
(C) pauss@home: envs/C$ echo $VAR_A
foo
(C) pauss@home: envs/C$ pyvenv_deactivate
pauss@home: envs/C$ echo $VAR_A
pauss@home: envs/C$
pyvenv-activate
can also be used to automatically activate and deactivate
the virtual environment when entering or exiting a Python virtual environment
project.
In order to enable it, you need to call the function
pyvenv_auto_activate_enable
in the interactive configuration file of your
shell (.bashrc
for bash, .zshrc
for zsh, ...).
It is possible to disable this mechanism by calling
pyvenv_auto_activate_disable
.
Example:
pauss@home: envs$ . ~/dev/pyvenv-activate/pyvenv-activate.sh
pauss@home: envs$ pyvenv_auto_activate_enable
pauss@home: envs$ python --version
Python 2.7.18rc1
pauss@home: envs$ which python
/usr/bin/python
pauss@home: envs$ cd A
(A) pauss@home: envs/A$ python --version
Python 3.8.2
(A) pauss@home: envs/A$ which python
/home/pauss/.local/share/virtualenvs/A-1baQ-YWx/bin/python
(A) pauss@home: envs/A$ python -c 'import six; print(six.__version__)'
1.15.0
(A) pauss@home: envs/A$ cd ..
pauss@home: envs$ python --version
Python 2.7.18rc1
pauss@home: envs$ which python
/usr/bin/python
pauss@home: envs$ cd B
(B) pauss@home: envs/B$ python --version
Python 3.8.2
(B) pauss@home: envs/B$ which python
/home/pauss/.local/share/virtualenvs/B-XFzaNdvP/bin/python
(B) pauss@home: envs/B$ python -c 'import six; print(six.__version__)'
Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'six'
(B) pauss@home:(1) envs/B$ cd ..
pauss@home: envs$ echo $VAR_A
pauss@home: envs$ cd C
(C) pauss@home: envs/C$ echo $VAR_A
foo
(C) pauss@home: envs/C$ cd ..
pauss@home: envs$ echo $VAR_A
pauss@home: envs$
For Bash and Zsh, by default, we check if we have entered or exited a Python virtual environment project on each prompt.
This is useful because it covers the case when when we change from one directory to another, and when we create a new Python virtual environment project.
Checking if we are in a Python virtual environment project is pretty fast, so checking this on every prompt is usually not an issue.
For other POSIX shells, unfortunately, we don't have a hook that can be run on
every prompt.
So, in order to still have access to automatic activation, we redefine the
command cd
to check the Python virtual environment project we change from
one directory to another.
If you don't want to check the Python virtual environment project on every
prompt for Bash and Zsh, and only do the check when we change from one
directory to another, pyvenv_auto_activate_enable
actually takes an optional
argument which is the mode to use.
It can take three different values:
prompt
: Check the Python virtual environment project on every prompt. This is the default for Bash and Zsh. It is not available for other POSIX shells.chpwd
: Check the Python virtual environment project we change from one directory to another. This is the default for POSIX shells other than Bash and Zsh.default
: Use the best mode for the current shell.
Example:
pyvenv_auto_activate_enable chpwd
It is possible to use pyvenv-activate
with projects that use
venv or
virtualenv.
In order to work, pyvenv-activate
needs to know where to find the virtual
environment directory.
This is done by creating a special file .pyvenv_venv_path
in the project
directory using the function pyvenv_setup_venv_file_path
.
pyvenv_setup_venv_file_path
takes two optional arguments:
venv_path
: The path to the virtual env to register. If not set,$VIRTUAL_ENV
is used.proj_path
: The path to the project where to store the virtual environment path file. If not set, use the current directory.
Example:
pauss@home: envs/B$ virtualenv .venv
created virtual environment CPython3.8.2.final.0-64 in 165ms
creator CPython3Posix(dest=/tmp/test_pyvenv_path/B/.env, clear=False, no_vcs_ignore=False, global=False)
seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/pauss/.local/share/virtualenv)
added seed packages: pip==21.0.1, setuptools==57.0.0, wheel==0.36.2
activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator
pauss@home: envs/B$ pyvenv_setup_venv_file_path .venv
pauss@home: envs/B$ ls -a
. .. .pyvenv_venv_path .venv
pauss@home: envs/B$ pyvenv_activate
(.venv) pauss@home: envs/B$ which python
/home/pauss/envs/B/.venv/bin/python
The first version of pyvenv-activate
only supported pipenv
and was called
pipenv-activate
.
In order to keep backward compatibility, the public functions are kept, and some symlinks to the new files are created.
We use the unit test framework shUnit2.
First, you need to initialize, and potentially update, the git submodules:
git submodule update --init --recursive
Each test ./test/*_test.sh
can be run individually, but it is also possible
to run all tests for all shells supported by
shUnit2 on your platform by running the
script ./tests/run_all_tests
.
The tests are run on the following shells when available: