将Python版本更改为3.x

94
根据 poetry 文档,设置新项目的正确方法是使用 poetry new poetry-demo。但是这会创建一个基于已停用的 python 2.7 的项目,并创建以下 toml 文件。
[tool.poetry]
name = "poetry-demo"
version = "0.1.0"
description = ""
authors = ["Harsha Goli <harshagoli@gmail.com>"]

[tool.poetry.dependencies]
python = "^2.7"

[tool.poetry.dev-dependencies]
pytest = "^4.6"

[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"
我该如何将它更新到3.7?只需将 python = "^2.7" 更改为 python = "^3.7" 即可。但是,运行 poetry install 后会出现以下错误:
[SolverProblemError]
The current project's Python requirement (2.7.17) is not compatible with some of the required packages Python requirement:
  - zipp requires Python >=3.6

Because no versions of pytest match >=4.6,<4.6.9 || >4.6.9,<5.0
 and pytest (4.6.9) depends on importlib-metadata (>=0.12), pytest (>=4.6,<5.0) requires importlib-metadata (>=0.12).
And because no versions of importlib-metadata match >=0.12,<1.5.0 || >1.5.0
 and importlib-metadata (1.5.0) depends on zipp (>=0.5), pytest (>=4.6,<5.0) requires zipp (>=0.5).
Because zipp (3.1.0) requires Python >=3.6
 and no versions of zipp match >=0.5,<3.1.0 || >3.1.0, zipp is forbidden.
Thus, pytest is forbidden.
So, because poetry-demo depends on pytest (^4.6), version solving failed.

创建新项目时,Poetry似乎会插入Poetry本身正在运行的Python版本。因此,您应该检查为什么在Python 2上运行poetry new poetry-demo,而不是3。 - Thomas
12个回答

105

诗歌使得在不同的Python版本或虚拟环境中操作变得非常容易。按照Poetry文档推荐的方式指定您的Python版本是:

poetry env use /path/to/preferred/python/version

在Linux上,您可以通过运行which python3.7命令来获取Python版本的路径,在Windows上则可以使用py -0p命令。


23
与pyenv一起使用时,您可以执行类似于 pyenv local 3.7 的操作,然后执行 poetry env use $(which python) - FiddleStix
2
还要注意,您可以引用主要版本:poetry env use $(which python3.9) - Nae
1
请注意,您仍需要使用 poetry env remove 2.7 删除虚拟环境,然后运行上述命令,以便Poetry使用新的Python版本。 - smac89

64

使用:

poetry env use 3.9
或者
poetry env use $(which python3.9)

由于某些原因,在Python 3.9上不起作用。尽管在pyproject.toml文件中已经明确声明了版本要求,但令人遗憾的是,需要手动强制执行。


3
poetry env use 3.9 对我来说起到了将 Python 版本从 3.10 降级到 3.9 的作用。 - jeffmcc
3
似乎这是一个 bug,将其在 toml 文件中更改并不意味着会生效。 - Jonathan

49

每当您手动更改pyproject.toml中的依赖项时,您必须注意以下几点:

  1. 之后运行poetry lock --no-update。这样做的原因是,如果找到了poetry.lock而不是pyproject.tomlpoetry install将其作为输入。

  2. 如果更改了python版本并使用项目内的虚拟环境,请在运行poetry install之前删除.venv。poetry不会更改仅一次创建的venv的python版本,因为它使用python版本本身来创建虚拟环境。


12

有趣的是,由于工具本身依赖的一个缺失的软件包并继续安装一个损坏的虚拟环境,诗歌正在默默地失败。以下是如何修复它。

sudo apt install python3-venv
poetry env remove python3
poetry install

我不得不移除pytest,然后使用poetry add pytest重新安装。

编辑:当我将项目从python3.7升级到python3.8时,我再次遇到了这个问题-这时你需要安装python3.8-venv而不是安装python3-venv


这个可行!除非我重新安装pytest,因为它没有被首先安装! - Abbas
对我来说也是一样,我不得不重新安装一个不再兼容的包:从poetry toml中手动删除它,然后通过poetry add {module}添加它。 - alanionita

9

我遇到了同样的问题。我通过修改文件 /home/nordman/.poetry/bin/poetrynordman是我的本地用户名),解决了这个问题。

只需将第一行 #!/usr/bin/env python 更改为 #!/usr/bin/env python3


