Python 3 `venv` 和 `wheel` 包

kbu*_*lds 23 python linux pip ubuntu-20.04

从python3.8开始,我注意到该wheel包似乎需要pip install无错误地打包(至少它们看起来像错误,但行为却像警告)。

注意:在我的所有示例中,我通过停用环境、删除环境并清除 pip 缓存来进行清理:

deactivate
rm test_env/ -rf
rm ~/.cache/pip/ -rf
Run Code Online (Sandbox Code Playgroud)

示例 1:问题

python3.8 -m venv test_env
source test_env/bin/activate
pip install markuppy
Run Code Online (Sandbox Code Playgroud)

我得到以下输出:

Collecting markuppy
  Downloading MarkupPy-1.14.tar.gz (6.8 kB)
Building wheels for collected packages: markuppy
  Building wheel for markuppy (setup.py) ... error
  ERROR: Command errored out with exit status 1:
   command: /home/k/test_env/bin/python3.8 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-tfm9bgxv/markuppy/setup.py'"'"'; __file__='"'"'/tmp/pip-install-tfm9bgxv/markuppy/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-cpx9gxcn
       cwd: /tmp/pip-install-tfm9bgxv/markuppy/
  Complete output (6 lines):
  usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
     or: setup.py --help [cmd1 cmd2 ...]
     or: setup.py --help-commands
     or: setup.py cmd --help
  
  error: invalid command 'bdist_wheel'
  ----------------------------------------
  ERROR: Failed building wheel for markuppy
  Running setup.py clean for markuppy
Failed to build markuppy
Installing collected packages: markuppy
    Running setup.py install for markuppy ... done
Successfully installed markuppy-1.14
Run Code Online (Sandbox Code Playgroud)

出错是因为没有wheel安装包。这已在 SO 的其他帖子中得到解决。

wheel示例 2:通过安装到 venv来修复问题

如果我wheel在创建新的 venv 后直接安装该软件包,则不会发生这种情况:

Collecting markuppy
  Downloading MarkupPy-1.14.tar.gz (6.8 kB)
Building wheels for collected packages: markuppy
  Building wheel for markuppy (setup.py) ... error
  ERROR: Command errored out with exit status 1:
   command: /home/k/test_env/bin/python3.8 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-tfm9bgxv/markuppy/setup.py'"'"'; __file__='"'"'/tmp/pip-install-tfm9bgxv/markuppy/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-cpx9gxcn
       cwd: /tmp/pip-install-tfm9bgxv/markuppy/
  Complete output (6 lines):
  usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
     or: setup.py --help [cmd1 cmd2 ...]
     or: setup.py --help-commands
     or: setup.py cmd --help
  
  error: invalid command 'bdist_wheel'
  ----------------------------------------
  ERROR: Failed building wheel for markuppy
  Running setup.py clean for markuppy
Failed to build markuppy
Installing collected packages: markuppy
    Running setup.py install for markuppy ... done
Successfully installed markuppy-1.14
Run Code Online (Sandbox Code Playgroud)

输出:

Collecting markuppy
  Using cached MarkupPy-1.14.tar.gz (6.8 kB)
Building wheels for collected packages: markuppy
  Building wheel for markuppy (setup.py) ... done
  Created wheel for markuppy: filename=MarkupPy-1.14-py3-none-any.whl size=7413 sha256=52b3e5c3e317ae21724acd871fe3deb85dde9df305b20d16f2c5592c43b11e91
  Stored in directory: /home/k/.cache/pip/wheels/95/13/60/31c9d5f4cd012e491aeac154ef8b0ec964916523623eb02f0b
Successfully built markuppy
Installing collected packages: markuppy
Successfully installed markuppy-1.14
Run Code Online (Sandbox Code Playgroud)

这也适用于给定requirements.txt文件。

requirements.txt

markuppy
Run Code Online (Sandbox Code Playgroud)
python3.8 -m venv test_env
source test_env/bin/activate
pip install wheel
pip install markuppy
Run Code Online (Sandbox Code Playgroud)

