Pipenv vs setup.py

问题描述 投票:18回答:3

我正在尝试迁移到pipenv。我传统上使用setup.pypip并做pip install -e .安装模块作为一个包,所以我可以从项目的任何地方实现from myproject.xyz.abc import myClass之类的东西。

如何与pipenv达到类似效果并摆脱setup.py

注意:我使用的是python 2.7

python pip setuptools pipenv
3个回答
19
投票

更新:

pipenv 9.0.0一直是released,它应该允许你按预期使用pipenv install -e .

原始答案:

pipenv install -e是越野车,一直是fixed in masterpull request)。它将在感恩节后的下一个版本中提供。

暂时的解决方法是:

pipenv shell
pip install -e .

发布后,你应该可以运行pipenv install -e .,类似于你对pip的期望。


12
投票

更新:2019年3月5日:从pip版本19.03开始,你可以省略你的软件包的setup.py并使用pyproject.toml[build-system](不支持在可编辑模式下安装(在这种情况下你还需要setup.py)

更新:2018年6月12日:一个更类似的工具https://github.com/takluyver/flitpoetryflit背后有一个很大的未来。希望他们合并力量,我们将拥有一体化舒适的软件包和应用程序管理,例如,生锈cargo


更新:2018年4月19日:有一个类似的工具,它可以同时处理所有包装管理,而不需要setup.py。这是https://github.com/sdispater/poetry


更新:2018年4月11日:Pipenv的作者在这里描述了问题:http://pipenv.readthedocs.io/en/latest/advanced/#pipfile-vs-setup-py


如果你在没有setup.py的软件包中运行pipenv install -e .,那么你将获得:

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

因此,无论如何你需要setup.py这样的情况。

理解应用程序和包的概念很重要。这些信息可能有用https://caremad.io/posts/2013/07/setup-vs-requirement/

如果您正在构建应用程序,那么pipenv是您唯一需要的东西。

但是,如果你正在构建一个包,那么无论如何你必须有setup.py,以便允许它的pip或pipenv安装(也许在可编辑模式下)。

pipenv的作者的答案在这里:https://github.com/pypa/pipenv/issues/1161#issuecomment-349972287

因此,pipenv vs setup.py是一个错误的表述。他们不能互相攻击。相反,相互支持,或相互排斥。

我们可能必须找到一种方法如何使用它们,而不重复。

当你构建一个包时,你仍然可以使用pipenv,但这会导致重复的事情(setup.py和Pipfile中的要求)。我使用以下方法来解决这个问题:

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,
    },
)

现在你有以下内容:

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

注意之前应该安装pipenv

然而,这不是解决问题的干净方法。


2
投票

在你的情况下,pipenv取代pip但你仍然需要一个setup.py

假设您的目录结构如下:

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

然后,您可以启动Python 3环境并使用以下命令安装包:

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

您可以使用cat Pipfilepipenv graph验证是否已安装该软件包。

但是,如果您的包根目录与您的pipenv根目录不同,那么pipenv install -e .将失败,并显示一条神秘的错误消息:

解析需求时出错。 - 你确定它可以安装吗?

在这种情况下,您应该从pipenv根目录调用pipenv install -e并提供包的根目录的路径。例如,使用此文件结构:

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

你会用:

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

正如另一位用户所提到的,在这种情况下,使用pip install -e .会将软件包从dir_a安装到虚拟环境中。但是,至少对我来说,它不会更新Pipfile所以没有多大用处。

© www.soinside.com 2019 - 2024. All rights reserved.