3
当你决定升级诗歌时会发生什么?这种变化是否会持续下去? - at0S
我还没有升级诗歌。 - NordMan

8

我尝试了所有我能找到的解决方案,但无法让poetry使用升级后的Python版本。最终找到了可行的方法。

tldr;

  1. 运行poetry config virtualenvs.in-project true以使用本地虚拟环境。
  2. 运行deactivate退出任何已存在的虚拟环境。
  3. 运行poetry shell激活新的本地虚拟环境。

所以这里是我看到的:

(my-project) ~/I/my-project ❯❯❯ poetry env info

Virtualenv
Python:         3.9.6
Implementation: CPython
Path:           /Users/my-user/.local/share/virtualenvs/my-project-some-hash
Valid:          True

System
Platform: darwin
OS:       posix
Python:   /usr/local/opt/python@3.9/Frameworks/Python.framework/Versions/3.9

我尝试运行 poetry env remove python,但出现了错误:


(my-project) ~/I/my-project ❯❯❯ poetry env remove python

  ValueError

  Environment "my-project-some-hash-py3.9" does not exist.

同时,我在某处看到建议使用本地虚拟环境,并通过设置该属性来实现,因此我这样做了:

poetry config virtualenvs.in-project true

这并没有解决我的问题,但我意识到更改此设置不会自动生效,因为我已经处于另一个非本地的虚拟环境中(请参见上面的poetry env info输出)。

因此,根据文档,我运行了deactivate以停用当前虚拟环境。

现在,我看到了这个:

~/I/my-project ❯❯❯ poetry env info

Virtualenv
Python:         3.10.1
Implementation: CPython
Path:           NA

System
Platform: darwin
OS:       posix
Python:   /Users/my-user/.pyenv/versions/3.10.1

现在我运行了poetry shell命令来创建一个新的虚拟环境,并且它已经使用了新的本地虚拟环境设置:

~/I/my-project ❯❯❯ poetry shell
Creating virtualenv my-project in /Users/my-user/projects/my-project/.venv
Spawning shell within /Users/my-user/projects/my-project/.venv

最终,我看到了我期待的升级版Python!

(.venv) ~/I/my-project ❯❯❯ poetry run python -V
Python 3.10.1

更新:在我完成所有上述操作后,我注意到 poetry env use 可以正常工作!
(.venv) ~/I/my-project ❯❯❯ python -V
Python 3.10.1
(.venv) ~/I/my-project ❯❯❯ poetry env use 3.9.6
Recreating virtualenv my-project in /Users/my-user/projects/my-project/.venv
Using virtualenv: /Users/my-user/projects/my-project/.venv
(.venv) ~/I/my-project ❯❯❯ python -V
Python 3.9.6


在我的情况下,有帮助的是取消设置虚拟环境变量,例如 unset VIRTUAL_ENV - undefined

7

您可以在pyproject.toml文件中进行更改,并执行以下命令 "poetry env use 3.x",这对我很有用。


1
我使用 virtualenvwrapper,其他解决方案都没有这个好用。+1 - nocibambi

4
您可以简单地使用pyenv。在您的项目内创建.python-version文件,poetry将匹配您指定的 Python 版本。
# check current python version (set up globally)
❯ pyenv version
3.9.0 (set by /Users/tomasz.zieba@showpad.com/.python-version)

# create .python-version file for project
❯ pyenv local 3.9.0

# check python version again (now it's set up locally)
❯ pyenv version
3.9.0 (set by /Users/tomasz.zieba@showpad.com/Documents/myproject/.python-version)

❯ poetry lock
(...)

❯ poetry run python --version
Python 3.9.0

1
poetry 工具可以自行管理 Python 版本。你也可以手动进行管理! - ssoto

3

我在我的 MacBook 上遇到了完全相同的问题!因此,为了使这个实用,首先让我们看一下 MacBook 的默认 Python 是什么。我正在运行 macOS Big Sur 11.2.1 (20D74)。在终端中:

python --version                                                                                                                  
Python 2.7.16

接下来,让我们安装poetry。我使用了poetryGitHub安装脚本。使用此脚本是安装poetry推荐方法(虽然我认为从互联网传输脚本到python解释器并非最佳实践)。 安装脚本相当智能:它会尝试检测系统上可用的python版本:

def _which_python(self):
    """Decides which python executable we'll embed in the launcher script."""
    allowed_executables = ["python", "python3"]
    if WINDOWS:
        allowed_executables += ["py.exe -3", "py.exe -2"]
