web-dev-qa-db-fra.com

Pipenv vs setup.py

J'essaie de migrer vers pipenv. J'ai utilisé traditionnellement setup.py avec pip et a fait pip install -e . pour installer le module en tant que package, afin que je puisse réaliser des choses comme from myproject.xyz.abc import myClass de n'importe où dans le projet.

Comment obtenir l'effet similaire avec pipenv et me débarrasser de setup.py?

Remarque: j'utilise python 2.7.

19
khan

Mise à jour:

pipenv 9.0.0 a été publié , ce qui devrait vous permettre d'utiliser pipenv install -e . comme prévu.

Réponse originale:

pipenv install -e est bogué et a été corrigé dans master ( pull request ). Il sera disponible dans la prochaine version, quelque temps après Thanksgiving.

La solution de contournement temporaire pour le moment est:

pipenv Shell
pip install -e .

Après la publication, vous devriez pouvoir exécuter pipenv install -e . similaire à ce que vous attendez avec pip.

19
cs01

MISE À JOUR: 5 mars 2019: Depuis la version 19.03 de pip, vous pouvez omettre setup.py pour vos packages et utiliser pyproject.toml et [build-system] (ne prend pas en charge l'installation en mode modifiable (dans ce cas, vous avez toujours besoin de setup.py)

MISE À JOUR: 12 juin 2018: Un autre outil similaire https://github.com/takluyver/flit . Il y a un grand avenir derrière poetry et flit. J'espère qu'ils fusionneront leurs forces et nous aurons des packages tout-en-un confortables et une gestion des applications, comme, Rust cargo par exemple


MISE À JOUR: 19 avril 2018: Il existe un outil similaire, qui peut gérer toute la gestion de l'emballage en même temps, sans avoir besoin de setup.py. C'est https://github.com/sdispater/poetry


MISE À JOUR: 11 avril 2018: L'auteur de Pipenv décrit le problème ici: http://pipenv.readthedocs.io/en/latest/advanced/# pipfile-vs-setup-py


Si vous exécutez pipenv install -e . dans un paquet sans setup.py, vous obtiendrez:

$ pipenv install -e .              
Directory '.' is not installable. File 'setup.py' not found.

Vous avez donc besoin de setup.py de toute façon pour un tel cas.

Il est important de comprendre le concept des applications et des packages. Ces informations pourraient être utiles https://caremad.io/posts/2013/07/setup-vs-requirement/

Si vous créez une application, alors pipenv est la seule chose dont vous avez besoin.

Cependant, si vous créez un package, vous devez avoir setup.py de toute façon, afin de permettre l'installation de pip ou pipenv (peut-être aussi en mode éditable).

La réponse de l'auteur du pipenv est ici: https://github.com/pypa/pipenv/issues/1161#issuecomment-349972287

Ainsi, pipenv vs setup.py est une mauvaise formulation. Ils ne peuvent pas être les uns contre les autres. Soutenez-vous plutôt ou excluez-vous les uns les autres.

Nous devrons peut-être trouver un moyen de les utiliser tous les deux, sans dupliquer les choses.

Lorsque vous construisez un package, vous pouvez toujours utiliser pipenv, mais cela conduit à des choses en double (requis dans setup.py et Pipfile). J'utilise l'approche suivante pour résoudre ce problème:

import pathlib
import subprocess

from setuptools import setup, find_packages
from setuptools.command.install import install
from setuptools.command.develop import develop


__requires__ = ['pipenv']

packages = find_packages(exclude=['tests'])
base_dir = pathlib.Path(__file__).parent

pipenv_command = ['pipenv', 'install', '--deploy', '--system']
pipenv_command_dev = ['pipenv', 'install', '--dev', '--deploy', '--system']

class PostDevelopCommand(develop):
    """Post-installation for development mode."""
    def run(self):
        subprocess.check_call(pipenv_command_dev)
        develop.run(self)

class PostInstallCommand(install):
    """Post-installation for installation mode."""
    def run(self):
        subprocess.check_call(pipenv_command)
        install.run(self)


with open(base_dir / 'README.md', encoding='utf-8') as f:
    long_description = f.read()

setup(
    name='dll_api',
    use_scm_version = True,
    long_description='\n' + long_description,
    packages=packages,
    setup_requires=['setuptools_scm'],
    cmdclass={
        'develop': PostDevelopCommand,
        'install': PostInstallCommand,
    },
)

Vous disposez maintenant des éléments suivants:

$ python setup.py install
running install
Installing dependencies from Pipfile.lock (e05404)…

Remarque pipenv doit être installé avant!

Ce n'est pas une façon propre de résoudre le problème, cependant, faites le travail.

12
Artem Zhukov

Dans votre cas, pipenv remplace pip mais vous aurez toujours besoin d'un setup.py.

En supposant que votre répertoire est structuré comme ceci:

dir_a/              <-- This will be your pipenv root dir and your package root dir.
    setup.py
    dir_b/
        __init__.py
        somefile.py
        otherfile.py

Ensuite, vous pouvez lancer un environnement Python 3 et installer votre package en utilisant:

$> cd dir_a
$> pipenv --python 3
$> pipenv Shell
$> pipenv install -e . 

Vous pouvez vérifier que le package a été installé à l'aide de cat Pipfile ou pipenv graph.

Cependant, si le répertoire racine de votre package n'est pas le même que votre répertoire racine pipenv, alors pipenv install -e . échouera avec un mystérieux message d'erreur:

Erreur d'analyse syntaxique. - êtes-vous sûr qu'il est installable?

Dans ce cas, vous devez appeler pipenv install -e depuis le répertoire racine de pipenv et donnez le chemin vers le répertoire racine du package. Par exemple, avec cette structure de fichiers:

dir_z/              <-- This will be your pipenv root dir.
    something.py
    empty_dir/
    dir_a/          <-- This is your package root dir.
        setup.py
        dir_b/
            __init__.py
            somefile.py
            otherfile.py

Vous utiliseriez:

$> cd dir_z
$> pipenv --python 3
$> pipenv Shell
$> pipenv install -e dir_a/

Comme un autre utilisateur l'a mentionné, en utilisant pip install -e . installe le package dans l'environnement virtuel à partir de dir_a dans ce scénario. Cependant, au moins pour moi, il ne met pas à jour le Pipfile donc ce n'est pas très utile.

2
FiddleStix