# Always Use Python Virtual Environments

**Category**: Python, Best Practices, Development Environment
**Use Case**: Any Python project development

## Why Virtual Environments

Python virtual environments (`venv`) are **essential** for development. They prevent dependency conflicts and keep your system Python clean.

## The Problem

Without virtual environments:
- ❌ System-wide package installations can conflict
- ❌ Different projects may require different package versions
- ❌ Your system Python can become cluttered and broken
- ❌ Other developers can't easily replicate your environment
- ❌ macOS and many Linux distros now protect system Python (PEP 668)

## The Solution

**Always create a virtual environment for every Python project:**

```bash
# Create virtual environment (one time setup)
python3 -m venv .venv

# Activate it (every time you work on the project)
source .venv/bin/activate  # macOS/Linux
.venv\\Scripts\\activate    # Windows

# Install dependencies
pip install -r requirements.txt

# When done
deactivate
```

## Best Practices

### 1. Use `.venv` as the directory name

Why `.venv`:
- ✅ Starts with `.` so it's hidden in file listings
- ✅ Standardized name everyone recognizes
- ✅ Already in most .gitignore templates
- ✅ Easy to remember and type

```bash
# Always use this name
python3 -m venv .venv
```

### 2. Always gitignore virtual environments

Add to `.gitignore`:
```gitignore
# Virtual environments
venv/
.venv/
env/
.env/  # Note: Be careful - this might also be for .env config files
```

### 3. Use requirements.txt

Track dependencies for reproducibility:

```bash
# Create/update requirements.txt
pip freeze > requirements.txt

# Or manually maintain it
cat > requirements.txt <<EOF
click>=8.1.0
rich>=13.0.0
EOF

# Install from requirements.txt
pip install -r requirements.txt
```

### 4. Activate before every work session

Create a habit:

```bash
# Start of work session
cd my-project
source .venv/bin/activate

# Your terminal should show (.venv) prefix
(.venv) $ python --version
(.venv) $ which python  # Should point to .venv/bin/python
```

### 5. Document setup in README

Always include virtual environment setup instructions:

```markdown
## Setup

1. Create virtual environment:
   \`\`\`bash
   python3 -m venv .venv
   \`\`\`

2. Activate virtual environment:
   \`\`\`bash
   source .venv/bin/activate  # macOS/Linux
   .venv\\Scripts\\activate    # Windows
   \`\`\`

3. Install dependencies:
   \`\`\`bash
   pip install -r requirements.txt
   \`\`\`
```

## Common Mistakes

### ❌ Installing packages globally

```bash
# DON'T DO THIS
pip install click
python3 -m pip install --user rich

# This will fail on modern macOS/Linux with:
# error: externally-managed-environment
```

### ✅ Installing in virtual environment

```bash
# DO THIS
python3 -m venv .venv
source .venv/bin/activate
pip install click rich
```

### ❌ Forgetting to activate

```bash
# If you see this, you forgot to activate:
$ python my_script.py
ModuleNotFoundError: No module named 'click'

# Solution: activate first
$ source .venv/bin/activate
(.venv) $ python my_script.py  # Now it works
```

### ❌ Committing .venv/ to git

```bash
# This bloats your repository (100+ MB)
git add .venv/  # DON'T DO THIS

# Make sure it's in .gitignore
echo ".venv/" >> .gitignore
```

## IDE Integration

### VS Code

VS Code auto-detects `.venv` and offers to use it:

1. Open project in VS Code
2. CMD+Shift+P → "Python: Select Interpreter"
3. Choose `.venv/bin/python`

Or add to `.vscode/settings.json`:
```json
{
  "python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python"
}
```

### PyCharm

PyCharm automatically detects and uses `.venv`:

1. File → Settings → Project → Python Interpreter
2. Click gear icon → Add
3. Select "Virtualenv Environment" → "Existing environment"
4. Choose `.venv/bin/python`

## Troubleshooting

### "Command not found: python"

Use `python3` instead:
```bash
python3 -m venv .venv
```

### "No module named 'venv'"

Install Python's venv module:
```bash
# Ubuntu/Debian
sudo apt install python3-venv

# Fedora/RHEL
sudo dnf install python3-venv
```

### Activating doesn't work

Make sure you `source` it (not just execute):
```bash
# Wrong
./venv/bin/activate

# Correct
source .venv/bin/activate
```

## Quick Reference

```bash
# Create
python3 -m venv .venv

# Activate
source .venv/bin/activate  # macOS/Linux
.venv\\Scripts\\activate    # Windows

# Install dependencies
pip install -r requirements.txt

# Save dependencies
pip freeze > requirements.txt

# Deactivate
deactivate

# Delete (if needed)
rm -rf .venv
```

## Real-World Example

This repository's `persuade` CLI uses a virtual environment:

```bash
# Setup (one time)
python3 -m venv .venv
source .venv/bin/activate
pip install persuade

# Daily use
source .venv/bin/activate
persuade sync ~/projects/my-app
deactivate
```

## Key Takeaway

**Never use system Python for development.**
**Always create a `.venv` for every project.**
**Always activate it before working.**

This is not optional - it's a fundamental best practice that prevents countless headaches and keeps your development environment clean and reproducible.
