目录

2024-11-28-python-wheel文件命名说明whl文件命名规则查询python兼容的版本

python wheel文件命名说明、whl文件命名规则、查询python兼容的版本

文章目录

以下整理一下python中wheel文件的命名规则。

一、wheel介绍

.whl 文件(WHL file)也称为轮子( wheel ),这是用于python分发(distribution)的标准内置包格式(standard built-package format)。它包含安装所需的所有文件和元数据(metadata)。.whl文件使用zip进行压缩。.whl文件还包含有关此wheel文件支持的Python版本和平台的信息。.whl文件格式是一种即装即用格式(ready-to-install format),允许在不构建源代码分发(without building the source distribution)的情况下运行安装包。

.whl文件本质上是zip文件,这些.whl文件可以使用解压缩选项(unzip option)或标准解压缩软件应用程序(如WinZIP和WinRAR)解压缩。

.whl文件按照以下约定命名:

{distribution}-{version}(-{build tag})? -{python tag}-{abi tag}-{platform tag}.whl

如果我们之前使用pip安装过Python包,那么我们的系统上很可能已经有轮子(wheel)被安装过。pip是安装wheel的包管理器。

我们可以通过pip安装已下载的.whl文件: pip install <filename>.whl ,安装包后,我们可以执行Python shell并尝试导入包:import whl_dist_name

wheel的直接好处是我们与其他人共享我们的包,他们不必担心构建它。他们只需pip install后即可使用该软件包。它也是一个更小的共享文件(与所有源代码相比),安装速度更快,因为它不需要运行安装脚本。

二、常见命名

flask-3.0.3-py3-none-any.whl

  • flask:whl文件模块文件名
  • 3.0.3:版本号
  • py3: 给python3版本使用的
  • py3-none-any:在任何平台上与python3兼容,即支持linux、windows、macOS系统python3版本

MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl

  • 支持windows系统64位,python2.7环境
  • cp27m: abi tag

MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl

  • 支持linux系统64位,python2.7环境
  • cp27mu: abi tag

flask-3.0.3-py2.py3-none-any.whl

  • 在任何操作系统和平台上(linux、windows、macOS)都支持Python 2和Python 3。

三、wheel文件命名规则

wheel 包的命名格式为 {distribution}-{version}(-{build tag})? -{python tag}-{abi tag}-{platform tag}.whl

其中各个 tag 的意义和取值在 PEP425 中有规定:

1、distribution: 模块名称。如numpy, flask,pyhive等。

2、version: 版本号

3、python tag

python tag 标记了具体的 python 实现。其中:

  • py 无实现特定的拓展,如py27指的是python2.7版本编译的
  • cp CPython ,也就是通常使用的 Python 实现
  • ip IronPython ,跑在 Windows CLI 平台上的 Python 实现
  • pp PyPy ,带 JIT 的 Python 实现
  • jy Jython ,跑在 JVM 上的 Python 实现

举个例子,如果 wheel 包里面包含了 C 拓展,那么打包出来的 python tag 就是 cpxx,其中 xx 是具体的版本号,如 cp27.

4、platform tag

platform tag也好理解,就是系统架构。比如

  • linux_x86_64 支持linux环境64位系统
  • win32 支持windows环境32位系统
  • win_amd64 支持windows环境64位系统
  • macosx_10_6 支持macOS系统10.6
  • any 兼容任意平台,即windows、linux、macOS都支持。如py27-none-any表示在任何平台上与Python 2.7(任何Python 2.7实现)兼容

最陌生的恐怕是之间的 abi tag ,这正是本文讨论的主题。

abi 这东西,看不见摸不着。系统上的东西嘛,敲下个命令就知道是什么操作系统;架构虽然玄乎点,不过也就是那么几种;然而有多少人知道自己当前使用的平台遵循着怎样的 abi 标准?什么时候 abi 可以兼容,什么时候又不可以?

3.1、pip wheel 打包时,abi tag是怎么敲定的

Python 对此有另外一个 PEP:

如果 sysconfig 定义了 SOABI ,那么就用 SOABI 的值。当然这是 Python 3 的事务,这里我自然不用管。如果没定义 SOABI ,比如 Python 2,wheel 会生成一个类似的 abi tag。在 Python 的标准里,这个 abi 取决于打包时使用的 Python 实现。举 CPython 为例,首先必须包含的是实现名和版本号,比如 CPython2.7.9 对应的是 cp27.其次,需要包含构建 CPython 时特定的选项。具体来说,打包时会依次判断当前的 CPython 是否有下列的功能,如果有,加上对应的 flag:

  1. –with-pydebug (flag: d )
  2. –with-pymalloc (flag: m )
  3. –with-wide-unicode (flag: u )

通常,我们看到的 abi tag 会是这样的 cp27mu ,这是因为 --with-pymalloc 是默认开启的,而包管理中分发的 CPython 会加上 --with-wide-unicode 选项。

有趣的是,如果打包时没办法判断 abi 类型,生成的 abi tag 会是 none 。而如果 Python 包是不依赖特定的 abi 的纯 Python 实现,生成的 abi tag 也是 none 。在安装时,值为 none 的 abi tag 会享受特殊待遇。这个下文再说。

另外同样的 Python 代码打出来 abi tag 相同的包,不一定完全一样。以我的亲身经历举例, pycrypto 这个库,在打包的时候会判断 libgmp 是否存在,如果存在,就构建 _fastmath 这个库。如果打包平台上存在 libgmp ,打出来的包就会包含 _fastmath 。反之,则不存在。而这两种情形下打出来的包,名字是一模一样的。

当然对于 abi tag 为 none 的包,它可以在任何一个 abi 版本上安装。因为所有的平台都至少支持 none abi 。但如果一个平台上的 Python 如此古怪,以致于没办法确定它的 abi 类型,那么也就只能装上 abi tag 为 none 的包。

四、如何判断给定 wheel 包是否能够安装

以MarkupSafe为例, 网站提供了很多种类的whl文件,应该选择哪种呢?

首先:有些文件从命名上就能看出来支持什么系统,若有些文件不知道python是否支持的,可以通过下面的方式查看。

https://i-blog.csdnimg.cn/blog_migrate/68f17eb03eb85ea0b25718deff0ebcc4.png

以下方式查看python兼容的whl版本

4.1、方式一

通过以下命令查看python兼容的版本

pip debug --verbose

本人windows环境安装python27执行后如下:

https://i-blog.csdnimg.cn/blog_migrate/56fd2bc75a81561b8181e873cd15b4d5.png

4.1、方式二

python 3.0版本可以通过以下方式查看兼容的版本号

C:\Python3.5\Scripts>python
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from pip import pep425tags
>>> print(pep425tags.get_supported())
[('cp35', 'cp35m', 'win32'), ('cp35', 'none', 'win32'), ('py3', 'none', 'win32'), 
('cp35', 'none', 'any'), ('cp3', 'none', 'any'), ('py35', 'none', 'any'),
('py3', 'none', 'any'), ('py34', 'none', 'any'), ('py33', 'none', 'any'),
('py32', 'none', 'any'), ('py31', 'none', 'any'), ('py30', 'none', 'any')]

68747470733a2f2f626c6f672e:6373646e2e6e65742f77656978696e5f34393131343530332f:61727469636c652f64657461696c732f313339333236363531