输出:

Collecting markuppy
  Using cached MarkupPy-1.14.tar.gz (6.8 kB)
Building wheels for collected packages: markuppy
  Building wheel for markuppy (setup.py) ... done
  Created wheel for markuppy: filename=MarkupPy-1.14-py3-none-any.whl size=7413 sha256=52b3e5c3e317ae21724acd871fe3deb85dde9df305b20d16f2c5592c43b11e91
  Stored in directory: /home/k/.cache/pip/wheels/95/13/60/31c9d5f4cd012e491aeac154ef8b0ec964916523623eb02f0b
Successfully built markuppy
Installing collected packages: markuppy
Successfully installed markuppy-1.14
Run Code Online (Sandbox Code Playgroud)

示例 3:添加wheelrequirements.txt没有帮助

重要的是要知道,如果您将wheel包放入requirements.txt文件中,并且不单独安装它,您会遇到与示例1中相同的问题:

requirements.txt

wheel
markuppy
Run Code Online (Sandbox Code Playgroud)
Collecting markuppy
  Using cached MarkupPy-1.14.tar.gz (6.8 kB)
Building wheels for collected packages: markuppy
  Building wheel for markuppy (setup.py) ... done
  Created wheel for markuppy: filename=MarkupPy-1.14-py3-none-any.whl size=7413 sha256=52b3e5c3e317ae21724acd871fe3deb85dde9df305b20d16f2c5592c43b11e91
  Stored in directory: /home/k/.cache/pip/wheels/95/13/60/31c9d5f4cd012e491aeac154ef8b0ec964916523623eb02f0b
Successfully built markuppy
Installing collected packages: markuppy
Successfully installed markuppy-1.14
Run Code Online (Sandbox Code Playgroud)

输出:

Collecting wheel
  Downloading wheel-0.37.0-py2.py3-none-any.whl (35 kB)
Collecting markuppy
  Downloading MarkupPy-1.14.tar.gz (6.8 kB)
Building wheels for collected packages: markuppy
  Building wheel for markuppy (setup.py) ... error
  ERROR: Command errored out with exit status 1:
   command: /home/k/test_env/bin/python3 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-z7cqzaej/markuppy/setup.py'"'"'; __file__='"'"'/tmp/pip-install-z7cqzaej/markuppy/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-kw3_8ayt
       cwd: /tmp/pip-install-z7cqzaej/markuppy/
  Complete output (6 lines):
  usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
     or: setup.py --help [cmd1 cmd2 ...]
     or: setup.py --help-commands
     or: setup.py cmd --help
  
  error: invalid command 'bdist_wheel'
  ----------------------------------------
  ERROR: Failed building wheel for markuppy
  Running setup.py clean for markuppy
Failed to build markuppy
Installing collected packages: wheel, markuppy
    Running setup.py install for markuppy ... done
Successfully installed markuppy-1.14 wheel-0.37.0
Run Code Online (Sandbox Code Playgroud)

Wheel 安装正确,但没有及时安装软件包markuppy

示例 4:wheel在系统级别安装没有帮助

如果我将wheel包直接安装到系统本身中,则创建的 venv 无权访问它,因此我得到与示例 1 相同的结果。

markuppy
Run Code Online (Sandbox Code Playgroud)

输出:

Collecting markuppy
  Downloading MarkupPy-1.14.tar.gz (6.8 kB)
Building wheels for collected packages: markuppy
  Building wheel for markuppy (setup.py) ... error
  ERROR: Command errored out with exit status 1:
   command: /home/k/test_env/bin/python3 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-5xkssq1l/markuppy/setup.py'"'"'; __file__='"'"'/tmp/pip-install-5xkssq1l/markuppy/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-aunof5xf
       cwd: /tmp/pip-install-5xkssq1l/markuppy/
  Complete output (6 lines):
  usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
     or: setup.py --help [cmd1 cmd2 ...]
     or: setup.py --help-commands
     or: setup.py cmd --help
  
  error: invalid command 'bdist_wheel'
  ----------------------------------------
  ERROR: Failed building wheel for markuppy
  Running setup.py clean for markuppy
