Pipenv详解

Pipenv的基本使用

本章将介绍pipenv的一些基本功能的使用

Pipfile & Pipfile.lock

下面是一个Pipfile和其产生的Pipfile.lock文件的简单示例。

Pipfile

[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true
name = "pypi"

[packages]
requests = "*"


[dev-packages]
pytest = "*"

Pipfile.lock

{
    "_meta": {
        "hash": {
            "sha256": "8d14434df45e0ef884d6c3f6e8048ba72335637a8631cc44792f52fd20b6f97a"
        },
        "host-environment-markers": {
            "implementation_name": "cpython",
            "implementation_version": "3.6.1",
            "os_name": "posix",
            "platform_machine": "x86_64",
            "platform_python_implementation": "CPython",
            "platform_release": "16.7.0",
            "platform_system": "Darwin",
            "platform_version": "Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64",
            "python_full_version": "3.6.1",
            "python_version": "3.6",
            "sys_platform": "darwin"
        },
        "pipfile-spec": 5,
        "requires": {},
        "sources": [
            {
                "name": "pypi",
                "url": "https://pypi.python.org/simple",
                "verify_ssl": true
            }
        ]
    },
    "default": {
        "certifi": {
            "hashes": [
                "sha256:54a07c09c586b0e4c619f02a5e94e36619da8e2b053e20f594348c0611803704",
                "sha256:40523d2efb60523e113b44602298f0960e900388cf3bb6043f645cf57ea9e3f5"
            ],
            "version": "==2017.7.27.1"
        },
        "chardet": {
            "hashes": [
                "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691",
                "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"
            ],
            "version": "==3.0.4"
        },
        "idna": {
            "hashes": [
                "sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4",
                "sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f"
            ],
            "version": "==2.6"
        },
        "requests": {
            "hashes": [
                "sha256:6a1b267aa90cac58ac3a765d067950e7dbbf75b1da07e895d1f594193a40a38b",
                "sha256:9c443e7324ba5b85070c4a818ade28bfabedf16ea10206da1132edaa6dda237e"
            ],
            "version": "==2.18.4"
        },
        "urllib3": {
            "hashes": [
                "sha256:06330f386d6e4b195fbfc736b297f58c5a892e4440e54d294d7004e3a9bbea1b",
                "sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f"
            ],
            "version": "==1.22"
        }
    },
    "develop": {
        "py": {
            "hashes": [
                "sha256:2ccb79b01769d99115aa600d7eed99f524bf752bba8f041dc1c184853514655a",
                "sha256:0f2d585d22050e90c7d293b6451c83db097df77871974d90efd5a30dc12fcde3"
            ],
            "version": "==1.4.34"
        },
        "pytest": {
            "hashes": [
                "sha256:b84f554f8ddc23add65c411bf112b2d88e2489fd45f753b1cae5936358bdf314",
                "sha256:f46e49e0340a532764991c498244a60e3a37d7424a532b3ff1a6a7653f1a403a"
            ],
            "version": "==3.2.2"
        }
    }
}

建议 & 版本控制

  • 请在版本控制中保留 Pipfile 和 Pipfile.lock 文件
  • 如果目标是多个Python版本,则不要将 Pipfile 保存在版本控制系统中
  • 在 Pipfile 的 [require] 部分中指定目标Python版本。理想情况下,您应该只有一个目标Python版本,因为这是一个部署工具。
  • pipenv install 命令完全兼容 pip install 语法。完整的文档可以在 这里 找到。
  • 注意,Pipfile 使用了 TOML 规范。

Pipenv 工作流

克隆 / 创建 项目仓库:

$ cd myproject

如果存在 Pipfile,则从中安装依赖项:

$ pipenv install

或者,向项目中添加一个包:

$ pipenv install <package>

如果不存在 Pipfile 文件,上一条命令将会创建一个 Pipfile 文件。如果 Pipfile 文件已经存在,则会使用上一条命令中指定的包自动编辑 Pipfile 文件。

下一步,激活 Pipenv shell:

$ pipenv shell
$ python --version

上面的命令将会生成一个新的shell 子进程,可以使用 exit 命令 使其失效。

Pipenv 升级工作流

  • 使用 pipenv update --outdated 命令查看哪些依赖项已过期。
  • 更新包,又两个选项:
    • 要更新所有的依赖项,使用命令 pipenv update
    • 使用 pipenv update 命令升级指定的包。

从 requirements.txt 导出包

如果在运行 pipenv install 命令时有一个可用的 requirements.txt 文件,pipenv会自动将这个文件中的内容导出并创建一个 Pipfile 文件。

也可以指定其他位置的 requirements.txt 文件:

$ pipenv install -r path/to/requirements.txt

如果 requirements.txt 文件中的包有固定的版本号,你可以通过编辑新生成的 Pipfile 文件来移除那些版本号,并让 pipenv 来负责处理。

如果你想在 Pipfile 中保留那些固定的版本号,可以使用 pipenv lock --keep-outdated 命令。请尽快升级已过期的包。

指定包的版本

你可以使用 语义化的版本控制方案 指定包的版本。例如 major.minor.micro

例如,你可以使用如下的命令安装 requests

$ pipenv install requests~=1.2   # 相当于 requests~=1.2.0

Pipenv 将安装 1.2 版本和任何 minor 版本的更新,但不会安装 2.0 版本。

上面的命令将会自动更新 Pipfile 文件以体现这个特殊的需求。

通常,Pipenv使用与pip相同的参数格式。但是,请注意,根据PEP 440,您不能使用包含连字符或加号的版本号。

要指定包含或者排除具体的版本,您可以使用如下命令:

$ pipenv install "requests>=1.4"   # 只安装等于或者大于 1.4.0 的版本
$ pipenv install "requests<=2.13"  # 只安装小于或者等于 2.13.0 的版本
$ pipenv install "requests>2.19"   # 安装 2.19.1 版本但是不安装 2.19.0 版本

注意:强烈建议使用双引号包裹包名和版本号以避免unix操作系统中的输入和输出重定向问题。

请优先使用 ~= 标识符而不是 == 标识符,因为后者会阻止 pipenv 更新包:

$ pipenv install "requests~=2.2"  # 锁定包的主版本(这相当于使用==2.*)

要避免安装某个特定的版本,可以使用 != 标识符。

要深入解释有效标识符和更复杂的用例,请查看 PEP-440 的相关部分。

指定Python版本

要使用已安装的(并且在PATH路径中)特定版本的Python创建virtualenv,请使用 --python VERSION 标记,如下所示:

使用Python3:

$ pipenv --python 3

使用Python3.6:

$ pipenv --python 3.6

使用Python2.7.14:

$ pipenv --python 2.7.14

当给定了一个Python版本的时候,Pipenv会自动扫描系统中能够匹配给定的Python版本的Python解释器。

如果 Pipfile 文件还没有创建,则会自动生成。生成的 Pipfile 内容如下:

[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true

[dev-packages]

[packages]

[requires]
python_version = "3.6"

注意:[requires] 部分中的 python_version = “3.6” 指定你的应用需要3.6 版本的Python,并且将来(例如,其他机器上)在 Pipfile上运行 pipenv install 命令时会自动使用。如果不需要这样,请随时删除这一部分。

如果没有在命令行上指定Python版本,那么将自动选择 [requires] 部分中的 python_full_versionpython_version 指定的Python版本,如果 requires 部分也没有 python_full_versionpython_version ,那么将使用系统默认的Python版本。

可编辑的依赖 (例如:-e 标记)

你可以使用Pipenv将路径安装为可编辑的,通常当处理包时,这对于当前工作目录是有用的:

$ pipenv install --dev -e .

$ cat Pipfile
...
[dev-packages]
"e1839a8" = {path = ".", editable = true}
...

注意:使用 -e 标记时, 所有子依赖项也都会添加到 Pipfile.lock 文件中。如果不使用 -e 选项,则不会将子依赖项添加到 Pipfile.lock 文件中。

使用pipenv进行环境管理

用来管理 pipenv 环境的三个主要命令是 pipenv installpipenv uninstallpipenv lock

pipenv install

这个命令用来将包安装到pipenv的虚拟环境并更新 Pipfile 文件。

该命令的使用形式为:

$ pipenv install [package names]

该命令还有三个可选的参数:

  • –two 使用系统的Python2链接在virtualenv中执行安装

  • –three 使用系统的Python3链接在virtualenv中执行安装

  • –python 使用提供的Python解释器在virtualenv中执行安装

    警告:以上三个参数只能单独使用。它们还具有破坏性,会删除当前的virtualenv,然后用适当版本的virtualenv替代。

    注意:Pipenv创建的virtualenv的名称可能与你期望的不一样。危险的字符(例如 $!*@” 以及空格、反引号、换行符、回车符和制表符)都将转换为下划线。此外,从根目录到当前文件夹的完整路径将被编码为一个 slug value,并附加到后面以确保virtualenv名称是惟一的。

  • –dev 安装Pipfile中 [default][devlop] 中的包

  • –system 使用系统的 pip 命令而不是virtualenv的 pip 命令

  • –ignore-pipfile 忽略 Pipfile 文件而直接安装 Pipfile.lock 中的包

  • –ignore-lock 忽略 Pipfile.lock 文件而直接安装 Pipfile 中的包。此外,不会更新 Pipfile.lock 文件。

pipenv uninstall

该命令支持 pipenv install 中所有的参数,并且还支持另外两个参数可选参数 –all–all-dev

  • –all 从虚拟环境中移除所有已安装的包,但 Pipfile.lock 文件不受影响
  • –all-dev 从虚拟环境中卸载所有开发包,并从 Pipfile 文件中移除这些包

pipenv lock

该命令用于创建 Pipfile.lock 文件,它声明项目的所有依赖项(和子依赖项)、依赖项的最新可用版本以及已下载文件的散列值。这确保了构建是可重复的,并且最重要的是确保了构建具有确定性。

关于shell配置

由于shell对于子shell的配置通常都是错误的,因此 pipenv shell —fancy 可能会产生意想不到的结果。如果是这种情况,请尝试使用​ pipenv shell,因为这种情况下将使用兼容模式生成子shell,即便配置是错误的。

正确的shell配置只在登录会话期间设置PATH之类的环境变量,而不是在每个子shell派生期间设置。在fish shell中,一般是这样子的:

if status --is-login
    set -gx PATH /usr/local/bin $PATH
end

因此,你也应该在 ~/.profile~/.bashrc 或者任何其他适当的地方加上上面的代码。

注意:pipenv shell 命令将以交互模式启动子shell。这意味着,如果shell从一个特定的文件中读取其配置以进行交互模式(例如,bash默认情况下会查找 ~/.bashrc),那么你必须修改(或创建)这个文件。

如果您遇到了与 pipenv shell 有关的问题,请检查 PIPENV_SHELL 环境变量,因为这个环境变量将在可用的时候被 pipenv shell 使用。

关于VCS依赖关系的说明

您也可以使用pipenv从git和其他版本控制系统安装包,安装时使用的URL遵从以下的规则:

<vcs_type>+<scheme>://<location>/<user_or_organization>/<repository>@<branch_or_tag>#

惟一可选的部分是 @ 部分。在git中使用SSH协议时,可以使用vcs的缩写和schema的别名git+git@

/@#

注意,这在解析时将被转换为 git+ssh://git@

请注意,强烈建议您使用 pipenv install -e 以可编辑模式安装任何版本控制的依赖项,以确保每次执行依赖项解析时都可以使用存储库的最新副本执行,并且包含所有已知的依赖项。

要将位于 https://github.com/requests/requests.git 的git仓库中的tag v2.19.1 安装为名为 requests的包,可以使用如下命令:

$ pipenv install -e git+https://github.com/requests/[email protected]#egg=requests
Creating a Pipfile for this project...
Installing -e git+https://github.com/requests/[email protected]#egg=requests...
[...snipped...]
Adding -e git+https://github.com/requests/[email protected]#egg=requests to Pipfile's [packages]...
[...]

vcs_type 可用的值包括 gitbzrsvnhg。schema可用的值包括 httphttpssshfile

在特定情况下,您还可以访问其他schema:snv 可以和 snv 组合起来作为一个schema,bzr 可以与 sftplp 组合作为一个方案。

请参阅 pip实现对vcs的支持 以了解更多相关信息。有关指定VCS依赖项时可用的其他选项的更多信息,请查看 Pipfile 规范。

Pipfile.lock 安全功能

Pipfile.lock 利用了pip中一些新的安全改进。默认情况下,Pipfile.lock 包含每个下载的包的 sha256 哈希值。这可以使pip能够保证从不信任的PyPI源安装包时或者在不稳定的网络环境下安装包时都能保证包的正确性与完整性。我们强烈建议通过将项目从开发环境提升到生产环境来进行部署。您可以使用 pipenv lock 编译开发环境上的依赖项,并将编译后的 Pipfile.lock 文件部署到您所有的生产环境,以便进行可重现的构建。

pipenv的高级用法

本章将介绍pipenv的一些更出色和更高级的特性

警告

  • Pipfile 中提供的 wheels 依赖项不会被 pipenv lock 命令捕获。
  • 使用私有索引存在一些与散列相关的已知问题。我们正在积极努力解决这个问题。不过,你还是很有可能会遇到这个问题。
  • 对于依赖项的安装来说,确定性越高越好。如果遇到问题,使用 –sequence 标志来增加确定性。

指定包的索引

如果你希望使用特定的包索引安装特定的包,你可以像下面这样做:

[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true
name = "pypi"

[[source]]
url = "http://pypi.home.kennethreitz.org/simple"
verify_ssl = false
name = "home"

[dev-packages]

[packages]
requests = {version="*", index="home"}
maya = {version="*", index="pypi"}
records = "*"

使用PyPI镜像

如果您想使用PyPI镜像的URL覆盖默认的PyPI索引URL,你可以使用以下命令:

$ pipenv install --pypi-mirror <mirror_url>

$ pipenv update --pypi-mirror <mirror_url>

$ pipenv sync --pypi-mirror <mirror_url>

$ pipenv lock --pypi-mirror <mirror_url>

$ pipenv uninstall --pypi-mirror <mirror_url>

或者,通过 PIPENV_PYPI_MIRROR 环境变量设置。

通过环境变量将凭证注入Pipfile

pipenv将在 Pipfile 中替换环境变量(如果定义了)。这在你需要进行私有PyPI认证时特别有用:

[[source]]
url = "https://$USERNAME:${PASSWORD}@mypypi.example.com/simple"
verify_ssl = true
name = "pypi"

pipenv在替换环境变量之前会对Pipfile进行哈希(并且,当您从Pipfile.lock 文件中安装包时,它将再次替换环境变量,所以在提交时不会提交任何隐私文件)

指定特定系统上安装的包

如果你想指定某个包只在某个特定的系统上安装,可以使用 PEP 508 说明符来完成。

下面的例子,将只在Windows系统上安装 pywinusb

[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true
name = "pypi"

[packages]
requests = "*"
pywinusb = {version = "*", sys_platform = "== 'win32'"}

下面是一个更复杂的例子:

[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true

[packages]
unittest2 = {version = ">=1.0,<3.0", markers="python_version < '2.7.9' or (python_version >= '3.0' and python_version < '3.4')"}

使用pipenv进行部署

如果希望使用pipenv作为部署过程的一部分,可以使用 –deploy 标志强制Pipfile.lock 文件是最新的。

$ pipenv install --deploy

上述命令将在Pipfile.lock 文件不是最新的时候导致构建失败,而不是生成一个新的。

你也可以使用 sync 命令精确安装 Pipfile.lock 文件中指定的包:

$ pipenv sync

注意:pipenv install --ignore-pipfilepipenv sync 命令很相似,但是pipenv sync 命令永远不会尝试重新锁定依赖项,因为它被认为是一个原子操作。默认情况下,除非使用了 –deploy 标志,否则 pipenv install 会尝试重新锁定依赖项。

部署系统依赖关系

可以使用 –system 标志将 Pipfile 的内容安装到它的父系统中:

$ pipenv install --system

这对于管理系统Python和部署基础设施非常有用。

pipenv和其他Python发行版

要在其他第三方的Python发行版上使用pipenv(例如 Anaconda),可以通过 –python 标记指定Python的二进制文件:

$ pipenv install --python=/path/to/python

Anaconda 使用 Conda 管理包,要复用Conda安装的Python包,请使用 –site-packages标记:

$ pipenv --python=/path/to/python --site-packages

生成一个 requirements.txt 文件

可以非常容易的将Pipfile和Pipfile.lock 转变成 requirements.txt 文件,并获得我们提供的附加功能和的其他好处。

如果有下面这样一个Pipfile文件:

[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true

[packages]
requests = {version="*"}

可以生成如下的 requirements.txt 文件:

[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true

[packages]
requests = {version="*"}

如果希望生成一个只包含开发需求的 requirements.txt 文件,也是可以做到的。如果有下面这样的一个Pipfile文件:

[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true

[dev-packages]
pytest = {version="*"}

会生成下面这样一个 requirements.txt 文件:

$ pipenv lock -r --dev
py==1.4.34
pytest==3.2.3

安全漏洞检测

Pipenv包含安全包,并将使用它来扫描依赖关系图,以查找已知的安全漏洞。

例如:

$ cat Pipfile
[packages]
django = "==1.10.1"

$ pipenv check
Checking PEP 508 requirements…
Passed!
Checking installed package safety…

33075: django >=1.10,<1.10.3 resolved (1.10.1 installed)!
Django before 1.8.x before 1.8.16, 1.9.x before 1.9.11, and 1.10.x before 1.10.3, when settings.DEBUG is True, allow remote attackers to conduct DNS rebinding attacks by leveraging failure to validate the HTTP Host header against settings.ALLOWED_HOSTS.

33076: django >=1.10,<1.10.3 resolved (1.10.1 installed)!
Django 1.8.x before 1.8.16, 1.9.x before 1.9.11, and 1.10.x before 1.10.3 use a hardcoded password for a temporary database user created when running tests with an Oracle database, which makes it easier for remote attackers to obtain access to the database server by leveraging failure to manually specify a password in the database settings TEST dictionary.

33300: django >=1.10,<1.10.7 resolved (1.10.1 installed)!
CVE-2017-7233: Open redirect and possible XSS attack via user-supplied numeric redirect URLs
============================================================================================

Django relies on user input in some cases  (e.g.
:func:`django.contrib.auth.views.login` and :doc:`i18n </topics/i18n/index>`)
to redirect the user to an "on success" URL. The security check for these
redirects (namely ``django.utils.http.is_safe_url()``) considered some numeric
URLs (e.g. ``http:999999999``) "safe" when they shouldn't be.

Also, if a developer relies on ``is_safe_url()`` to provide safe redirect
targets and puts such a URL into a link, they could suffer from an XSS attack.

CVE-2017-7234: Open redirect vulnerability in ``django.views.static.serve()``
=============================================================================

A maliciously crafted URL to a Django site using the
:func:`~django.views.static.serve` view could redirect to any other domain. The
view no longer does any redirects as they don't provide any known, useful
functionality.

Note, however, that this view has always carried a warning that it is not
hardened for production use and should be used only as a development aid.

注意:为了在维护其许可的版权许可的同时启用该功能,pipenv为 pyup.io 操作的后端安全API嵌入了一个API客户机密钥,而不是包含 CC-BY-NC-SA 授权的安全数据库的完整副本。这个嵌入式客户端密钥在所有 pipenv check 用户之间共享,因此将根据总体使用情况而不是单个客户端使用情况进行API访问节流。

您还可以通过设置环境变量 PIPENV_PYUP_API_KEY 来使用自己的安全API密钥。

社区集成

有一系列社区维护的插件和扩展,可用于一系列编辑器和IDE,以及与Pipenv项目集成的不同产品:

  • Heroku (Cloud Hosting)
  • Platform.sh (Cloud Hosting)
  • PyUp (Security Notification)
  • Emacs (Editor Integration)
  • Fish Shell (Automatic $ pipenv shell
  • VS Code (Editor Integration)
  • PyCharm (Editor Integration)

正在开发中的:

  • Sublime Text (Editor Integration)
  • Mysterious upcoming Google Cloud product (Cloud Hosting)

在编辑器中打开模块

Pipenv允许使用 pipenv open 命令打开任何已安装的Python模块(包括代码库中的模块):

$ pipenv install -e git+https://github.com/kennethreitz/background.git#egg=background
Installing -e git+https://github.com/kennethreitz/background.git#egg=background…
...
Updated Pipfile.lock!

$ pipenv open background
Opening '/Users/kennethreitz/.local/share/virtualenvs/hmm-mGOawwm_/src/background/background.py' in your EDITOR.

这允许您轻松地阅读正在使用的代码,而不是在GitHub上查找代码。

注意:pipenv open 命令会使用标准的 EDITOR 环境变量。如果你想使用VS Code,你可以将环境变量 EDITOR 变量的值设置为 code,即 EDITOR=code。如果你在macOS下,你可以将 这个命令 安装到你的 PATH 路径下。

自动安装Python

如果已经安装并配置了pyenv,Pipenv会自动询问你是否需要安装它一个需要但是还未安装的特定的Python版本。

这是一个非常奇特的功能:

$ cat Pipfile
[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true

[dev-packages]

[packages]
requests = "*"

[requires]
python_version = "3.6"

$ pipenv install
Warning: Python 3.6 was not found on your system…
Would you like us to install latest CPython 3.6 with pyenv? [Y/n]: y
Installing CPython 3.6.2 with pyenv (this may take a few minutes)...
Making Python installation global…
Creating a virtualenv for this project…
Using /Users/kennethreitz/.pyenv/shims/python3 to create virtualenv…
...
No package provided, installing all dependencies.
...
Installing dependencies from Pipfile.lock…
?   ❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒❒ 5/5 — 00:00:03
To activate this project's virtualenv, run the following:
 $ pipenv shell

Pipenv自动支持 python_full_versionpython_version PEP 508 说明符。

自动加载 .env 文件

如果项目目录下包含一个 .env 文件,它会被 pipenv shellpipenv run 命令自动加载:

$ cat .env
HELLO=WORLD⏎

$ pipenv run python
Loading .env environment variables…
Python 2.7.13 (default, Jul 18 2017, 09:17:00)
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.environ['HELLO']
'WORLD'

这对于将生产凭证排除在代码库之外非常有用。我们不建议将 .env 文件提交到源代码控制中!

如果你的 .env 文件位于不同的路径下或者有其他名称,你可以设置一个 PIPENV_DOTENV_LOCATION 环境变量:

$ PIPENV_DOTENV_LOCATION=/path/to/.env pipenv shell

要禁止pipenv加载 .env 文件,可以设置 PIPENV_DONT_LOAD_ENV 环境变量:

$ PIPENV_DONT_LOAD_ENV=1 pipenv shell

定制脚本快捷方式

Pipenv支持在Pipfile的(可选)[scripts] 部分中创建自定义快捷方式。

然后可以在终端中运行 pipenv run ,以便在pipenv虚拟环境的上下文中运行命令,即使你没有首先激活pipenv shell。

例如,在您的Pipfile中:

[scripts]
printspam = "python -c \"print('I am a silly example, no one would need to do this')\""

然后,在终端中运行:

$ pipenv run printspam
I am a silly example, no one would need to do this

需要参数的命令也可以:

[scripts]
echospam = "echo I am really a very silly example"

$ pipenv run echospam "indeed"
I am really a very silly example indeed

环境变量支持

Pipenv支持在值中使用环境变量,例如:

[[source]]
url = "https://${PYPI_USERNAME}:${PYPI_PASSWORD}@my_private_repo.example.com/simple"
verify_ssl = true
name = "pypi"

[dev-packages]

[packages]
requests = {version="*", index="home"}
maya = {version="*", index="pypi"}
records = "*"

环境变量可以使用 {$MY_ENVAR}$MY_ENVAR 的方式指定。在Windows下,还可以使用 %MY_ENVAR% 来指定。

使用环境变量配置pipenv

Pipenv附带了一些可以通过shell环境变量启用的选项。要激活它们,只需在shell中创建对应的变量,pipenv就会检测到。

  • PIPENV_CACHE_DIR

    pipenv存储包缓存的目录。默认是当前项目所属的用户的用户缓存目录。

  • PIPENV_COLORBLIND

    是否启用终端的彩色显示。

  • PIPENV_DEFAULT_PYTHON_VERSION

    创建virtualenv时使用的默认Python版本。可以设置成一个表示Python版本的字符串,例如 3.6,或者一个表示Python解释器所在目录的路径。 默认值是安装pipenv的环境(即执行 sys.executable 得到的返回值)。命令行选项 –two–three–python 的优先级高于此变量指定的值。

  • PIPENV_DONT_LOAD_ENV

    如果设置了这个变量,则不会加载 .env 文件。默认情况下,在运行 run 命令或者 shell 命令时会加载 .env 文件。

  • PIPENV_DONT_USE_PYENV

    如果设置了,则pipenv在创建virtualenv的时候不会不会试图使用pyenv安装Python。默认情况下,如果pyenv是可用的,会在必要时使用pyenv自动安装需要的Pytho版本。

  • PIPENV_DOTENV_LOCATION

    如果设置了此环境变量的值,则会从这个环境变量指定的位置加载 .env 文件。默认情况下是从项目的根目录加载 .env 文件。

  • PIPENV_EMULATOR

    指定 pipenv shell 命令使用哪种终端模拟器。默认会自动检测要使用的终端模拟器。如果你的终端模拟器(例如 Cmder)不能被正确检测到,则需要设置这个环境变量。

  • PIPENV_HIDE_EMOJIS

    在输出中禁用表情符号。默认会显示表情符号。Windows下会自动

  • PIPENV_IGNORE_VIRTUALENVS

    如果设置这个环境变量,pipenv将会为该项目分配一个虚拟环境。默认情况下,Pipenv会尝试检测自身是否在虚拟环境中运行,并在可能的情况下重用它。这使得用户可以使用已存在的虚拟环境和pipenv。

  • PIPENV_INSTALL_TIMEOUT

    等待包安装的超时时间。默认值是900(15分钟),可以设置为任意时常。

  • PIPENV_MAX_DEPTH

    递归查找Pipfile的默认目录深度。默认值为3。请查看 PIPENV_NO_INHERIT

  • PIPENV_MAX_RETRIES

    Pipenv重新尝试发起网络请求的最大次数。默认值是0。在CI环境下进行健壮性测试时将自动设置为1。

  • PIPENV_MAX_ROUNDS

    设置pip要进行多少轮解析。默认值是16,可以设置为一个在大多数情况下都能正常工作的数字。

  • PIPENV_MAX_SUBPROCESS

    Pipenv在安装依赖项时使用的子进程个数。默认值是16,可以设置为一个在大多数情况下都能正常工作的数字。

  • PIPENV_NOSPIN

    如果设置了该变量,则会禁用终端spinner。这可以使得日志更清晰。 Windows和CI环境下会自动设置该变量。

  • PIPENV_NO_INHERIT

    告诉Pipenv不要继承父目录。这对于部署非常有用,可以避免使用错误的当前目录。将会覆盖 PIPENV_MAX_DEPTH 环境变量。

  • PIPENV_PIPFILE

    如果设置,则指定自定义Pipfile的位置。当从与Pipfile所在目录不同的位置运行pipenv时,指示pipenv在此环境变量指定的位置中找到Pipfile。默认值是在当前和父目录中自动查找Pipfile。 请查看 PIPENV_MAX_DEPTH.

  • PIPENV_PYPI_MIRROR

    如果设置了该变量,则会使用该变量指定的镜像URL替换默认的PyPI索引URL。默认不使用镜像,而是使用 pypi.org。命令行选项 --pypi-mirror 会覆盖该变量的值。

  • PIPENV_SHELL

    设置 pipenv shell 的首选 shell的绝对路径。默认值是自动检测当前正在使用的shell。

  • PIPENV_SHELL_FANCY

    如果设置了该变量,则在调用 pipenv shell 时始终使用 fancy 模式。默认值是在可用的情况下使用兼容模式。

  • PIPENV_SKIP_LOCK

    如果设置了该变量,Pipenv不会自动锁定依赖项。如果一个项目有大量依赖项,这可能是可取的,因为锁定本来就是一个很缓慢的操作。默认会在每次运行时锁定依赖项并更新Pipfile.lock。注意:这只影响 installuninstall 命令。

  • PIPENV_SPINNER

    设置默认的spinner类型。Spinners与node.js Spinners是相同的,点击 这里 查看详情。

  • PIPENV_TIMEOUT

    Pipenv等待virtualenv创建完成的最大秒数。默认值为120。可以设置为能够正常工作的任意的数值。

  • PIPENV_VENV_IN_PROJECT

    如果设置了该变量,则会在项目目录下创建 .venv 目录来放置virtualenv。默认会在全局位置创建virtualenv。

  • PIPENV_YES

    如果设置了该变量,Pipenv会在所有提示下自动输入 yes

    默认情况下,如果当前命令行会话是交互式的,则提示用户输入答案。

  • is_in_virtualenv()

    动态检查virtualenv成员。

    返回值:根据是否在一个常规的virtualenv中来返回True或者False。

    返回值类型:布尔值

    请点击 这里 查看源码。

定制虚拟环境位置

如果已经设置了 WORKON_HOME 环境变量,pipenv将自动使用这个环境变量的值作为存储虚拟环境的目录,如果还没有设置这个环境变量,可以像下面这样设置:

$ export WORKON_HOME=~/.venvs

此外,还可以设置环境变量 PIPENV_VENV_IN_PROJECT,让pipenv将虚拟环境附加到项目根目录的 .venv 路径下。

测试项目

Pipenv已被用于在例如 Requests 等项目中声明开发依赖关系和运行测试套件。

我们目前已经成功地测试了 Travis-CI 和 tox 的部署。

Travis CI

可以在 Requests 中找到一个Travis CI 设置的例子。这个项目使用了一个Makefile文件定义公共的功能,例如 inittests 命令。下面是一个简化的例子:

.travis.yml

language: python
python:
    - "2.6"
    - "2.7"
    - "3.3"
    - "3.4"
    - "3.5"
    - "3.6"
    - "3.7-dev"

# command to install dependencies
install: "make"

# command to run tests
script:
    - make test

对应的Makefile文件:

init:
    pip install pipenv
    pipenv install --dev

test:
    pipenv run py.test tests

Tox Automation Project

另外,你也可以设置一个像下面这样的 tox.ini 文件用于本地和外部的测试:

[tox]
envlist = flake8-py3, py26, py27, py33, py34, py35, py36, pypy

[testenv]
deps = pipenv
commands=
    pipenv install --dev
    pipenv run py.test tests

[testenv:flake8-py3]
basepython = python3.4
commands=
    pipenv install --dev
    pipenv run flake8 --version
    pipenv run flake8 setup.py docs project test

Pipenv 会自动使用tox提供的 virtualenv。如果 pipenv install --dev 安装了pytest,那么安装的命令 py.test 会出现在给定的virtualenv中,并且可以直接使用 py.test tests 调用,而不用使用 pipenv run py.test tests 这样的方式调用。

您可能还想在 pipenv install 中添加 –ignore-pipfile,以避免在每次测试运行时意外修Pipfile.lock文件。这将导致Pipenv忽略对Pipfile的更改,并且(更重要的是)阻止它将当前环境添加到Pipfile.lock中。这可能很重要,因为当前环境(即由tox提供的virtualenv)通常包含当前项目(可能需要也可能不需要)和来自tox的deps指令的其他依赖项。也可以通过向tox.ini添加 skip_install = True 来禁用初始配置。

这种方法要求您显式地更新锁文件,这在任何情况下都可能是一个好主意。

一个第三方的插件 tox-pipenv 也可以和tox一起使用。

命令行的自动完成功能

在fish shell中,添加如下配置:

eval (pipenv --completion)

bash或者zsh,添加如下配置:

eval "$(pipenv --completion)"

与平台提供的Python组建一起工作

操作系统接口的特定于平台的Python绑定,只有通过系统包管理器才能使用,而无法使用pip安装到虚拟环境中。在这些情况下,可以通过访问系统的 site-packages 目录创建虚拟环境:

$ pipenv --three --site-packages

为了确保所有可以通过pip安装的组件都实际安装到虚拟环境中,并且系统包只用于根本不参与python级依赖项解析的接口,请使用 PIP_IGNORE_INSTALLED 设置:

$ PIP_IGNORE_INSTALLED=1 pipenv install --dev

Pipfile VS setup.py

应用程序和库之间有一个细微但非常重要的区别。在Python社区中经常被混淆。

库为其他库和应用程序提供了可重用的功能(让我们在这里使用伞形术语项目)。这些库必须与其他库一起工作,并且所有这些库都有自己的一组用来定义抽象依赖关系的子依赖项,以避免项目中不同库的子依赖项中的版本冲突。库永远不应该固定依赖项版本,如果某个库依赖于某些子依赖项特定的特性/修复/bug的话,可以指定这些子依赖项的最低或最高(或者更新不太频繁的)版本。库依赖项是通过setup.py中的 install_require 指定的。

库最终用于某些应用程序。应用程序的不同之处在于,它们通常不依赖于其他项目。它们将被部署到特定的环境中,只有这样,它们所有依赖项和子依赖项的确切版本才会固定下来。使这一过程变得更容易,是目前Pipenv的主要目标。

总结一下:

  • 对于库来说,通过setup.py文件中的 install_requires 来指定抽象依赖。究竟要安装哪个版本以及在何处获得该依赖项不是由您来决定的!
  • 对于应用程序,在Pipfile中定义依赖关系以及从何处获取依赖项,并使用该文件更新Pipfile.lock中的一组具体依赖关系。该文件定义了适用于您的项目的一个特定的幂等环境。Pipfile.lock文件是你可信任的源。Pipfile为创建Pipfile.lock提供了便利,因为它并未严格指定要使用的依赖项的确切版本。Pipenv可以帮助您定义一组可工作的、无冲突的特定依赖版本,否则这将是一项非常乏味的任务。
  • 当然,Pipfile和Pipenv对于库开发人员仍然很有用,因为它们可以用来定义开发或测试环境。
  • 当然,对于某些项目,库和应用程序之间的区别不是很明显。在这种情况下,除了使用Pipenv和Pipfile外,还要使用 install_requires

你也可以这样做:

$ pipenv install -e .

这将告诉Pipenv锁定所有 setup.py 中声明的依赖项。

更改Pipenv缓存的位置

可以通过设置 PIPENV_CACHE_DIR 环境变量让pipenv使用一个特定的缓存目录。这在将 PIP_CACHE_DIR 更改为另一个目录的相同情况下非常有用。

更改默认的Python版本

默认情况下,Pipenv将使用python3的任意一个版本初始化一个项目。除了使用 –two–three 标志启动项目外,还可以使用 PIPENV_DEFAULT_PYTHON_VERSION 指定在不使用 –two–three 标志启动项目时使用哪个版本。

使用Pipenv时经常遇到的问题

Pipenv不断被志愿者改进,但仍然是一个非常年轻的项目。介于资源有限,并且有一些很奇怪的问题需要解决,因此,我们需要每个人的帮助(包括你的!)

以下是人们使用Pipenv时经常遇到的一些问题。看看这戏问题是否解决了你的疑惑。

注意:请首先确认你使用的是最新版本的Pipenv

依赖项不能被解析

确保您的依赖关系确实得到了解析。如果您确定了这一点,可能需要清除解析器缓存。运行以下命令然后重试:

$ pipenv lock --clear

如果还是不行,请尝试手动删除整个缓存目录。缓存目录通常位于以下位置:

  • ~/Library/Caches/pipenv (macOS)
  • %LOCALAPPDATA%\pipenv\pipenv\Cache (Windows)
  • ~/.cache/pipenv (other operating systems)

Pipenv默认不会安装预发布版本(例如,alpha/beta 等版本,或者带有例如 1.Ob1 等后缀的版本)。如果你确实需要安装预发布版本,请在命令中传递 –pre 标记,或者在Pipfile中进行如下设置:

[pipenv]
allow_prereleases = true

没有名称为的模块

这通常是将Pipenv与系统包混合使用的结果。我们强烈建议在隔离的环境中安装Pipenv。卸载所有现有Pipenv安装,并查看 安装Pipenv ,从中选择一个推荐的安装方式。

找不到pyenv安装的Python

请确保你正确设置了 PYENV_ROOT 环境变量。Pipenv只支持版本名类似于 3.7.3 这样的CPython发行版。

Pipenv不支持pyenv的全局和本地Python版本

Pipenv默认使用它所在的Python环境创建virtualenv。可以设置 –python 选项或者 $PYENV_ROOT/shims/python

来选择Python解释器。

要查看更多信息,请点击 指定包的版本 。

如果想要pipenv能够自动正确处理选择Python解释器,可以将环境变量 PIPENV_PYTHON 的值设置为 $PYENV_ROOT/shims/python 。这就会让Pipenv默认使用pyenv的有效Python版本来创建虚拟环境。

ValueError: unknown locale: UTF-8

macOS的区域设置检测中有一个bug,阻止我们正确地检测您的shell编码。如果其他系统的区域设置变量没有指定编码,可能也会存在问题。

解决方法是将以下两个环境变量设置为标准的本地化格式:

  • LC_ALL
  • LANG

对于Bash shell,你可以将下面的代码添加到 ~/.bash_profile 来解决这个问题:

export LC_ALL='en_US.UTF-8'
export LANG='en_US.UTF-8'

如果是Zsh,可以在 ~/.zshrc 中编辑。

注意:你可以把 en_USUTF-8 分别更改为你使用的 区域/语言 和编码。

/bin/pip: 没有这个文件或目录

这可能跟你的区域设置有关系。请查看上面一节,可能是一种解决方案。

shell的提示符中没有显示virtualenv的名称

这是Pipenv的默认行为。您可以使用shell插件或 PS1 环境变量自己来设置。如果想要恢复,可以使用如下命令(Windows下不可用):

$ pipenv shell -c

Pipenv不支持setup.py中的依赖项

这是Pipenv的默认行为。Pipfile和setup.py有不同的用途,默认情况下不应该考虑彼此。更多信息见 Pipfile vs setup . py。

在Supervisor程序中使用 pipenv run

当你使用 pipenv run … 配置一个 supervisor程序的命令时,你需要正确设置区域环境变量以确保其正常工作。

请在 /etc/supervisor/supervisord.conf 中的 [supervisord] 部分添加如下一行:

[supervisord]
environment=LC_ALL='en_US.UTF-8',LANG='en_US.UTF-8'

在锁定依赖项时抛出了异常:

运行 pipenv lock —clear 并重试。锁序列缓存结果以加速后续运行。如果一个缺陷导致格式损坏,即使取缺陷已经修复,缓存可能仍然包含错误的结果。使用 –clear 标记来清除缓存,移除错误的结果。

你可能感兴趣的:(Python学习,python,pipenv)