<p>pipenv 不尊重 pip.conf</p>

创建于 2017-10-08  ·  15评论  ·  资料来源: pypa/pipenv

我使用devpi作为私有 pypi 存储库,我可以在其中代理缓存 pypi 包并添加我自己的内部包。

我的pip.conf如下所示:

[global]
index_url = https://pypi.priv.xxx/prod/+simple/
[search]
index = https://pypi.priv.xxx/prod/

找不到提及此问题的其他问题。

最有用的评论

这些条目可能包含肯定不会进入应该进入项目存储库的 Pipfile 的凭据。

所有15条评论

这些条目需要进入您的 Pipfile。

@kennethreitz我不认为我已经把我的情况说得很清楚了,所以让我试着用一些我在开始使用 pipenv 时遇到的用例来说服你。
首先,我刚刚开始深入研究 pipenv,它是如何工作的以及它的代码。 我知道您可以在Pipfile指定一个源,我还看到您可以使用命名索引,这看起来类似于~/.pypirc可以完成的操作。

创建一个新的 pipenv 项目/环境

$ mkdir foobar
$ cd foobar
$ pipenv install --verbose requests
⠋New python executable in /home/xxx/.local/share/virtualenvs/foobar-JdBU33Mf/bin/python         
Installing setuptools, pip, wheel...done.                                                      

Virtualenv location: /home/xxx/.local/share/virtualenvs/foobar-JdBU33Mf                         
Installing requests… 
⠙Installing u'requests'
$ "/home/xxx/.local/share/virtualenvs/foobar-JdBU33Mf/bin/pip" install   --verbose   "requests"
-i https://pypi.python.org/simple --exists-action w
Collecting requests
  1 location(s) to search for versions of requests:
  * https://pypi.python.org/simple/requests/
  Getting page https://pypi.python.org/simple/requests/
[...]
Successfully installed certifi-2017.7.27.1 chardet-3.0.4 idna-2.6 requests-2.18.4 urllib3-1.22
Cleaning up...

Adding requests to Pipfile's [packages]…
  PS: You have excellent taste! ✨ 🍰 ✨
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
Updated Pipfile.lock (76e6d4)!

从附加索引安装包

当安装 pypi 不知道的包时,它不会立即工作(它确实可以与 pip 或 pip-tools 一起使用,因为它们使用pip.conf设置)。

$ pipenv install --verbose palantir
Installing palantir…
⠋Installing u'palantir'
$ "/home/hr/.local/share/virtualenvs/foobar-JdBU33Mf/bin/pip" install   --verbose   "palantir" -i https://pypi.python.org/simple --exists-action w
Collecting palantir
  1 location(s) to search for versions of palantir:
[...]
Error:  An error occurred while installing palantir!
  Could not find a version that satisfies the requirement palantir (from versions: )
No matching distribution found for palantir

