Travailler sur une lib externe à votre projet proprement en Python 11


Quand on a une lib externe en dépendance à son projet, on veut être capable de l’importer MAIS pouvoir en modifier le code.

L’installer avec pip ou python setup.py install va copier le code dans le dossier site-packages et ce n’est pas ce que l’on veut car ça oblige à refaire l’installation à chaque modif.

Le mettre dans un dossier “libs” qu’on ajoute au PYTHON PATH ou pire, ajouter chaque dépendance au PYTHON PATH n’est pas une solution qu’on est fier d’exhiber au hackerspace du coin.

On s’en remet donc généralement à un symlink, sans savoir qu’il existe en fait un outil fait pour ça :

python setup.py develop

Cette commande va ajouter des entrées spéciales dans des fichiers placés dans site-packages qui vont vous permettre d’utiliser votre lib comme si elle était installée. Mais en vérité il va chercher le code dans votre dossier de dev, donc si vous modifiez le code, vous avez toujours la version de votre lib la plus fraîche.

Une fois qu’on a une lib stable, on peut retirer ce lien avec :

python setup.py develop --uninstall

Et installer la lib normalement.

Notez que tout ceci ne fonctionne que si le setup.py utilise setuptools et non distutils qui provoque l’erreur error: invalid command ‘develop’.

Comme setuptools inclut maintenant le meilleur de distutils, on peut remplacer :

from distutils.core import setup

Par :

from setuptools import setup

Sans soucis.

pip vient lui aussi avec un outil pour ça en la forme du flag -e qui fait exactement la même chose. Exemple :

pip install -e /chemin/local/vers/projet

Cela fonctionne comme pour python setup.py develop --uninstall mais on bénéficie de tous les goodies de pip en prime.

Néanmoins, pip pousse plus loin l’automatisation. Si vous faites pip install -e sur un repo distant, il va également cloner pour vous le code.

Ex :

pip install -e git+https://git@github.com/sametmax/minibelt.git#egg=minibelt

Et on retrouvera un clone du projet dans /chemin/vers/virtualenv/src/ qui sera importable, modifiable et pushable. Le résultat est automatisable, puisque pip freeze le prend en compte:

$ pip freeze
argparse==1.2.1
-e git+https://git@github.com/sametmax/minibelt.git@b898155b40d7de73cc404db7d274128f2b2fc330#egg=minibelt-master
wsgiref==0.1.2

L’URL est assez bâtarde à trouver par contre, car elle doit toujours finir par #egg=nom-du-projet et commencer par un double protocole, celui du VCS et celui du transport.

P.S: j’ai remis la coloration syntaxique et les iframes (donc la musique). J’aime bien ce thème là, mais le header chie sa mère. Est-ce que vous l’aimez suffisamment pour que je me casse le cul à le réparer ?

11 thoughts on “Travailler sur une lib externe à votre projet proprement en Python

  • foxmask

    encore une perle à mettre de coté … heum fasais bien chier avec le 1° cas du setup install …
    pour le ” PS ” faut que ca te plaise à toi d’abord ; c’est quand meme sensé être ton univers hein ;)

  • Jambon

    Ah oui, nikel !

    J’avais vu passer ça dans je sais plus quelle doc, mais pas assez détaillé pour pouvoir vraiment l’utiliser.

    Par contre tu fais chier, j’ai masse simlynks à virer maintenant…

  • Ronan

    Merci d’avoir répondu à ma question, c’est top. Bel article.
    J’utilise donc aussi “pip install -e git+…” depuis peu et c’est top.
    Je vous conseille même “pip install –src ./lib_path/ -e git+…” pour avoir votre lib installée à un endroit plus accessible.
    Pour le coup j’ai fait un template de projet ici : https://github.com/ronhanson/python-project-template/
    J’espère que ca aidera quelqu’un.

  • Ronan Delacroix

    Oui, tous les projets “editables” s’installent dedans du coup.
    Ca marche avec le -r requirements.txt
    Mais sont ajoutés au path avec un fichier mon_package.egg-link dans site-packages…

    Petit coup de gueule du jour :
    Depuis python 3 je crois, mon fichier requirements.txt ressemble à ca :
    pymagento >= 0.1
    jellyfish >= 0.2
    –allow-all-external
    –allow-unverified xmlrpclib

    pymagento (petite lib simpliste) requiert xmlrpclib, mais cette lib n’est pas “verified”…
    Je sais pas bien ce que ca veut dire, mais ca me casse bien les burnes d’avoir a mettre des parametres de commande dans un requirements.txt… Même pour une dependance chainée…

    Je sais pas comment corriger ca simplement…

  • Sam Post author

    Il n’y a pas de correction simple, il faut contacter l’auteur de la lib et lui dire d’uploader xmlrpclib sur pypi, ou bien dire à l’auteur de pymagento de changer de dépendance.

  • frnx

    Ah, sympa le pip -e, je connaissais pas! Ca marche même si le projet n’utilise pas setuptools?

  • Sam Post author

    Je ne sais pas, faut tester. Pip est vachement plus flexible sur ce qu’il peut installer.

  • Joshua

    Bon, j’ai une question de noob. Donc en fait “python setup.py develop” c’est fait pour quand on veut modifier une lib externe, celle-ci étant dans le répertoire de travail. Du coup , on a juste besoin de faire un import normal, et ça va pointer direct dans le répertoire de travail. Je crois avoir compris ça.

    Ensuite on fait “python setup.py develop –uninstall” et les import pointent de nouveau vers les librairies originelles, c’est ça ? Donc quand tu dis “Et installer la lib normalement.”, ça veut dire remplacer la lib originelle avec la nouvelle modifiée ?

    Si, si, je sens bien que c’est une question stupide.

  • Sam Post author

    –uninstall desintalle les liens, mais n’installe rien à la place. Il faut donc procéder à l’installation de ta lib normalement par la suite sinon tu ne pourras plus l’importer.

  • frnx

    Du coup, j’ai testé ce matin, le pip -e ça marche nickel sur un paquet distutils! Elle me manquait trop cette option depuis que j’ai lâché setuptools parce que ça me faisait des conflits chelous avec des paquets systèmes dont l’installation par pip se passe mal ou pas du tout!

Leave a comment

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Des questions Python sans rapport avec l'article ? Posez-les sur IndexError.