|
|
@@ -16,7 +16,7 @@ finally: |
|
|
|
fp.close() |
|
|
|
``` |
|
|
|
|
|
|
|
versus: |
|
|
|
# versus |
|
|
|
|
|
|
|
```python |
|
|
|
try: |
|
|
@@ -32,35 +32,261 @@ fp.close() |
|
|
|
|
|
|
|
Que se passe-t-il si l'exception *n'est pas* ZeroDivisionError? |
|
|
|
|
|
|
|
# |
|
|
|
|
|
|
|
\center \huge Utiliser des bibliothèques tierces |
|
|
|
|
|
|
|
Plan: |
|
|
|
# Rappel |
|
|
|
|
|
|
|
- sys.path |
|
|
|
- difference debian/arch |
|
|
|
- in $HOME |
|
|
|
- PYTHONPATH |
|
|
|
```python |
|
|
|
import foo |
|
|
|
|
|
|
|
answer = foo.get_answer() |
|
|
|
``` |
|
|
|
|
|
|
|
Fonctionne si: |
|
|
|
|
|
|
|
* Il y a un `foo.py` quelque part qui contient une fonction `get_answer` |
|
|
|
* Dans le dossier courant |
|
|
|
* Ou dans la bibliothèque standard Python |
|
|
|
|
|
|
|
# Parlons de PATH |
|
|
|
|
|
|
|
* Vous connaissez peut-être la variable PATH, qui dit |
|
|
|
où sont les exécutables. |
|
|
|
|
|
|
|
```bash |
|
|
|
PATH="/bin:/usr/bin:/usr/sbin" |
|
|
|
$ ifconfig |
|
|
|
# résout sur /usr/sbin/ifconfig |
|
|
|
$ ls |
|
|
|
# résount sur /bin/ls |
|
|
|
``` |
|
|
|
|
|
|
|
# sys.path |
|
|
|
|
|
|
|
En Python c'est pareil. |
|
|
|
|
|
|
|
```python |
|
|
|
import sys |
|
|
|
print(sys.path) |
|
|
|
``` |
|
|
|
|
|
|
|
# Sur mon Arch |
|
|
|
|
|
|
|
``` |
|
|
|
* '' # vide = chemin courant |
|
|
|
* /usr/lib/python3.7 |
|
|
|
* /usr/lib/python3.7/lib-dynload |
|
|
|
* /home/dmerej/.local/lib/python3.7/site-packages |
|
|
|
* /usr/lib/python3.7/site-packages |
|
|
|
``` |
|
|
|
|
|
|
|
# À noter |
|
|
|
|
|
|
|
Seul deux des composants sont accessibles en *écriture* par |
|
|
|
mon utilisateur courant: |
|
|
|
|
|
|
|
* Le chemin courant |
|
|
|
* Un chemin dans mon $HOME (`~/.local/lib/python3.7/site-packages/`) |
|
|
|
|
|
|
|
Même principe sur macOS et Windows (presque) |
|
|
|
|
|
|
|
# Bibliothèques tierces |
|
|
|
|
|
|
|
Par example, pour faire des jolis tableaux: |
|
|
|
|
|
|
|
```python |
|
|
|
import tabulate |
|
|
|
|
|
|
|
scores = [ |
|
|
|
["John", 345], |
|
|
|
["Mary-Jane", 2], |
|
|
|
["Bob", 543], |
|
|
|
] |
|
|
|
table = tabulate.tabulate(score) |
|
|
|
print(table) |
|
|
|
``` |
|
|
|
|
|
|
|
``` |
|
|
|
--------- --- |
|
|
|
John 345 |
|
|
|
Mary-Jane 2 |
|
|
|
Bob 543 |
|
|
|
--------- --- |
|
|
|
``` |
|
|
|
|
|
|
|
# Le problème |
|
|
|
|
|
|
|
On peut trouver le code source de `tabulate` facilement. |
|
|
|
|
|
|
|
Mais comment faire pour le mettre dans `sys.path`? |
|
|
|
|
|
|
|
|
|
|
|
# À la main |
|
|
|
|
|
|
|
On peut récupérer les sources et les installer avec `python3 setup.py install --user` |
|
|
|
|
|
|
|
* Quasiment *tous* les projets python on un `setup.py` utilisable de cette façon. |
|
|
|
* On utilise `--user` pour éviter des problèmes de permissions |
|
|
|
|
|
|
|
* Démo! |
|
|
|
|
|
|
|
# Anatomie du setup.py |
|
|
|
|
|
|
|
Un appel à `setuptools.setup()`. C'est tout |
|
|
|
|
|
|
|
```python |
|
|
|
from setuptools import setup |
|
|
|
|
|
|
|
setup( |
|
|
|
name='tabulate', |
|
|
|
version='0.8.1', |
|
|
|
description='Pretty-print tabular data', |
|
|
|
py_modules=["tabulate"], |
|
|
|
scripts=["bin/tabulate"], |
|
|
|
... |
|
|
|
) |
|
|
|
``` |
|
|
|
|
|
|
|
# À noter |
|
|
|
|
|
|
|
Sur linux, si le paquet contient des *scripts*, ils arriveront dans `~/.local/bin`. |
|
|
|
|
|
|
|
Sous macOS et Windows, ce sera un autre emplacement, mais qui *dépendra de la version de Python*. |
|
|
|
|
|
|
|
* Utilisez `python3 -m` quand c'est possible! |
|
|
|
|
|
|
|
|
|
|
|
# Avec pip |
|
|
|
|
|
|
|
* `pip` vient par défaut avec Python3 |
|
|
|
* Vous pouvez aussi l'installer avec `get-pip.py` |
|
|
|
* Toujours le lancer avec `python3 -m pip`. |
|
|
|
|
|
|
|
# Dépendances |
|
|
|
|
|
|
|
Prenons une autre bibliothèque: `cli-ui`. |
|
|
|
|
|
|
|
Elle sert à faire des jolis programmes en couleur: |
|
|
|
|
|
|
|
```python |
|
|
|
import cli_ui |
|
|
|
|
|
|
|
cli_ui.info_1("Ceci est une info importante") |
|
|
|
cli_ui.info("Ceci est en", cli_ui.bold, "gras") |
|
|
|
``` |
|
|
|
|
|
|
|
# Dépendances de cli-ui |
|
|
|
|
|
|
|
En fait, `cli-ui` utilise *d'autres* bibliothèques. |
|
|
|
|
|
|
|
Par example: |
|
|
|
|
|
|
|
```python |
|
|
|
headers=["name", "score"] |
|
|
|
data = [ |
|
|
|
[(bold, "John"), (green, 10.0)], |
|
|
|
[(bold, "Jane"), (green, 5.0)], |
|
|
|
] |
|
|
|
cli_ui.info_table(data, headers=headers) |
|
|
|
``` |
|
|
|
|
|
|
|
Devinez qui s'occupe d'afficher le tableau! |
|
|
|
|
|
|
|
# Déclaration des dépendances |
|
|
|
|
|
|
|
Aussi dans setup.py: |
|
|
|
|
|
|
|
```python |
|
|
|
setup( |
|
|
|
name="cli-ui", |
|
|
|
version="0.9.1", |
|
|
|
install_requires=[ |
|
|
|
"tabulate", |
|
|
|
... |
|
|
|
], |
|
|
|
... |
|
|
|
) |
|
|
|
``` |
|
|
|
|
|
|
|
# Intérêt de pip |
|
|
|
|
|
|
|
* Va chercher tout seul sur `pypi` |
|
|
|
* Lance `setup.py` tout seul (pour trouver les dépendances, et les installer) |
|
|
|
|
|
|
|
* S'utilise avec `python3 -m pip install --user ...` |
|
|
|
|
|
|
|
|
|
|
|
# Fonctionalités en plus |
|
|
|
|
|
|
|
* Peut supprimer quelque chose d'installé - `python3 -m pip uninstall <>` |
|
|
|
* Peut chercher sur `pypi` directement - `python3 -m pip search <>` |
|
|
|
* Peut lister ce qui est installé - `python3 -m pip list` |
|
|
|
|
|
|
|
# Limitations de pip seul |
|
|
|
|
|
|
|
* Il faut penser à utiliser `--user` |
|
|
|
* Si le paquet est déjà installé dans le système (genre `/usr/lib/` source linux), |
|
|
|
pip ne saura pas le mettre à jour - il faudra passer par le gestionnaire de paquet de |
|
|
|
la distribution |
|
|
|
|
|
|
|
# Versions de dépendances |
|
|
|
|
|
|
|
Parfois, les versions sont incompatibles entre elles! |
|
|
|
|
|
|
|
https://tankerhq.github.io/python-cli-ui/changelog.html#v0-8-0 |
|
|
|
|
|
|
|
# Solution |
|
|
|
|
|
|
|
On peut donner des versions dans `setup.py`: |
|
|
|
|
|
|
|
```python |
|
|
|
install_requires=[ |
|
|
|
"cli-ui <= 0.8", |
|
|
|
... |
|
|
|
] |
|
|
|
``` |
|
|
|
|
|
|
|
# Plusieurs projets |
|
|
|
|
|
|
|
* Projet A utilise `cli-ui` 0.7 |
|
|
|
* Projet B utilise `cli-ui` 0.9 |
|
|
|
|
|
|
|
Comment faire pour travailler sur les deux projets? |
|
|
|
|
|
|
|
# Environements virtuels |
|
|
|
|
|
|
|
* Un chemin *isolé* du reste du système. |
|
|
|
* Contient un binaire python légèrement différent du binaire ordinaire. |
|
|
|
* Se crée avec `python3 -m venv <le chemin>` - sauf sous debian ;-( |
|
|
|
|
|
|
|
# Avec virtualenv |
|
|
|
|
|
|
|
* Vous pouvez aussi install `virtualenv` avec pip puis utiliser `virtualenv` |
|
|
|
|
|
|
|
```bash |
|
|
|
$ python3 -m pip install virtualenv --user |
|
|
|
$ python3 -m virtualenv <le chemin> |
|
|
|
``` |
|
|
|
|
|
|
|
- so how do we put the code from pypi.org inside sys.path? |
|
|
|
- setup.py |
|
|
|
# L'isolation en pratique |
|
|
|
|
|
|
|
- pip |
|
|
|
* Plus de chemin dans `~/.local/lib` |
|
|
|
* Moins de chemins dans le système |
|
|
|
* Les scripts restent dans le virtualenv |
|
|
|
|
|
|
|
- example with tabulate |
|
|
|
- TODO: example with more deps |
|
|
|
# Pip + Virtualenv = <3 |
|
|
|
|
|
|
|
- problemes: |
|
|
|
Et vous avez aussi un `pip` spécial dans `/le chemin/bin/pip` |
|
|
|
|
|
|
|
- un seul .local/bin sur linux :/ |
|
|
|
- 2 projets avec des versions de deps differentes |
|
|
|
* Plus besoin de `--user` |
|
|
|
* On peut créér deux virtualenvs différent pour les projets A et B |
|
|
|
|
|
|
|
# The rules |
|
|
|
|
|
|
|
* One virtualenv per project |
|
|
|
* One virtualenv per Python version |
|
|
|
* Only use pip from *inside* a virtualenv |
|
|
|
# Activer un virtualenv |
|
|
|
|
|
|
|
Tuto: |
|
|
|
Si taper le chemin du virtualenv vous embête, vous pouves |
|
|
|
*l'activer* avec `source bin/activate` |
|
|
|
|
|
|
|
* let's install tabulate and requests |
|
|
|
Pour sortir: `deactivate`. |