如果Pipfile设置了新索引并且包与此索引相关联(遵循 https://docs.pipenv.org/advanced.html#specifying-package-indexes),则尝试从无论如何,命令行将首先调用pypi

$ pipenv install --verbose palantir
Installing palantir… 
⠋Installing u'palantir'                                                                        
$ "/home/hr/.local/share/virtualenvs/foobar-JdBU33Mf/bin/pip" install   --verbose   "palantir"
-i https://pypi.python.org/simple --exists-action w                                            
⠋$ "/home/hr/.local/share/virtualenvs/foobar-JdBU33Mf/bin/pip" install   --verbose   "palantir"
 -i https://pypi.priv.xxx/prod/+simple/ --exists-action w                
Collecting palantir                         
  1 location(s) to search for versions of palantir:
[...]
Successfully installed palantir-1.1.5
Cleaning up...

Adding palantir to Pipfile's [packages]…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…

使用pip-tools生成的需求文件

使用pip-tools ,需求文件将以用于安装软件包的索引开头:

#
# This file is autogenerated by pip-compile
# To update, run:
#
#    pip-compile --output-file requirements.txt requirements.in
#
--index-url https://pypi.priv.xxx/prod/+simple/

bcrypt==3.0.0
[...]

使用需求文件(从一个干净的项目开始)时不遵守此设置:

$ pipenv install -r requirements.txt
Requirements file provided! Importing into Pipfile…
Pipfile.lock (c23e27) out of date, updating to (3c7b08)…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
CRITICAL:pip.index:Could not find a version that satisfies the requirement palantir==1.1.5 (from versions: )
Warning: Your dependencies could not be resolved. You likely have a mismatch in your sub-dependencies.
  You can use $ pipenv install --skip-lock to bypass this mechanism, then run $ pipenv graph to inspect the situation.

观察

我觉得在处理索引和用户体验方面存在某种“差距”:

  • 用户在通过命令行安装时无法指定索引(按名称或资源),这会强制用户在Pipfile为索引创建一个条目,并将每个包与一个索引相关联。 对于来自 pypi 的一堆包而只有一个来自私有索引的包,这不是很方便。
  • 从命令行安装软件包时,应该使用的默认索引是什么?
  • 从自定义索引安装包时,无法在命令行中指定它。
  • 在需求文件中指定索引时,它会被忽略。

我正在深入研究代码以提供 PR 来涵盖上述暴露的问题:

  • 在项目初始化时,检查pip.conf以获取自定义索引
  • Pipfile定义默认索引以在未指定时使用
  • 在命令行上按名称或资源提供索引
  • 尊重需求文件中提供的索引并将其添加到Pipfile

如果在需求文件或命令行中使用了索引,但Pipfile不知道该索引,则应添加一个自动名称的条目,该名称类似于 pipenv 中使用的 venv 命名。

为什么我这么在意? 在中国,pypi 并不总是可用或快速(多次超时或死慢),因此拥有像 devpi 这样的索引可以缓存并允许我混合我的私人包是双赢的。 这使我们的开发、测试、docker 构建等更快。

例如,当涉及超时时,这是一个非常经典的行为:

Locking [dev-packages] dependencies…
Locking [packages] dependencies…
Warning: Your dependencies could not be resolved. You likely have a mismatch in your sub-dependencies.
  You can use $ pipenv install --skip-lock to bypass this mechanism, then run $ pipenv graph to inspect the situation.
Could not find a version that matches requests==2.17.3,==2.18.4
Tried: 0.2.0, 0.2.0, 0.2.1, 0.2.1, 0.2.2, 0.2.2, 0.2.3, 0.2.3, 0.2.4, 0.2.4, 0.3.0, 0.3.0, 0.3.1, 0.3.1, 0.3.2, 0.3.2, 0.3.3, 0.3.3, 0.3.4, 0.3.4, 0.4.0, 0.4.0, 0.4.1, 0.4.1, 0.5.0, 0.5.0, 0.5.1, 0.5.1, 0.6.0, 0.6.0, 0.6.1, 0.6.1, 0.6.2, 0.6.2, 0.6.3, 0.6.3, 0.6.4, 0.6.4, 0.6.5, 0.6.5, 0.6.6, 0.6.6, 0.7.0, 0.7.0, 0.7.1, 0.7.1, 0.7.2, 0.7.2, 0.7.3, 0.7.3, 0.7.4, 0.7.4, 0.7.5, 0.7.5, 0.7.6, 0.7.6, 0.8.0, 0.8.0, 0.8.1, 0.8.1, 0.8.2, 0.8.2, 0.8.3, 0.8.3, 0.8.4, 0.8.4, 0.8.5, 0.8.5, 0.8.6, 0.8.6, 0.8.7, 0.8.7, 0.8.8, 0.8.8, 0.8.9, 0.8.9, 0.9.0, 0.9.0, 0.9.1, 0.9.1, 0.9.2, 0.9.2, 0.9.3, 0.9.3, 0.10.0, 0.10.0, 0.10.1, 0.10.1, 0.10.2, 0.10.2, 0.10.3, 0.10.3, 0.10.4, 0.10.4, 0.10.6, 0.10.6, 0.10.7, 0.10.7, 0.10.8, 0.10.8, 0.11.1, 0.11.1, 0.11.2, 0.11.2, 0.12.0, 0.12.0, 0.12.1, 0.12.1, 0.13.0, 0.13.0, 0.13.1, 0.13.1, 0.13.2, 0.13.2, 0.13.3, 0.13.3, 0.13.4, 0.13.4, 0.13.5, 0.13.5, 0.13.6, 0.13.6, 0.13.7, 0.13.7, 0.13.8, 0.13.8, 0.13.9, 0.13.9, 0.14.0, 0.14.0, 0.14.1, 0.14.1, 0.14.2, 0.14.2, 1.0.0, 1.0.0, 1.0.1, 1.0.1, 1.0.2, 1.0.2, 1.0.3, 1.0.3, 1.0.4, 1.0.4, 1.1.0, 1.1.0, 1.2.0, 1.2.0, 1.2.1, 1.2.1, 1.2.2, 1.2.2, 1.2.3, 1.2.3, 2.0.0, 2.0.0, 2.0.0, 2.0.0, 2.0.1, 2.0.1, 2.0.1, 2.0.1, 2.1.0, 2.1.0, 2.1.0, 2.1.0, 2.2.0, 2.2.0, 2.2.0, 2.2.0, 2.2.1, 2.2.1, 2.2.1, 2.2.1, 2.3.0, 2.3.0, 2.3.0, 2.3.0, 2.4.0, 2.4.0, 2.4.0, 2.4.0, 2.4.1, 2.4.1, 2.4.1, 2.4.1, 2.4.2, 2.4.2, 2.4.2, 2.4.2, 2.4.3, 2.4.3, 2.4.3, 2.4.3, 2.5.0, 2.5.0, 2.5.0, 2.5.0, 2.5.1, 2.5.1, 2.5.1, 2.5.1, 2.5.2, 2.5.2, 2.5.2, 2.5.2, 2.5.3, 2.5.3, 2.5.3, 2.5.3, 2.6.0, 2.6.0, 2.6.0, 2.6.0, 2.6.1, 2.6.1, 2.6.1, 2.6.1, 2.6.2, 2.6.2, 2.6.2, 2.6.2, 2.7.0, 2.7.0, 2.7.0, 2.7.0, 2.8.0, 2.8.0, 2.8.0, 2.8.0, 2.8.1, 2.8.1, 2.8.1, 2.8.1, 2.9.0, 2.9.0, 2.9.0, 2.9.0, 2.9.1, 2.9.1, 2.9.1, 2.9.1, 2.9.2, 2.9.2, 2.9.2, 2.9.2, 2.10.0, 2.10.0, 2.10.0, 2.10.0, 2.11.0, 2.11.0, 2.11.0, 2.11.0, 2.11.1, 2.11.1, 2.11.1, 2.11.1, 2.12.0, 2.12.0, 2.12.0, 2.12.0, 2.12.1, 2.12.1, 2.12.1, 2.12.1, 2.12.2, 2.12.2, 2.12.2, 2.12.2, 2.12.3, 2.12.3, 2.12.3, 2.12.3, 2.12.4, 2.12.4, 2.12.4, 2.12.4, 2.12.5, 2.12.5, 2.12.5, 2.12.5, 2.13.0, 2.13.0, 2.13.0, 2.13.0, 2.14.0, 2.14.0, 2.14.0, 2.14.0, 2.14.1, 2.14.1, 2.14.1, 2.14.1, 2.14.2, 2.14.2, 2.14.2, 2.14.2, 2.15.1, 2.15.1, 2.15.1, 2.15.1, 2.16.0, 2.16.0, 2.16.0, 2.16.0, 2.16.1, 2.16.1, 2.16.1, 2.16.1, 2.16.2, 2.16.2, 2.16.2, 2.16.2, 2.16.3, 2.16.3, 2.16.3, 2.16.3, 2.16.4, 2.16.4, 2.16.4, 2.16.4, 2.16.5, 2.16.5, 2.16.5, 2.16.5, 2.17.0, 2.17.0, 2.17.0, 2.17.0, 2.17.1, 2.17.1, 2.17.1, 2.17.1, 2.17.2, 2.17.2, 2.17.2, 2.17.2, 2.17.3, 2.17.3, 2.17.3, 2.17.3, 2.18.0, 2.18.0, 2.18.0, 2.18.0, 2.18.1, 2.18.1, 2.18.1, 2.18.1, 2.18.2, 2.18.2, 2.18.2, 2.18.2, 2.18.3, 2.18.3, 2.18.3, 2.18.3, 2.18.4, 2.18.4, 2.18.4, 2.18.4

@kennethreitz
不。 例如,我住在中国。 pypi.python.org的速度通常低于50k/s,我必须设置一个全球中国镜像。 或者我会看到很多

  File "d:\python27\lib\site-packages\pipenv\patched\pip\_vendor\requests\packages\urllib3\response.
py", line 324, in read
    flush_decoder = True
  File "d:\python27\lib\contextlib.py", line 35, in __exit__
    self.gen.throw(type, value, traceback)
  File "d:\python27\lib\site-packages\pipenv\patched\pip\_vendor\requests\packages\urllib3\response.
py", line 246, in _error_catcher
    raise ReadTimeoutError(self._pool, None, 'Read timed out.')
pip._vendor.requests.packages.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='pypi.py
thon.org', port=443): Read timed out.

所以,你的意思是每次我使用 pipenv 都需要为它写一个 pip.conf[Pipfile] 吗? 这对我来说是不可接受的。

这些条目可能包含肯定不会进入应该进入项目存储库的 Pipfile 的凭据。

@eromoe @hrbonz所以是pipenv先解决pypi而不是私服的问题吗?

对我来说,是的。 我真的需要一个全局镜像设置。

pip.conf 如下:

  1. 首先读取站点范围的文件,然后
  2. 读取每个用户的文件,最后
  3. 读取 virtualenv 特定文件。

尊重 pip.conf 意味着 pip 用户可以无缝切换到 pipenv。

我喜欢能够将这些配置放在Pipfile的想法(以便轻松地将配置共享给其他开发人员),但是 pipenv 绝对还必须尊重pip.conf (对于任何未在点文件)。

@erinxocon这是我发现的问题之一。 我一直忙于工作,但希望在下周之前推动第一个 PR。

嗨, @kennethreitz感谢您的精彩项目。

我有一个问题,你会在讨论中提出论点后重新考虑你在这个问题上的立场吗?

我有另一个与 pip.conf 非常相似的用例,并且在单独的 pip.conf 文件中具有凭据对于在 CI/CD 管道和本地开发机器上进行可预测的构建是有效的。

@hrbonz现在我找到了只使用 pip 中的$PIP_INDEX_URL env 变量的解决方案,直到 pipenv 支持 pip.conf 文件。 那些$PIP_VARIABLE现在可以从.env文件中获取。

我认为结合 pypa/pip#3728 和自定义索引将是私有索引的 _the_ 解决方案,而不会暴露凭据。 也在#1406 中发表了评论。

如果您只需要索引名称和 URL(例如使用devpi ),这是一种解决方法。 每当您想要创建具有自定义索引名称和 URL 但其他方面都是原始的 Pipfile 时,您可以调用此 shell 函数。

pipenv_init() {
  # pipenv issue #856: pipenv doesn't respect pip.conf
  # https://github.com/pypa/pipenv/issues/856

  # This function accepts one optional argument: the path to the pipenv
  # executable. If not set or empty, defaults to PATH lookup.
  local PIPENV="${1:-pipenv}"
  if ! command -v -- "${PIPENV}" > /dev/null; then
    >&2 printf '%s\n' 'pipenv not found'
    return 1
  fi

  # Check for required environment variables.
  if [[ -z "${PIPENV_INDEX_NAME-}" ]] || [[ -z "${PIPENV_INDEX_URL-}" ]]; then
    >&2 printf '%s\n' 'PIPENV_INDEX_{NAME,URL} env vars must be set and not empty'
    return 1
  fi

  # Create fresh Pipfile and virtualenv.
  #
  # While doing so, move requirements.txt out of the way so pipenv
  # doesn't attempt to populate the virtualenv before we have a chance
  # to modify Pipfile.
  # https://github.com/pypa/pipenv/blob/v9.0.3/pipenv/cli.py#L308-L330
  # https://github.com/pypa/pipenv/blob/v9.0.3/pipenv/project.py#L117-L119
  # https://github.com/pypa/pipenv/blob/v9.0.3/pipenv/project.py#L231-L240
  # https://github.com/pypa/pipenv/blob/v9.0.3/pipenv/utils.py#L1112-L1124
  local TEMP_REQUIREMENTS_TXT
  "${PIPENV}" --rm || true
  rm -f -- Pipfile Pipfile.lock
  if [[ -f requirements.txt ]]; then
    TEMP_REQUIREMENTS_TXT="$(mktemp)"
    mv -- requirements.txt "${TEMP_REQUIREMENTS_TXT}"
  fi
  "${PIPENV}" install
  if [[ -n "${TEMP_REQUIREMENTS_TXT}" ]]; then
    mv -- "${TEMP_REQUIREMENTS_TXT}" requirements.txt
  fi
  rm -- Pipfile.lock

  # Within Pipfile's `[[source]]` section, set `name` to
  # `${PIPENV_INDEX_NAME}` and `url` to `${PIPENV_INDEX_URL}`.
  local TEMP_PIPFILE="$(mktemp)"
  < Pipfile \
      sed \
      -e '/^\[\[source\]\]$/,/^\[/ { s|^\(name = \).*|\1"'"${PIPENV_INDEX_NAME}"'"| ; s|^\(url = \).*|\1"'"${PIPENV_INDEX_URL}"'"| ; }' \
    > "${TEMP_PIPFILE}"
  mv -- "${TEMP_PIPFILE}" Pipfile
}

先生,认真的。 我有一个直接受此问题影响的简单用例。

我有一个使用 pipenv 的项目。 我在家里和工作中都写了这个项目。
在家里,我没有问题。 在工作中,我必须使用内部pipy索引。

由于 Pipfile 已提交并推送到 git,因此当我从家里跳到工作时,我无法不断更改它。 我想要一个外部配置,向 pipenv 发出信号,表明我必须使用另一个索引。

将此配置放在 Pipfile 中不起作用。

有任何更新吗?

@hrbonz @ninrod @GhostofGoes在 #1769 和 #1809 中修复——Pipfiles 中的环境变量现在在运行时扩展

感谢大家的耐心等待,我们的首要任务是代码库的核心功能,因此像这样的功能往往会被遗漏。 总是乐于讨论我们目前没有优先考虑的项目的贡献!

在此问题得到解决之前,我能想到的唯一替代方法是覆盖 PyPi URL,以便所有流量都转发到 PyPi 的内部镜像(例如,Artifactory 或诸如此类)。 由于 PyPi 无论如何在内部受到限制。

此页面是否有帮助?
0 / 5 - 0 等级