Failed to build markuppy
Installing collected packages: markuppy
    Running setup.py install for markuppy ... done
Successfully installed markuppy-1.14
Run Code Online (Sandbox Code Playgroud)

示例 5:wheel在系统级别安装并授予 venv 访问系统站点包的权限

如果我在系统级别安装wheel,然后在创建系统站点包时授予我的 venv 访问权限(请注意 venv 命令上的标志),则不会发生此问题。

python3.8 -m venv test_env
source test_env/bin/activate
pip install wheel
pip install -r requirements.txt
Run Code Online (Sandbox Code Playgroud)

输出:

Collecting markuppy
  Downloading MarkupPy-1.14.tar.gz (6.8 kB)
Building wheels for collected packages: markuppy
  Building wheel for markuppy (setup.py) ... done
  Created wheel for markuppy: filename=MarkupPy-1.14-py3-none-any.whl size=7414 sha256=cefe8d9f20cecaf72253cab1e18acbdcb6d30827d7a3fd5a74bbef4935bc2e44
  Stored in directory: /home/k/.cache/pip/wheels/95/13/60/31c9d5f4cd012e491aeac154ef8b0ec964916523623eb02f0b
Successfully built markuppy
Installing collected packages: markuppy
Successfully installed markuppy-1.14
Run Code Online (Sandbox Code Playgroud)

这种方法的明显缺点是它破坏了项目的 venv 和系统本身安装的 python 包之间的隔离。

示例 6:在 Python3.7 中这一切都不会发生

Collecting markuppy
  Using cached MarkupPy-1.14.tar.gz (6.8 kB)
Building wheels for collected packages: markuppy
  Building wheel for markuppy (setup.py) ... done
  Created wheel for markuppy: filename=MarkupPy-1.14-py3-none-any.whl size=7413 sha256=52b3e5c3e317ae21724acd871fe3deb85dde9df305b20d16f2c5592c43b11e91
  Stored in directory: /home/k/.cache/pip/wheels/95/13/60/31c9d5f4cd012e491aeac154ef8b0ec964916523623eb02f0b
Successfully built markuppy
Installing collected packages: markuppy
Successfully installed markuppy-1.14
Run Code Online (Sandbox Code Playgroud)

输出:

Collecting markuppy
  Downloading MarkupPy-1.14.tar.gz (6.8 kB)
Using legacy 'setup.py install' for markuppy, since package 'wheel' is not installed.
Installing collected packages: markuppy
    Running setup.py install for markuppy ... done
Successfully installed markuppy-1.14
Run Code Online (Sandbox Code Playgroud)

尽管它确实提供了 pipsetup.py install代替wheel.

问题

我们该如何处理这个wheel包裹呢?似乎我们都希望在大多数(所有?)环境中都安装这个包,但是标准库中的环境工具不会自动提供它。

我喜欢让我的项目环境与系统 python 环境完全隔离的想法,所以看起来我能看到的唯一选项是:

  1. wheel创建新的 venv 后立即手动安装软件包。
  2. 使用 venv 之外的另一个工具来管理环境。

Jas*_*zik 7

设置 venv 时,在运行其他任何操作之前,pip install --upgrade pip wheel先运行即可。无论如何,这是一个很好的做法,可以确保您使用最新版本的 pip 来解决您的依赖关系,因此会出现警告:

WARNING: You are using pip version 22.0.4; however, version 22.2.2 is available.
You should consider upgrading via the '/home/user/tmp/test_env/bin/python3 -m pip install --upgrade pip' command.
Run Code Online (Sandbox Code Playgroud)

默认情况下,轮子似乎不再包含在内,因为我也能够在 3.10 上进行复制。指定--system-site-packages使用系统轮是预期的,venv 的全部目的是避免接触系统 python。在安装过程中不使用requirements.txt也是有道理的,因为不太可能有任何软件包被wheel列为依赖项,因此它可能是并行安装的。