Skip to content

Shell’s Awareness of Workspace Python `.

Source: Notion | Last edited: 2025-05-07 | ID: 1ea2d2dc-3ef...


This project uses Cursor IDE’s built-in virtual environment management capabilities for a simple, IDE-centric approach.

The setup uses:

  1. Cursor IDE’s .venv virtual environment creation
  2. Shell configuration that automatically detects and activates the environment
  3. Shell’s built-in Docker container detection

1. Cursor IDE Virtual Environment Management

Section titled “1. Cursor IDE Virtual Environment Management”

Cursor IDE automatically creates and manages a virtual environment in the .venv directory in each project workspace. This is the standard location for Python virtual environments and is compatible with most Python tools.

2. Automatic Environment Detection and Activation

Section titled “2. Automatic Environment Detection and Activation”

The shell configuration (both zsh and bash) automatically detects when you’re in a directory (or subdirectory) with a .venv folder and activates that environment:

Terminal window
# Python Virtual Environment Management
# Prioritizes Cursor IDE's .venv directory, falls back to pyenv if needed
# Function to detect and activate the appropriate Python virtual environment
activate_python_env() {
# Skip if we're in a Docker container
if [ -f /.dockerenv ]; then
return
fi
# Check for Cursor IDE .venv in current directory or parent directories
local dir="$PWD"
local max_depth=5 # Limit search to 5 parent directories
local depth=0
while [ "$dir" != "/" ] && [ $depth -lt $max_depth ]; do
if [ -d "$dir/.venv" ] && [ -f "$dir/.venv/bin/activate" ]; then
# Deactivate any active virtual environment first
if [ -n "$VIRTUAL_ENV" ]; then
deactivate 2>/dev/null || true
fi
# Activate Cursor IDE's virtual environment
source "$dir/.venv/bin/activate"
return
fi
dir=$(dirname "$dir")
((depth++))
done
# If we haven't found a Cursor IDE venv and pyenv is available, use it
if command -v pyenv >/dev/null 2>&1; then
# Only if not already handled by pyenv (checking for PYENV_VERSION or .python-version)
if [ -z "$PYENV_VERSION" ] && [ ! -f "$PWD/.python-version" ]; then
eval "$(pyenv init --path)" >/dev/null 2>&1
eval "$(pyenv init -)" >/dev/null 2>&1
fi
fi
}
# Keep pyenv in PATH for compatibility
export PYENV_ROOT="$HOME/.pyenv"
case ":$PATH:" in
*":$PYENV_ROOT/bin:"*) ;; # PATH already contains pyenv, do nothing
*) export PATH="$PYENV_ROOT/bin:$PATH" ;; # Add pyenv to beginning of PATH
esac
# Run the function each time the directory changes
autoload -U add-zsh-hook
add-zsh-hook chpwd activate_python_env
# Run once at shell startup
activate_python_env

This ensures that the correct Python environment is always available in your terminal when working in a project directory.

The shell configuration automatically detects when you’re inside a Docker container and avoids activating local environments in that case:

Terminal window
# Skip if we're in a Docker container
if [ -f /.dockerenv ]; then
return
fi

This ensures that inside containers, you use the container’s Python environment as expected.

The example above shows the configuration for Zsh, which uses add-zsh-hook to trigger the activation function when changing directories. For Bash, a different approach is needed since it lacks a native directory change hook. Below are the key differences between the actual implementations:

Terminal window
# Run the function each time the directory changes
autoload -U add-zsh-hook
add-zsh-hook chpwd activate_python_env
# Run once at shell startup
activate_python_env
Terminal window
# Run when changing directory in Bash
cd() {
builtin cd "$@" || return
activate_python_env
}
# Run once at shell startup
activate_python_env

The key difference is that:

  • Zsh uses a built-in hook system (chpwd) that automatically runs when the directory changes
  • Bash overrides the cd command to run our activation function after changing directories
  • Both run the activation function once at shell startup to handle the initial directory This implementation difference reflects the fundamental capabilities of each shell while achieving the same end result - automatic virtual environment activation when navigating around your project.
  1. In Cursor IDE, create a virtual environment for your project:
  • Assume requirements.txt exist in in the workspace and/or pyproject.toml in the project root directory
  • Open Command Palette (Cmd+Shift+P)
  • Select “Python - Select Interpreter” > “Create Virtual Environment…”
  • Select “Venv” and then choose either “Use Existing” or “Delete and Recreate” if there’s existing .venv directory before selecting the desired Python interpreter.
    • pyenv managed ones are easy to be configured in one’s own user directory
  1. Cursor IDE will create a .venv directory in your project root directory.
  2. When you open a terminal in Cursor IDE, your shell will automatically detect and activate the environment.
  • IDE-centric workflow - Cursor IDE manages the environment
  • Automatic activation in terminals - No manual commands needed
  • Simple .venv directory structure - Standard and compatible with tools
  • Works with Docker - Environments are disabled in containers
  • Clean, simple configuration that “just works”
  • If your environment isn’t activating, check that the .venv directory exists in your project
  • Ensure that you have the latest shell configuration from this repo
  • Try changing directories (cd .) to trigger the activation hook
  • In some cases, you may need to restart your terminal or shell