Cheatsheets — vue longue
retour à la listeToutes les pages concaténées sur un seul document, pour un Ctrl-F direct.
pyenv
page dédiée →Gère des versions de Python, pas des paquets. Fonctionne par shims : de faux
exécutables placés très tôt dans le PATH, qui redirigent vers la version active.
Voir et installer
pyenv versions # installées, l'active marquée d'une étoile
pyenv version # l'active ICI, et qui l'a décidée
pyenv install --list | rg "^\s*3\.12"
pyenv install 3.12.9
pyenv version
3.12.9 (set by /Users/edouard/code/mon-projet/.python-version)
La deuxième partie est la plus utile : elle dit quel fichier impose la version.
Choisir une version
pyenv global 3.12.9 # défaut de la machine -> ~/.pyenv/version
pyenv local 3.12.9 # ce dossier -> ./.python-version
pyenv shell 3.12.9 # ce shell seulement -> $PYENV_VERSION
pyenv local --unset
Ordre de priorité : shell > local > global.
Environnements nommés (plugin pyenv-virtualenv)
pyenv virtualenv 3.12.9 mon-env # -> ~/.pyenv/versions/3.12.9/envs/mon-env
pyenv local mon-env # activation automatique en entrant dans le dossier
pyenv activate mon-env
pyenv deactivate
pyenv virtualenv-delete mon-env
Ils vivent dans ~/.pyenv/versions/, pas dans le projet. C'est la différence de fond
avec un .venv local.
venv standard, sans le plugin
pyenv local 3.12.9
python -m venv .venv
source .venv/bin/activate
pip install httpx pydantic
pip freeze > requirements.txt
deactivate
Les deux pièges qui coûtent des minutes
Le shim répond à la place du venv. Un paquet installé dans le venv, et pourtant la commande résolue est celle de pyenv :
which uvicorn
/Users/edouard/.pyenv/versions/lewagon/bin/uvicorn
Contournement immédiat : python -m uvicorn main:app passe par le Python courant et ignore
le PATH. Sinon hash -r (zsh : rehash) vide le cache de commandes du shell.
La commande existe ailleurs. Message classique :
pyenv: jupyter: command not found
The `jupyter' command exists in these Python versions:
3.12.9/envs/lewagon
3.10.6/envs/taxifare-env
Le shim cherche dans la version active, qui n'a pas le paquet. Soit on active le bon
environnement, soit on passe par uv run.
Diagnostic
which -a python python3 # tous les candidats, dans l'ordre du PATH
pyenv which python # ce que pyenv résoudrait
pyenv doctor # si le plugin est installé
PYENV_VERSION=system python -V # contournement ponctuel
Rapport avec uv
uv est indépendant : il télécharge ses propres interpréteurs dans
~/.local/share/uv/python/ et ne consulte jamais pyenv. Seul point de friction : les deux
lisent .python-version.
See also
Gestionnaire de projets Python en Rust. Remplace pyenv + venv + pip + pip-tools
d'un seul coup, et télécharge ses propres interpréteurs.
Démarrer un projet
uv init --python 3.12 mon-projet
cd mon-projet
uv add httpx pydantic pytest
uv run python -V
Using CPython 3.12.11
Creating virtual environment at: .venv
Python 3.12.11
Toujours passer --python. Sans lui, uv prend sa version par défaut — souvent une 3.13
ou 3.14 — et écrit requires-python = ">=3.13" dans le pyproject.toml.
uv init crée pyproject.toml, .python-version, main.py, README.md, .gitignore et
un dépôt git. Le .venv/ n'apparaît qu'au premier add ou run.
| Variante | Résultat |
|---|---|
uv init |
projet application, fichiers à plat |
uv init --package |
src/<nom>/__init__.py + [build-system] |
uv init --lib |
idem plus py.typed |
Le quotidien
uv add httpx # ajoute et installe
uv add --dev pytest ruff # dépendance de dev
uv remove httpx
uv sync # aligne .venv sur uv.lock
uv lock # regénère le lock sans installer
uv tree # arbre des dépendances
uv run <commande> # exécute dans le venv, sans activation
uv add et uv run synchronisent implicitement. uv sync sert surtout après un clone, ou
quand le .venv est cassé.
uv sync désinstalle ce qui n'est pas dans le lock, contrairement à pip install -r.
uv sync
Resolved 100 packages in 4ms
Uninstalled 3 packages in 8ms
- markdown-it-py==4.2.0
- mdurl==0.1.2
- rich==15.0.0
Reprendre un repo existant
git clone <url> && cd <repo> && ls
| Ce qu'on trouve | Ce qu'on lance |
|---|---|
uv.lock |
uv sync |
pyproject.toml seul |
uv sync (le lock est généré) |
requirements.txt |
uv venv --python 3.12 puis uv pip install -r requirements.txt |
poetry.lock |
poetry install, ou uv pip install -e . |
| rien | uv init --python 3.12 |
uv venv + uv pip ne modifient aucun fichier du repo — c'est la voie propre pour
accélérer l'installation chez un client sans imposer son outillage.
Le piège .python-version
uv et pyenv lisent ce fichier. Si uv y écrit 3.13 et que pyenv n'a pas de 3.13, pyenv
affiche une erreur à chaque commande dans ce dossier. C'est du bruit, uv continue de
fonctionner, mais c'est pénible.
# corriger requires-python dans pyproject.toml D'ABORD
uv python pin 3.12
Updated `.python-version` from `3.13` -> `3.12`
Dans l'autre ordre, uv refuse : The requested Python version 3.12 is incompatible with the project requires-python value of >=3.13.
Outils globaux
uv tool install ruff # installé isolément, disponible partout
uv tool list
uvx ruff check . # exécute sans installer
Diagnostic
uv run python -c "import sys; print(sys.executable)"
/Users/edouard/code/mon-projet/.venv/bin/python3
Le chemin doit contenir /.venv/ et être dans le projet. S'il pointe vers
.pyenv/shims, /opt/homebrew ou /usr/bin, on n'est pas où on croit.
uv python list # interpréteurs connus
uv cache clean # vider le cache
Pour un live coding sous pression, activer une fois et oublier le préfixe :
source .venv/bin/activate