docs/shell.md
This guide covers Pipenv's shell integration features, environment variable management, and best practices for configuring your development environment.
Pipenv provides robust shell integration that allows you to work within your project's virtual environment seamlessly.
To activate your project's virtual environment, use the shell command:
$ pipenv shell
This spawns a new shell subprocess with the virtual environment activated. You'll notice your shell prompt changes to indicate the active environment:
(project-a1b2c3) $
To exit the virtual environment and return to your normal shell, simply type:
$ exit
or press Ctrl+D.
Pipenv supports two shell activation modes:
To use fancy mode:
$ pipenv shell --fancy
If you don't want to activate the full shell, you can run individual commands within the virtual environment:
$ pipenv run python script.py
$ pipenv run pytest
This is particularly useful for one-off commands or in CI/CD pipelines.
Pipenv automatically loads environment variables from .env files in your project directory when you use pipenv shell or pipenv run. This feature helps you manage environment-specific configuration without hardcoding values in your code.
A typical .env file might look like this:
# .env
DEBUG=True
DATABASE_URL=postgresql://user:password@localhost/dbname
SECRET_KEY=your-secret-key-here
API_KEY=1234567890abcdef
When you run a command with Pipenv, these variables are automatically loaded:
$ pipenv run python
Loading .env environment variables...
Python 3.10.4 (default, Mar 23 2022, 17:29:05)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.environ['DEBUG']
'True'
>>> os.environ['DATABASE_URL']
'postgresql://user:password@localhost/dbname'
You can use variable expansion in your .env files using the ${VARNAME} syntax:
# .env
HOME_DIR=${HOME}
CONFIG_PATH=${HOME_DIR}/.config/myapp
LOG_DIR=${HOME_DIR}/logs
This allows you to define variables in terms of other variables, including system environment variables:
$ pipenv run python -c "import os; print(os.environ['CONFIG_PATH'])"
Loading .env environment variables...
/home/user/.config/myapp
If your .env file is located in a different path or has a different name, you can specify its location:
$ PIPENV_DOTENV_LOCATION=/path/to/custom/.env pipenv shell
Or set it permanently in your shell configuration:
# Add to ~/.bashrc or ~/.zshrc
export PIPENV_DOTENV_LOCATION=/path/to/custom/.env
In some cases, you might want to prevent Pipenv from loading .env files:
$ PIPENV_DONT_LOAD_ENV=1 pipenv shell
This is useful when you want to use system environment variables instead of those defined in the .env file.
Pipenv supports tab completion for commands, options, and arguments via argcomplete.
Shell completion is an optional feature. Install it alongside pipenv:
pip install "pipenv[completion]"
Or install argcomplete separately:
pip install argcomplete
Add the following line to your ~/.bashrc (or ~/.bash_profile on macOS):
eval "$(register-python-argcomplete pipenv)"
Then reload your shell:
source ~/.bashrc
Add to your ~/.zshrc:
autoload -U bashcompinit
bashcompinit
eval "$(register-python-argcomplete pipenv)"
Then reload:
source ~/.zshrc
register-python-argcomplete --shell fish pipenv | source
To make it permanent, add the line above to ~/.config/fish/config.fish.
If you use multiple tools that support argcomplete, you can activate completion for all of them in one step:
activate-global-python-argcomplete
This installs a shell hook that handles any package that calls
argcomplete.autocomplete().
After reloading your shell, type pipenv and press Tab — you should see the
list of available subcommands. Pressing Tab again after a partial subcommand
name (e.g. pipenv ins<Tab>) completes it to pipenv install.
Git Bash supports bash completion. Add to your ~/.bashrc (typically
C:\Users\<you>\.bashrc):
eval "$(register-python-argcomplete pipenv)"
Then restart Git Bash or run source ~/.bashrc.
In older versions of pipenv (before 2026.5.0), shell completion was powered by
Click and activated with the _PIPENV_COMPLETE environment variable:
# OLD method — no longer works in pipenv >= 2026.5.0
eval "$(_PIPENV_COMPLETE=bash_source pipenv)" # bash
eval "$(_PIPENV_COMPLETE=zsh_source pipenv)" # zsh
_PIPENV_COMPLETE=fish_source pipenv | source # fish
Starting with pipenv 2026.5.0, shell completion uses
argcomplete instead. Replace the
lines above with the register-python-argcomplete commands shown in the
Activation section and make sure the argcomplete package is
installed (pip install "pipenv[completion]").
If completion is not working:
Confirm argcomplete is installed in the same environment as pipenv:
pip show argcomplete
Verify the activation line is present in your shell startup file and that the file is being sourced for interactive sessions.
Restart your shell completely (not just source) if the hook was
recently added.
Check for errors by running the registration command directly:
register-python-argcomplete pipenv
It should print a shell function definition without errors.
If you see a migration message about _PIPENV_COMPLETE, you are using
the old activation method. See Migrating from pipenv < 2026.5.0
above.
A common issue with shell integration is improper PATH configuration. Many shell configurations add to the PATH in every subshell, which can cause problems with virtual environments.
The correct approach is to set environment variables like PATH only during login sessions, not in every subshell:
# ~/.config/fish/config.fish
if status --is-login
set -gx PATH /usr/local/bin $PATH
end
# ~/.bashrc or ~/.zshrc
if [[ -z $PIPENV_ACTIVE ]]; then
export PATH=/usr/local/bin:$PATH
fi
For different environments (development, staging, production), use separate .env files:
# Development
$ PIPENV_DOTENV_LOCATION=.env.development pipenv shell
# Staging
$ PIPENV_DOTENV_LOCATION=.env.staging pipenv shell
# Production
$ PIPENV_DOTENV_LOCATION=.env.production pipenv shell
Never commit .env files to version control. Add them to your .gitignore:
# .gitignore
.env
.env.*
Provide a template for required environment variables:
# .env.example (safe to commit)
DEBUG=
DATABASE_URL=
SECRET_KEY=
Use different variables for different environments to prevent accidental use of development settings in production.
You can define custom scripts in your Pipfile for common tasks:
[scripts]
start = "python app.py"
test = "pytest"
lint = "flake8 ."
Then run them with:
$ pipenv run start
$ pipenv run test
Some shells support hooks that can automatically activate virtual environments when entering a directory:
direnv is a tool that can automatically load/unload environment variables based on the current directory:
# .envrc
layout pipenv
This automatically activates the Pipenv environment when entering the directory.
For zsh users, zsh-autoenv can automatically activate/deactivate environments:
# .autoenv.zsh
pipenv shell
# .autoenv_leave.zsh
exit
If pipenv shell doesn't work correctly:
pipenv run as an alternative to shell activationIf environment variables aren't being loaded correctly:
.env file syntax for errorsSee the Troubleshooting section under Shell Completion above.
Pipenv uses python-dotenv internally to load .env files. For more advanced usage, you can use this library directly in your code:
# app.py
from dotenv import load_dotenv
import os
# Load .env file manually (Pipenv does this automatically)
load_dotenv()
# Access environment variables
debug = os.environ.get("DEBUG", "False") == "True"
database_url = os.environ["DATABASE_URL"]
This gives you more control over how environment variables are loaded and used in your application.
Pipenv's shell integration and environment variable management features provide a powerful way to manage your Python development environment. By understanding and using these features effectively, you can create a more productive and secure development workflow.
Remember to follow best practices for shell configuration and environment variable management to avoid common issues and ensure a smooth experience with Pipenv.