Virtualenv: [RFC] 下一代 virtualenv

创建于 2019-06-10  ·  37评论  ·  资料来源: pypa/virtualenv

1362年的讨论之后,很明显,为了使 virtualenv 能够支持新世界(Windows 应用商店安装、venv 解释器),我们需要一些重大的方向改变。

这是我对继续这个项目的建议。 这将是该项目的主要重构,但计划保持现有的接口兼容性。

项目目标

  • 创建系统(调用程序)python 的新副本,该副本具有自己的自定义、可单独控制的包列表
  • 在所有受支持的 Python 环境中尽可能保持一致的界面和行为(例如,将新的 venv 功能向后移植到旧的解释器),
  • 可扩展(创建和 shell 激活脚本都支持明智),
  • PyPi 包(使用解释器进行带外升级的能力)。

计划功能

  • 通用pypi轮
  • 跨平台- Windows、所有 UNIX 风格、MacOS。
  • 支持大多数支持的pythons ,支持Python版本的初始池: python2.7 , python3.4 , python3.5 , python3.5 , pypy3 , pypy2 (希望在某个时候使用 IronPython 和 Jython - 我们应该支持其他任何东西吗?)
  • 两年的支持
  • 能够指定目标 python (我们将使用 PEP-514/PEP-394/explicit 链接来发现这些版本)并创建虚拟环境,即使该目标没有安装这个包
  • 更喜欢内置的 venv :如果目标 python 有 venv,我们将使用它创建环境(然后对其执行后续操作以促进我们提供的其他保证)
  • 提供种子包的能力(在创建虚拟环境后,这些包将被安装):

    • 我们接受 PEP-508 格式,
    • 能够联系 PyPi 以获取最新的匹配规范,或仅离线(此类安装包必须离线)
    • 默认情况下pip , setuptoolswheel是种子包(这些包也作为离线轮包自动注入)
  • 接口

    • CLI 界面( python -m virtualenvvirtualenv
    • 滚轮接口 (env PYTHONPATH=/t/path/to/virtualenv.whl python -m virtualenv ) - 万向轮,
    • zipapp界面,
    • API接口: import virtualenv; virtualenv.create("target")
  • shell 支持- 激活/停用脚本和提示环境变量 - 默认情况下我们生成:

    • bash / zsh,
    • csh,
    • 鱼,
    • 电源外壳,
    • xonsh,
    • 指令,
    • Python,
    • 一个定义良好的 API 来安装自定义 shell 脚本(可能作为插件系统的一部分)。
  • 三层配置系统,每个选项确定如下:

    • 首先,ini 配置支持(存在于用户主页中的全局 ini 配置),
    • 第二,具有VIRTUALENV_前缀的环境变量,
    • 最后,命令行选项(argparse 驱动)
  • 插件系统这些是用户可以注入自己的自定义逻辑的扩展点,并生成 virtualenv 的扩展版本(当前引导逻辑):

    • 扩展解析器(添加您自己的自定义 CLI 标志),
    • 调整选项(在 CLI 解析后更改选项),
    • 安装后(虚拟环境创建完成后执行一些操作)
  • virtualenv 支持- 即使调用 python 是一个 virtualenv 创建的 python,操作也应该工作,
  • venv 支持- 即使调用 python 是一个 virtualenv 创建的 python,操作也应该工作,
  • 可重定位的环境:只要根 python 没有从操作系统中删除,环境就应该继续工作(例如,重命名根环境文件夹不应该破坏事物)。

与 stdlib venv 的区别

我们与标准库 venv 有何不同? virtualenv 包计划是:

  • PyPi 包,因此将更频繁地升级,更容易保持最新状态并提供跨 python 的功能奇偶校验,
  • 内置解释器发现和交叉解释器支持,
  • 更多接口(zippapp、wheel、安装包),
  • 更容易定制 - 插件系统,
  • 成为新功能的试验场(这可能会使其成为 venv),
  • 更长的 EOL。

通常,提供需要虚拟环境作为 API 的其他下游工具(例如 tox、pre-commit、pipenv、pipsi、pipx)所需的功能。

PyPy 成员(以及公众也请)分享您的想法,如果您同意,则加一个。 @pfmoore @dstufft @di @pradyunsg @cjerdonek @ncoghlan @jaraco @techalchemy @uranusjr @pganssle @benoit-pierre @dholth @lkollar @takluyver @zooba

最有用的评论

因此,重写达到了一种状态,我觉得人们可以查看它并提供一些反馈。 如果您有空闲时间来帮助解决此问题,请与我联系; 计划是月底发布🤞 注意https://github.com/pypa/virtualenv/milestone/7还需要实现,但是,核心思想就在那里。

附注。 在https://github.com/pypa/virtualenv/pull/1481/下创建了一个反馈 PR

所有37条评论

一个雄心勃勃的提议!

ini 配置支持(用户主页中的全局 ini 配置)

考虑使用 appdirs(或类似的)来发现平台首选位置的配置。

appdirs 也可能是一个选择,不过那样我们就需要开始将东西供应到我们的包中的业务。 公平地说,这其中的 70% 已经完成,只需要更好的重组。

为什么是供应商而不是仅仅依赖它? (并不是说供应商很难,它只是一个文件)。 IMO,我们真的需要接受(除了 pip 的显着例外)打包工具确实应该像任何其他应用程序一样构建。 如果依赖关系非常困难以至于 PyPA 应用程序避免它们,这说明我们在使用户开发应用程序变得容易的情况下做得有多好?

(抱歉,这里没有对 virtualenv 提出一些重要的观点,我只是看到很多人说“添加 PyPI 依赖关系没什么大不了的”,然后我在销售方面工作的 PyPA 工具让我想知道......) .

我认为如果没有 vendoring 交叉解释器功能将很难。 例如,为没有安装 virtualenv 的解释器创建一个虚拟环境。

PYTHONPATH=/t/path/to/virtualenv.whl python -m virtualenv

呃,这意味着我们不能依赖来自 virtualenv 的任何附加包。 既然我们将提供一个 zipapp,这会启用哪些用例?

@gaborbernat你的意思是-p选项? 大概吧。 这似乎正是 zipapps 旨在帮助解决的那种情况,但没有人真正做过很多工作来解决使其运行良好的细节。

来自@pradyunsg

呃,这意味着我们不能依赖来自 virtualenv 的任何附加包

实际上,正如@gaborbernat所说, -p选项可能意味着:-( 但我确实想知道为什么我们需要“wheel on PYTHONPATH ”选项以及 zipapp - 特别是考虑到轮子PYTHONPATH通常不受支持(由于通常的 pip 引导原因,我们在 virtualenv 内部使用它们 - pip 几乎是所有事物的例外 ;-))

两年的支持

唔...

我担心的是,这种网络效应可能会导致采用较新版本 Python 的速度减慢,以及支持的 Python 数量的组合爆炸式增长。 CPython 正在讨论 3.9 的不同发布节奏,因此 2 年甚至可能比核心开发人员的某些版本可能更长。

也就是说,我不想阻止这一点,但主要是确保我表达了我不热衷于这样做。

(希望在某个时候使用 IronPython 和 Jython - 我们应该支持其他任何东西吗?)

确实。 @gaborbernat可能知道我会这么说——拥有这些会很好,但我很确定更熟悉实现的人最适合这样做。 至少,就长期支持而言,理想情况下,还包括首先获得良好支持的工作(CI、测试等)。

首先,ini 配置支持(存在于用户主页中的全局 ini 配置),

我有偏见——我真的很想看到这是 TOML。 :)

