devsetup1-5 Exercise 2: A Virtual Environment Is Disposable ============================================================ COMMANDS -------- mkdir -p ~/projects/disposable && cd ~/projects/disposable # BEFORE activation type -a python3 python3 -m venv .venv source .venv/bin/activate # DURING activation type -a python3 pip --version pip install requests pip freeze > requirements.txt cat requirements.txt deactivate # AFTER deactivation type -a python3 # Destroy the environment completely rm -rf .venv # Rebuild it from the list python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt python3 -c "import requests; print(requests.__version__)" deactivate WHAT type -a python3 REPORTS ---------------------------- Before: /usr/bin/python3 only. During: /home/you/projects/disposable/.venv/bin/python3 FIRST, then /usr/bin/python3. The shell runs the first one, which is the venv's. pip --version also reports a path inside .venv. After: back to /usr/bin/python3 only. This is the point of activation: it puts the environment's bin directory at the front of PATH, so "python3" and "pip" resolve to the venv's copies. It changes nothing about the system Python. WHAT requirements.txt LOOKS LIKE -------------------------------- certifi==... charset-normalizer==... idna==... requests==... urllib3==... pip freeze lists requests and everything it depends on, each pinned to the exact version installed. Your version numbers will differ. THE .gitignore -------------- Check for it: cat .venv/.gitignore Since Python 3.13, python3 -m venv creates a .gitignore inside the environment containing a single "*", so Git ignores the whole folder. You commit requirements.txt (the recipe), not .venv (the result). WHY THIS WORKS AS AN ANSWER --------------------------- Deleting and rebuilding the environment turns "a venv is disposable" from a claim into something you have watched happen. It also shows why the requirements file matters more than the environment itself.