...

由于默认的Python版本是2.7.16,在调用python时返回此版本,因此~/.poetry/bin中的条目如下所示:

#!/usr/bin/env python

这里提供给您!默认情况下,python 将被写入到 pyproject.toml 文件中,因此您需要进行额外的操作以确保:a) python3 是项目依赖;b)虚拟环境将使用 python3 作为 python 解释器。

就像 @mfalade 提到的,您可以使用 poetry env 设置环境:

poetry env use /path/to/python3

同时也要修改 pyproject.toml ,并添加以下内容:

...
[tool.poetry.dependencies]
python = "^3.9"
...

从这一点开始,您就可以使用poetry来为项目创建虚拟环境了,它将使用python3,文件中指定了依赖关系...然后草又变绿了。

但是我们能否默认使用python3呢?GitHub上有一个富有洞见的讨论串另一个讨论串。如果您回顾上面安装脚本中的代码片段,就会想知道为什么不先检查python3,再检查python,特别是考虑到这是Windows安装的确切顺序。好吧,您并不孤单,我也在想 ;)

我不建议直接编辑~/.poetry/bin/poetry文件,因为这个文件是安装脚本生成的(那么如果再次运行安装脚本会发生什么呢?而且还会再次覆盖掉)。

实际上,这只是一个小问题,知道了这个工具如何运作,解决起来也很容易。不过,我希望安装指南中可以提到这一点...

无论如何,希望对您有所帮助!


1
我个人使用的方式非常有效: 使用pyenv管理Python版本,以及它的插件pyenv-virtualenv来管理这些版本作为虚拟环境,然后使用Poetry来自动从中选择版本并管理依赖项:
使用pyenv安装你想要使用的Python版本:
pyenv install -v 3.7

基于已安装的3.7版本创建虚拟环境。 您需要使用pyenv-virtualenv插件。

pyenv virtualenv 3.7 arshbot_3.7_virtualenv

假设有一个名为arshbot_proj的项目。在$HOME目录中工作:

mkdir ~/arshbot_proj
cd ~/arshbot_proj

使用刚创建的虚拟环境。将此项目附加到它上面。 下面创建一个 .python-version 文件,指示 arshbot_3.7_virtualenv。
pyenv local arshbot_3.7_virtualenv

使用poetry init命令在目录中创建pyproject.toml文件,使用arshbot_3.7_virtualenv虚拟环境。 你也可以使用poetry new代替poetry init来创建项目结构,同时在pyproject.toml旁边创建项目,而不是在以上步骤中先创建项目。 当这个目录里有pyproject.toml和.python-version两个文件时,Poetry将自动选择使用arshbot_3.7_virtualenv,Python版本为3.7。 Poetry还将使用此虚拟环境在~/.pyenv/versions/3.7/envs/arshbot_3.7_virtualenv/lib/python3.7/site-packages安装软件包。
poetry init

就是这样。每次在激活的虚拟环境中从该目录运行Poetry时,它都会自动选择3.7版本。对于不同的Python版本,只需重复上述步骤,将3.7替换为新版本即可。

虚拟环境将出现两次:作为虚拟环境的envs目录中,也作为版本的versions目录中,当Poetry安装包时,其内容会被复制。

BONUS: 我们尝试使用不同的方法来使其更加清晰,概念相同,结果相同。 由于默认情况下,如果您没有更改PYENV_ROOT,则pyenv会在~/.pyenv/versions中安装每个Python版本: 如果您希望系统版本(随您的发行版一起提供)成为您可以选择的版本之一,请使用venv模仿pyenv安装Python版本,现在将其称为system_ver,以代替3.7。由于它已经存在于系统中,我们不需要pyenv下载它,我们将其复制到我们的versions目录中,以便创建虚拟环境时可用。

cd ~/.pyenv/versions
python3 -m venv --copies system system_ver
pyenv virtualenv system_ver system_ver_virtualenv

如果想在您的项目中使用它来替代之前的版本3.7:

cd ~/arshbot_proj
pyenv local system_ver_virtualenv

Poetry 现在将使用您发行版最初附带的任何版本。--copies 将确保 venv 复制文件而不是使用链接,因此您可以省略它。如果您需要稍后使用虚拟环境中的文件创建项目的多阶段 Dockerfile,则通常很有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接