(我还没有完全处理这个因为我必须去某个地方——但这看起来确实是一个伟大的总体目标!)

由于交叉解释器的特性,我们已经不能真正依赖额外的包,所以我不认为这是一个主要缺点,我希望有一个简单的无安装/依赖的方式来运行虚拟环境(当人们需要从节点包调用我们)。 鉴于除了 zipapp 看起来便宜之外,它不会花费我们太多的费用。

更喜欢内置的 venv:如果目标 python 有 venv,我们将使用它创建环境(然后对其执行后续操作以促进我们提供的其他保证)

我不确定我是否理解这样做的理由。 看起来它会使virtualenv的维护变得更加困难并且会使最终用户更难以理解行为。 setuptools已经在走另一条路,试图吸收distutils而不是继续修补它。

@pganssle范围不同,问题空间也不同。 virtualenv问题是系统经常对系统包施加额外的限制,所以他们对内置的 venv 打补丁以遵守这些限制。 复制所有这些将很困难,参见例如#1362。

FWIW 我认为使用内置的venv包进行隔离是正确的想法,它内置在实际的解释器中(而不是只是一个 stdlib 模块的 distutils),所以它可以做比virtualenv更干净的事情

Virtualenv 也不需要猴子补丁任何东西,它只会使用应该没问题的公共 API。

FWIW 我建议检查我的旧重写 virtualenv 分支,它已经做了很多这些事情。

我可能会建议一个插件系统对 virtualenv 不是非常有用,但最多可能只有一个钩子,一个创建后的步骤,即使这样你也可以只需要安装一个列表。

此外,您仍然可以“自然地”依赖东西并仍然使用 zipapps,您只需要在 zipapp 本身内进行供应商。 我建议放弃在目标 python 下重新执行选项,这是一件坏事,可以做得更干净。

697 -- @dstufft的旧公关

PYTHONPATH=/t/path/to/virtualenv.whl python -m virtualenv

OTOH,无论如何我们可能不应该这样做 - https://www.python.org/dev/peps/pep-0427/#is -it-possible-to-import-python-code-directly-from-车轮文件

@pradyunsg那么还有没有其他方法可以引导 pip 而不将轮子放在路径上?

引导 pip 可能没问题 - 这就是 virtualenv 现在使用的1 。 但我强烈建议将它用于 pip,而不是作为运行 virtualenv 本身的一种方式。

1但我会避免使用任何复杂的功能 - 使用 PATH 上的轮子从该轮子安装 pip 几乎可以保证没问题。 但是,例如,如果您使用这样的轮子访问互联网,您可能会遇到问题,因为我认为 certifi 需要将其嵌入的证书包作为实际文件(但我可能错了,这从来没有给我带来问题,但我知道get-pip.py明确地从轮子中提取证书来解决这一点。

我们为什么不将 pip 作为zipapp发货? 据我了解,这将避免这种需求,并且 zipapp 支持 python 2.7 🤔

@gaborbernat你试过了吗? 它有效吗? 如果您概述的方法适用于 Windows,我最初没有任何顾虑,但@uranusjr可能会有反馈。 我唯一的评论与@dstuff 一致,也就是说——

我们不将 pip 作为 zipapp 发送的任何原因?

因为在某些情况下,pip 不会直接从 zipfile(或轮子,这是同一件事)运行,正如我上面所说的。 在 99%(警报 - 编造数字)的情况下,它可以工作,但有时证书包需要是真实文件这一事实很重要。

它可能会做工精细捆绑PIP作为一个毒刃不过,因为SHIV运行前解包zipapp,正是为了避免出现从zip中断运行的极端情况。 不过,据我所知,没有人尝试过。

像往常一样,它没有发生的主要原因是:

  1. 没有人想到。
  2. 没有人有时间/动机去做。
  3. 目前的方法效果很好,还有更大的鱼可以煎。

那么还有没有其他方法可以在不将轮子放在路径上的情况下引导 pip 呢?

我认为我们在这里不需要 - virtualenv 正在使用 pip 轮从自身 IIRC 安装,这应该可以正常工作。 正如@pfmoore所说,

目前的方法效果很好,还有更大的鱼可以煎。

这比其他海事组织要多得多。 我们可以,但还有更多有影响力的问题需要解决。 :)

我曾经有一个 PR 将 pip 构建为 zip 应用程序,它可以工作,但 IIRC 我必须对 pip 进行更改以使其功能齐全。

现在这可能有点复杂,因为 pip 确实将自身作为 PEP 517 的子进程调用。我不确定,但这绝对值得探索。

在这一点上,shiv(或其他自解压选项)比尝试将 pip 工作到 zip-runnable 更适合 pip。 但我认为在这一点上这不是特别重要的事情。 ensurepip 已经采用了轮子路径,为什么不这样做呢。 在我们炒完所有大鱼之后,可以探索替代的 pip 引导,并有可能将其贡献回 stdlib。

在我们炸完所有更大的鱼后,可以探索替代的 pip bootstrapping

听起来像是一个计划[我们已经在遵循这个计划。 ;)]

感谢您提供链接,根据反馈,我已经在https://github.com/gaborbernat/virtualenv/tree/rewrite/src/virtualenv开始了一些初步工作20.0.0

+1 用于使用 venv(如果存在)。 这将使 PyPy 的用例更简单。

因此,重写达到了一种状态,我觉得人们可以查看它并提供一些反馈。 如果您有空闲时间来帮助解决此问题,请与我联系; 计划是月底发布🤞 注意https://github.com/pypa/virtualenv/milestone/7还需要实现,但是,核心思想就在那里。

附注。 在https://github.com/pypa/virtualenv/pull/1481/下创建了一个反馈 PR

功能请求:提供定义自定义环境变量的机制,例如将env.txt文件放置在 venv bin 目录中,格式为:

VARNAME=value
OTHERVAR=othervalue

我不认为我理解你的用例? 这些环境变量将如何使用、设置、何时使用?

编辑。 NM。 我看到你在https://github.com/pypa/virtualenv/issues/1124 上进行了扩展

一个小更新; 我已经设法解决了大多数阻塞问题,除了两个仍然需要一些爱的问题:测试包括标头 + 缓存 python 询问调用,并在应用程序数据上应用了一些锁,因此我们可以并行创建虚拟环境(到不同的位置)。 按照目前的速度,我可能会晚几天……但绝对应该在 2 月 7 日之前结束。

我们在推出方面有什么计划? 我们会在主要版本之前发布测试版吗?

是的,想在周一发布一些东西...然后暂时留出一周的反馈,修复...然后用重写和发布替换 master。

我不是 100% 确定一周就足够了,我们绝对应该通过多个渠道进行沟通,希望人们试用 Beta。

那里的关键字是试探性的。 我在这里很乐观,考虑到我付出的努力,我不希望出现重大问题,但是🤷‍♂

随着测试版的推出,我觉得这个问题就是目的。 我将结束,我们可以讨论更多专注于专门问题的问题。

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

相关问题

asottile picture asottile  ·  5评论

asottile picture asottile  ·  6评论

manthey picture manthey  ·  4评论

earthgecko picture earthgecko  ·  4评论

oconnor663 picture oconnor663  ·  3评论